webs-sdk 0.18.90 → 0.18.91

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.
@@ -26,6 +26,23 @@ const GIFSÍA_CSS = `
26
26
  background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
27
27
  background-color: #2a2a3a;
28
28
  }
29
+ .gifsía-gallery-scroll {
30
+ display: flex;
31
+ gap: 12px;
32
+ overflow-x: auto;
33
+ scroll-snap-type: x mandatory;
34
+ -webkit-overflow-scrolling: touch;
35
+ scrollbar-width: none;
36
+ -ms-overflow-style: none;
37
+ }
38
+ .gifsía-gallery-scroll::-webkit-scrollbar {
39
+ display: none;
40
+ }
41
+ .gifsía-gallery-item {
42
+ scroll-snap-align: start;
43
+ flex: 0 0 calc(25% - 9px);
44
+ min-width: 80px;
45
+ }
29
46
  @keyframes gifsía-scan {
30
47
  0% { top: 0%; }
31
48
  100% { top: 100%; }
@@ -55,26 +72,27 @@ const defaultTheme = {
55
72
  textSecondaryColor: '#A0A0C0',
56
73
  createButtonColor: '#6C63FF',
57
74
  disabledColor: '#4A4A6A',
75
+ gifPanelBackground: '#252540',
58
76
  };
59
77
  const defaultTexts = {
60
- galleryTitle: 'Galería De GIFs',
61
- photoSectionTitle: 'Foto',
78
+ galleryTitle: 'GIF Gallery',
79
+ photoSectionTitle: 'Photo',
62
80
  gifSectionTitle: 'GIF',
63
- uploadButton: 'Subir imagen',
64
- createGifButton: 'Crear GIF',
65
- creatingGifButton: 'Creando GIF...',
66
- copyLinkButton: 'Copiar enlace',
67
- downloadButton: 'Descargar',
68
- emptyPhotoText: 'Sube una foto para crear tu GIF',
69
- emptyGifText: 'Tu GIF aparecerá aquí',
70
- loadingGalleryText: 'Cargando galería...',
71
- errorText: 'Ha ocurrido un error. Inténtalo de nuevo.',
72
- fileTooLargeText: 'El archivo es demasiado grande. Máximo {size}MB.',
73
- invalidFormatText: 'Formato de archivo no válido. Por favor, sube una imagen.',
74
- linkCopiedText: '¡Enlace copiado!',
75
- queueText: 'En cola',
76
- pasteImageTooltip: 'Pegar imagen del portapapeles',
77
- resetTooltip: 'Limpiar y empezar de nuevo',
81
+ uploadButton: 'Upload image',
82
+ createGifButton: 'Create GIF',
83
+ creatingGifButton: 'Creating GIF...',
84
+ copyLinkButton: 'Copy link',
85
+ downloadButton: 'Download',
86
+ emptyPhotoText: 'Upload a photo to create your GIF',
87
+ emptyGifText: 'Your GIF will appear here',
88
+ loadingGalleryText: 'Loading gallery...',
89
+ errorText: 'An error occurred. Please try again.',
90
+ fileTooLargeText: 'File is too large. Max {size}MB.',
91
+ invalidFormatText: 'Invalid format. Please upload an image.',
92
+ linkCopiedText: 'Link copied!',
93
+ queueText: 'In queue',
94
+ pasteImageTooltip: 'Paste image from clipboard',
95
+ resetTooltip: 'Clear and start over',
78
96
  };
79
97
  function GifBadge({ color = '#6C63FF' }) {
80
98
  return ((0, jsx_runtime_1.jsxs)("svg", { width: "28", height: "20", viewBox: "0 0 28 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [(0, jsx_runtime_1.jsx)("rect", { width: "28", height: "20", rx: "4", fill: color }), (0, jsx_runtime_1.jsx)("text", { x: "4", y: "14", fill: "white", fontSize: "10", fontWeight: "700", fontFamily: "monospace", children: "GIF" })] }));
@@ -87,6 +105,7 @@ function GifsIa({ config, galleryItems: galleryProp, theme = {}, texts = {}, ima
87
105
  const t = Object.assign(Object.assign({}, defaultTexts), texts);
88
106
  const th = Object.assign(Object.assign({}, defaultTheme), theme);
89
107
  const createBtnColor = th.createButtonColor || th.primaryColor;
108
+ const gifBg = th.gifPanelBackground || th.cardBackground;
90
109
  const maxFileMB = (_a = config.maxFileSizeMB) !== null && _a !== void 0 ? _a : 10;
91
110
  (0, react_1.useEffect)(() => {
92
111
  const id = 'gifsía-styles';
@@ -118,15 +137,16 @@ function GifsIa({ config, galleryItems: galleryProp, theme = {}, texts = {}, ima
118
137
  apiBaseUrl: config.apiBaseUrl,
119
138
  tags,
120
139
  contents: config.galleryContents,
121
- locale: config.locale || 'es',
140
+ locale: config.locale || 'en',
122
141
  website_id: config.website_id,
123
142
  });
124
143
  const mapped = items
125
144
  .map((item, idx) => {
126
- var _a, _b;
145
+ var _a, _b, _c, _d, _e;
127
146
  return ({
128
147
  id: (_a = item.id) !== null && _a !== void 0 ? _a : idx,
129
- imageUrl: item.thumbnail || ((_b = item.images) === null || _b === void 0 ? void 0 : _b.img1) || item.imageUrl || '',
148
+ imageUrl: item.thumbnail || ((_b = item.images) === null || _b === void 0 ? void 0 : _b.img3) || ((_c = item.images) === null || _c === void 0 ? void 0 : _c.img1) || item.imageUrl || '',
149
+ gifUrl: ((_d = item.metadata) === null || _d === void 0 ? void 0 : _d.gif) || ((_e = item.metadata) === null || _e === void 0 ? void 0 : _e.gif_light) || item.gifUrl || item.gif_url || undefined,
130
150
  title: item.title || '',
131
151
  });
132
152
  })
@@ -134,7 +154,7 @@ function GifsIa({ config, galleryItems: galleryProp, theme = {}, texts = {}, ima
134
154
  setDynamicGallery(mapped);
135
155
  }
136
156
  catch (err) {
137
- console.error('[GifsIa] Error cargando galería:', err);
157
+ console.error('[GifsIa] Error loading gallery:', err);
138
158
  }
139
159
  finally {
140
160
  setLoadingGallery(false);
@@ -143,7 +163,6 @@ function GifsIa({ config, galleryItems: galleryProp, theme = {}, texts = {}, ima
143
163
  load();
144
164
  }, [config.apiUrl, config.apiBaseUrl, config.galleryTags]);
145
165
  const gallery = galleryProp && galleryProp.length > 0 ? galleryProp : dynamicGallery;
146
- const [carouselIndex, setCarouselIndex] = (0, react_1.useState)(0);
147
166
  const [selectedGalleryId, setSelectedGalleryId] = (0, react_1.useState)(null);
148
167
  const [uploadedImageBase64, setUploadedImageBase64] = (0, react_1.useState)(null);
149
168
  const [isGenerating, setIsGenerating] = (0, react_1.useState)(false);
@@ -155,11 +174,25 @@ function GifsIa({ config, galleryItems: galleryProp, theme = {}, texts = {}, ima
155
174
  const fileInputRef = (0, react_1.useRef)(null);
156
175
  const pollRef = (0, react_1.useRef)(null);
157
176
  const timeoutRef = (0, react_1.useRef)(null);
177
+ const galleryScrollRef = (0, react_1.useRef)(null);
158
178
  (0, react_1.useEffect)(() => {
159
179
  if (gallery.length > 0 && selectedGalleryId === null) {
160
180
  setSelectedGalleryId(gallery[0].id);
161
181
  }
162
182
  }, [gallery, selectedGalleryId]);
183
+ (0, react_1.useEffect)(() => {
184
+ const el = galleryScrollRef.current;
185
+ if (!el)
186
+ return;
187
+ const onWheel = (e) => {
188
+ if (Math.abs(e.deltaX) > Math.abs(e.deltaY))
189
+ return;
190
+ e.preventDefault();
191
+ el.scrollLeft += e.deltaY;
192
+ };
193
+ el.addEventListener('wheel', onWheel, { passive: false });
194
+ return () => el.removeEventListener('wheel', onWheel);
195
+ }, []);
163
196
  const clearPolls = (0, react_1.useCallback)(() => {
164
197
  if (pollRef.current) {
165
198
  clearInterval(pollRef.current);
@@ -171,9 +204,6 @@ function GifsIa({ config, galleryItems: galleryProp, theme = {}, texts = {}, ima
171
204
  }
172
205
  }, []);
173
206
  (0, react_1.useEffect)(() => () => clearPolls(), [clearPolls]);
174
- const visibleCount = 4;
175
- const handlePrev = () => setCarouselIndex(prev => Math.max(0, prev - 1));
176
- const handleNext = () => setCarouselIndex(prev => Math.min(Math.max(0, gallery.length - visibleCount), prev + 1));
177
207
  const processFile = (file) => {
178
208
  if (!file.type.startsWith('image/')) {
179
209
  alert(t.invalidFormatText);
@@ -214,7 +244,7 @@ function GifsIa({ config, galleryItems: galleryProp, theme = {}, texts = {}, ima
214
244
  }
215
245
  }
216
246
  catch (_a) {
217
- console.warn('[GifsIa] No hay imagen en el portapapeles o permiso denegado');
247
+ console.warn('[GifsIa] No clipboard image or permission denied');
218
248
  }
219
249
  };
220
250
  const handleReset = () => {
@@ -229,7 +259,7 @@ function GifsIa({ config, galleryItems: galleryProp, theme = {}, texts = {}, ima
229
259
  fileInputRef.current.value = '';
230
260
  };
231
261
  const handleCreateGif = async () => {
232
- var _a, _b, _c;
262
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
233
263
  if (!uploadedImageBase64 || isGenerating)
234
264
  return;
235
265
  clearPolls();
@@ -238,74 +268,121 @@ function GifsIa({ config, galleryItems: galleryProp, theme = {}, texts = {}, ima
238
268
  setProgressPercent(0);
239
269
  setQueuePosition(null);
240
270
  setGenError(null);
241
- const base = config.generateBaseUrl.replace(/\/$/, '');
242
271
  const pollInterval = (_a = config.pollInterval) !== null && _a !== void 0 ? _a : 3000;
243
272
  const maxPollTime = (_b = config.maxPollTime) !== null && _b !== void 0 ? _b : 120000;
244
273
  const selectedItem = gallery.find(g => g.id === selectedGalleryId);
274
+ const generateUrl = (_c = config.generateApiUrl) !== null && _c !== void 0 ? _c : (config.generateBaseUrl ? `${config.generateBaseUrl.replace(/\/$/, '')}/get_art_generation` : null);
275
+ if (!generateUrl) {
276
+ setGenError(t.errorText);
277
+ setIsGenerating(false);
278
+ return;
279
+ }
245
280
  try {
246
- const genRes = await fetch(`${base}/get_art_generation`, {
281
+ const genRes = await fetch(generateUrl, {
247
282
  method: 'POST',
248
283
  headers: { 'Content-Type': 'application/json' },
249
- body: JSON.stringify(Object.assign(Object.assign(Object.assign(Object.assign({ image: uploadedImageBase64 }, (selectedItem && { reference_image: selectedItem.imageUrl })), (config.userId && { us_id: config.userId })), (config.userLogin && { us_login: config.userLogin })), (config.wid && { wid: config.wid }))),
284
+ body: JSON.stringify(Object.assign(Object.assign(Object.assign(Object.assign({ image: uploadedImageBase64 }, (selectedItem && { reference_image: selectedItem.gifUrl || selectedItem.imageUrl })), (config.userId && { us_id: config.userId })), (config.userLogin && { us_login: config.userLogin })), (config.wid && { wid: config.wid }))),
250
285
  });
251
286
  if (!genRes.ok)
252
- throw new Error(`Error en generación: ${genRes.status}`);
287
+ throw new Error(`Generation error: ${genRes.status}`);
253
288
  const genData = await genRes.json();
254
- console.log('[GifsIa] gen response:', genData);
255
- const jobId = ((_c = genData === null || genData === void 0 ? void 0 : genData.data) === null || _c === void 0 ? void 0 : _c.md5) || (genData === null || genData === void 0 ? void 0 : genData.md5) || (genData === null || genData === void 0 ? void 0 : genData.job_id) || (genData === null || genData === void 0 ? void 0 : genData.id);
289
+ console.log('[GifsIa] generate response:', JSON.stringify(genData));
290
+ if ((genData === null || genData === void 0 ? void 0 : genData.success) === 0 || (genData === null || genData === void 0 ? void 0 : genData.success) === false) {
291
+ throw new Error((genData === null || genData === void 0 ? void 0 : genData.msg) || (genData === null || genData === void 0 ? void 0 : genData.error) || 'Generation failed');
292
+ }
293
+ const jobId = ((_d = genData === null || genData === void 0 ? void 0 : genData.data) === null || _d === void 0 ? void 0 : _d.md5) ||
294
+ ((_e = genData === null || genData === void 0 ? void 0 : genData.data) === null || _e === void 0 ? void 0 : _e.request_id) ||
295
+ ((_f = genData === null || genData === void 0 ? void 0 : genData.data) === null || _f === void 0 ? void 0 : _f.job_id) ||
296
+ ((_g = genData === null || genData === void 0 ? void 0 : genData.data) === null || _g === void 0 ? void 0 : _g.id) ||
297
+ (genData === null || genData === void 0 ? void 0 : genData.md5) ||
298
+ (genData === null || genData === void 0 ? void 0 : genData.request_id) ||
299
+ (genData === null || genData === void 0 ? void 0 : genData.job_id) ||
300
+ (genData === null || genData === void 0 ? void 0 : genData.id);
301
+ console.log('[GifsIa] jobId extracted:', jobId);
256
302
  if (!jobId)
257
- throw new Error('No se recibió job ID');
303
+ throw new Error(`No job ID received. Response: ${JSON.stringify(genData)}`);
258
304
  timeoutRef.current = setTimeout(() => {
259
305
  clearPolls();
260
306
  setIsGenerating(false);
261
307
  setGenError(t.errorText);
262
308
  onError === null || onError === void 0 ? void 0 : onError(t.errorText);
263
309
  }, maxPollTime);
310
+ const base = (_j = (_h = config.generateBaseUrl) === null || _h === void 0 ? void 0 : _h.replace(/\/$/, '')) !== null && _j !== void 0 ? _j : '';
264
311
  const poll = async () => {
265
- var _a, _b, _c, _d, _e, _f, _g, _h;
312
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
266
313
  try {
267
- const queueRes = await fetch(`${base}/get_queue_position`, {
268
- method: 'POST',
269
- headers: { 'Content-Type': 'application/json' },
270
- body: JSON.stringify(Object.assign(Object.assign({ md5: jobId }, (config.userId && { us_id: config.userId })), (config.wid && { wid: config.wid }))),
271
- });
272
- if (queueRes.ok) {
273
- const queueData = await queueRes.json();
274
- const pos = (_c = (_b = (_a = queueData === null || queueData === void 0 ? void 0 : queueData.data) === null || _a === void 0 ? void 0 : _a.position) !== null && _b !== void 0 ? _b : queueData === null || queueData === void 0 ? void 0 : queueData.position) !== null && _c !== void 0 ? _c : null;
275
- setQueuePosition(pos);
276
- }
277
- const pctRes = await fetch(`${base}/get_arg_pct`, {
278
- method: 'POST',
279
- headers: { 'Content-Type': 'application/json' },
280
- body: JSON.stringify(Object.assign(Object.assign({ md5: jobId }, (config.userId && { us_id: config.userId })), (config.wid && { wid: config.wid }))),
281
- });
282
- if (!pctRes.ok)
283
- return;
284
- const pctData = await pctRes.json();
285
- const pct = (_f = (_e = (_d = pctData === null || pctData === void 0 ? void 0 : pctData.data) === null || _d === void 0 ? void 0 : _d.pct) !== null && _e !== void 0 ? _e : pctData === null || pctData === void 0 ? void 0 : pctData.pct) !== null && _f !== void 0 ? _f : 0;
286
- setProgressPercent(pct);
287
- if (pct >= 100) {
288
- clearPolls();
289
- const jobRes = await fetch(`${base}/get_art_job`, {
290
- method: 'POST',
291
- headers: { 'Content-Type': 'application/json' },
292
- body: JSON.stringify(Object.assign(Object.assign({ md5: jobId }, (config.userId && { us_id: config.userId })), (config.wid && { wid: config.wid }))),
293
- });
294
- if (!jobRes.ok)
295
- throw new Error('Error obteniendo GIF final');
296
- const jobData = await jobRes.json();
297
- console.log('[GifsIa] job data:', jobData);
298
- const gifUrl = ((_g = jobData === null || jobData === void 0 ? void 0 : jobData.data) === null || _g === void 0 ? void 0 : _g.url) || (jobData === null || jobData === void 0 ? void 0 : jobData.url) || (jobData === null || jobData === void 0 ? void 0 : jobData.gif) || ((_h = jobData === null || jobData === void 0 ? void 0 : jobData.data) === null || _h === void 0 ? void 0 : _h.gif);
299
- if (!gifUrl)
300
- throw new Error('No se recibió URL del GIF');
301
- setGeneratedGifUrl(gifUrl);
302
- setProgressPercent(100);
303
- setIsGenerating(false);
304
- onGifCreated === null || onGifCreated === void 0 ? void 0 : onGifCreated(gifUrl);
314
+ const progressUrl = (_a = config.progressApiUrl) !== null && _a !== void 0 ? _a : (base ? `${base}/get_arg_pct` : null);
315
+ if (progressUrl) {
316
+ const isProxy = !!config.progressApiUrl;
317
+ if (isProxy) {
318
+ const pctRes = await fetch(progressUrl, {
319
+ method: 'POST',
320
+ headers: { 'Content-Type': 'application/json' },
321
+ body: JSON.stringify(Object.assign(Object.assign({ md5: jobId }, (config.userId && { us_id: config.userId })), (config.wid && { wid: config.wid }))),
322
+ });
323
+ if (pctRes.ok) {
324
+ const pctData = await pctRes.json();
325
+ const pct = (_d = (_c = (_b = pctData === null || pctData === void 0 ? void 0 : pctData.data) === null || _b === void 0 ? void 0 : _b.pct) !== null && _c !== void 0 ? _c : pctData === null || pctData === void 0 ? void 0 : pctData.pct) !== null && _d !== void 0 ? _d : 0;
326
+ const pos = (_f = (_e = pctData === null || pctData === void 0 ? void 0 : pctData.data) === null || _e === void 0 ? void 0 : _e.position) !== null && _f !== void 0 ? _f : null;
327
+ const gifUrl = (_h = (_g = pctData === null || pctData === void 0 ? void 0 : pctData.data) === null || _g === void 0 ? void 0 : _g.gifUrl) !== null && _h !== void 0 ? _h : null;
328
+ setProgressPercent(pct);
329
+ if (pos !== null)
330
+ setQueuePosition(pos);
331
+ if (gifUrl) {
332
+ clearPolls();
333
+ setGeneratedGifUrl(gifUrl);
334
+ setProgressPercent(100);
335
+ setIsGenerating(false);
336
+ onGifCreated === null || onGifCreated === void 0 ? void 0 : onGifCreated(gifUrl);
337
+ return;
338
+ }
339
+ return;
340
+ }
341
+ }
342
+ else {
343
+ const queueUrl = `${base}/get_queue_position`;
344
+ const queueRes = await fetch(queueUrl, {
345
+ method: 'POST',
346
+ headers: { 'Content-Type': 'application/json' },
347
+ body: JSON.stringify(Object.assign(Object.assign({ md5: jobId }, (config.userId && { us_id: config.userId })), (config.wid && { wid: config.wid }))),
348
+ });
349
+ if (queueRes.ok) {
350
+ const qd = await queueRes.json();
351
+ setQueuePosition((_l = (_k = (_j = qd === null || qd === void 0 ? void 0 : qd.data) === null || _j === void 0 ? void 0 : _j.position) !== null && _k !== void 0 ? _k : qd === null || qd === void 0 ? void 0 : qd.position) !== null && _l !== void 0 ? _l : null);
352
+ }
353
+ const pctRes = await fetch(progressUrl, {
354
+ method: 'POST',
355
+ headers: { 'Content-Type': 'application/json' },
356
+ body: JSON.stringify(Object.assign(Object.assign({ md5: jobId }, (config.userId && { us_id: config.userId })), (config.wid && { wid: config.wid }))),
357
+ });
358
+ if (!pctRes.ok)
359
+ return;
360
+ const pctData = await pctRes.json();
361
+ const pct = (_p = (_o = (_m = pctData === null || pctData === void 0 ? void 0 : pctData.data) === null || _m === void 0 ? void 0 : _m.pct) !== null && _o !== void 0 ? _o : pctData === null || pctData === void 0 ? void 0 : pctData.pct) !== null && _p !== void 0 ? _p : 0;
362
+ setProgressPercent(pct);
363
+ if (pct >= 100) {
364
+ clearPolls();
365
+ const jobRes = await fetch(`${base}/get_art_job`, {
366
+ method: 'POST',
367
+ headers: { 'Content-Type': 'application/json' },
368
+ body: JSON.stringify(Object.assign(Object.assign({ md5: jobId }, (config.userId && { us_id: config.userId })), (config.wid && { wid: config.wid }))),
369
+ });
370
+ if (!jobRes.ok)
371
+ throw new Error('Error fetching GIF');
372
+ const jobData = await jobRes.json();
373
+ const gifUrl = ((_q = jobData === null || jobData === void 0 ? void 0 : jobData.data) === null || _q === void 0 ? void 0 : _q.url) || (jobData === null || jobData === void 0 ? void 0 : jobData.url) || (jobData === null || jobData === void 0 ? void 0 : jobData.gif) || ((_r = jobData === null || jobData === void 0 ? void 0 : jobData.data) === null || _r === void 0 ? void 0 : _r.gif);
374
+ if (!gifUrl)
375
+ throw new Error('No GIF URL received');
376
+ setGeneratedGifUrl(gifUrl);
377
+ setProgressPercent(100);
378
+ setIsGenerating(false);
379
+ onGifCreated === null || onGifCreated === void 0 ? void 0 : onGifCreated(gifUrl);
380
+ }
381
+ }
305
382
  }
306
383
  }
307
384
  catch (err) {
308
- console.error('[GifsIa] Error en polling:', err);
385
+ console.error('[GifsIa] Polling error:', err);
309
386
  }
310
387
  };
311
388
  poll();
@@ -332,7 +409,7 @@ function GifsIa({ config, galleryItems: galleryProp, theme = {}, texts = {}, ima
332
409
  setTimeout(() => setCopySuccess(false), 2000);
333
410
  }
334
411
  catch (_a) {
335
- console.warn('[GifsIa] No se pudo copiar al portapapeles');
412
+ console.warn('[GifsIa] Could not copy to clipboard');
336
413
  }
337
414
  };
338
415
  const handleDownload = async () => {
@@ -371,25 +448,49 @@ function GifsIa({ config, galleryItems: galleryProp, theme = {}, texts = {}, ima
371
448
  @keyframes gifsía-scan { 0% { top: 0%; } 100% { top: 100%; } }
372
449
  @keyframes gifsía-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
373
450
  .gifsía-scan-line { position: absolute; left: 0; width: 100%; height: 3px; background: linear-gradient(90deg, transparent, ${th.primaryColor}, transparent); animation: gifsía-scan 1.8s linear infinite; z-index: 10; box-shadow: 0 0 8px 2px ${th.primaryColor}80; }
374
- ` }), (0, jsx_runtime_1.jsx)("input", { ref: fileInputRef, type: "file", accept: config.acceptedFormats || 'image/*', onChange: handleFileChange, style: { display: 'none' } }), (0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: '24px' }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '12px' }, children: [(0, jsx_runtime_1.jsx)(GifBadge, { color: th.primaryColor }), (0, jsx_runtime_1.jsx)("h3", { style: { margin: 0, fontSize: '18px', fontWeight: 700, color: th.textColor }, children: t.galleryTitle })] }), loadingGallery ? ((0, jsx_runtime_1.jsx)("p", { style: { color: th.textSecondaryColor, fontSize: '14px' }, children: t.loadingGalleryText })) : gallery.length > 0 ? ((0, jsx_runtime_1.jsxs)("div", { style: { position: 'relative', display: 'flex', alignItems: 'center', gap: '8px' }, children: [(0, jsx_runtime_1.jsx)("button", { onClick: handlePrev, disabled: carouselIndex === 0, style: {
375
- width: '36px', height: '36px', borderRadius: '50%', border: `1px solid ${th.borderColor}`,
376
- backgroundColor: th.cardBackground, color: th.textColor, cursor: carouselIndex === 0 ? 'not-allowed' : 'pointer',
377
- opacity: carouselIndex === 0 ? 0.3 : 1, flexShrink: 0,
451
+ ` }), (0, jsx_runtime_1.jsx)("input", { ref: fileInputRef, type: "file", accept: config.acceptedFormats || 'image/*', onChange: handleFileChange, style: { display: 'none' } }), (0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: '24px' }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '12px' }, children: [(0, jsx_runtime_1.jsx)(GifBadge, { color: th.primaryColor }), (0, jsx_runtime_1.jsx)("h3", { style: { margin: 0, fontSize: '18px', fontWeight: 700, color: th.textColor }, children: t.galleryTitle })] }), loadingGallery ? ((0, jsx_runtime_1.jsx)("p", { style: { color: th.textSecondaryColor, fontSize: '14px' }, children: t.loadingGalleryText })) : gallery.length > 0 ? ((0, jsx_runtime_1.jsxs)("div", { style: { position: 'relative' }, children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => { if (galleryScrollRef.current)
452
+ galleryScrollRef.current.scrollBy({ left: -300, behavior: 'smooth' }); }, style: {
453
+ position: 'absolute', left: '4px', top: '50%', transform: 'translateY(-50%)',
454
+ zIndex: 10, width: '32px', height: '32px', borderRadius: '50%', border: 'none',
455
+ backgroundColor: `${th.primaryColor}dd`, color: '#FFFFFF',
378
456
  display: 'flex', alignItems: 'center', justifyContent: 'center',
379
- }, children: (0, jsx_runtime_1.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: (0, jsx_runtime_1.jsx)("polyline", { points: "15 18 9 12 15 6" }) }) }), (0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', gap: '12px', flex: 1, overflow: 'hidden' }, children: gallery.slice(carouselIndex, carouselIndex + visibleCount).map((item) => {
457
+ cursor: 'pointer', boxShadow: '0 2px 8px rgba(0,0,0,0.5)',
458
+ transition: 'background-color 0.2s',
459
+ }, onMouseEnter: (e) => { e.currentTarget.style.backgroundColor = th.primaryColor; }, onMouseLeave: (e) => { e.currentTarget.style.backgroundColor = `${th.primaryColor}dd`; }, children: (0, jsx_runtime_1.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: (0, jsx_runtime_1.jsx)("polyline", { points: "15 18 9 12 15 6" }) }) }), (0, jsx_runtime_1.jsx)("div", { ref: galleryScrollRef, style: {
460
+ display: 'flex',
461
+ flexDirection: 'row',
462
+ gap: '12px',
463
+ overflowX: 'auto',
464
+ overflowY: 'hidden',
465
+ scrollSnapType: 'x mandatory',
466
+ WebkitOverflowScrolling: 'touch',
467
+ scrollbarWidth: 'none',
468
+ msOverflowStyle: 'none',
469
+ width: '100%',
470
+ }, children: gallery.map((item) => {
380
471
  const isSelected = selectedGalleryId === item.id;
381
472
  return ((0, jsx_runtime_1.jsx)("button", { onClick: () => setSelectedGalleryId(item.id), style: {
382
- flex: '1', padding: 0, border: `3px solid ${isSelected ? th.primaryColor : 'transparent'}`,
383
- borderRadius: '10px', overflow: 'hidden', cursor: 'pointer', backgroundColor: 'transparent',
384
- outline: 'none', minWidth: 0,
385
- }, children: (0, jsx_runtime_1.jsx)("img", { src: item.imageUrl, alt: item.title || '', style: { width: '100%', aspectRatio: '4/3', objectFit: 'cover', display: 'block' } }) }, item.id));
386
- }) }), (0, jsx_runtime_1.jsx)("button", { onClick: handleNext, disabled: carouselIndex >= gallery.length - visibleCount, style: {
387
- width: '36px', height: '36px', borderRadius: '50%', border: `1px solid ${th.borderColor}`,
388
- backgroundColor: th.cardBackground, color: th.textColor,
389
- cursor: carouselIndex >= gallery.length - visibleCount ? 'not-allowed' : 'pointer',
390
- opacity: carouselIndex >= gallery.length - visibleCount ? 0.3 : 1, flexShrink: 0,
473
+ flexShrink: 0,
474
+ width: 'calc(25% - 9px)',
475
+ minWidth: '120px',
476
+ scrollSnapAlign: 'start',
477
+ padding: 0,
478
+ border: `3px solid ${isSelected ? th.primaryColor : 'transparent'}`,
479
+ borderRadius: '10px',
480
+ overflow: 'hidden',
481
+ cursor: 'pointer',
482
+ backgroundColor: 'transparent',
483
+ outline: 'none',
484
+ }, children: (0, jsx_runtime_1.jsx)("img", { src: item.gifUrl || item.imageUrl, alt: item.title || '', style: { width: '100%', aspectRatio: '4/3', objectFit: 'cover', display: 'block' } }) }, item.id));
485
+ }) }), (0, jsx_runtime_1.jsx)("button", { onClick: () => { if (galleryScrollRef.current)
486
+ galleryScrollRef.current.scrollBy({ left: 300, behavior: 'smooth' }); }, style: {
487
+ position: 'absolute', right: '4px', top: '50%', transform: 'translateY(-50%)',
488
+ zIndex: 10, width: '32px', height: '32px', borderRadius: '50%', border: 'none',
489
+ backgroundColor: `${th.primaryColor}dd`, color: '#FFFFFF',
391
490
  display: 'flex', alignItems: 'center', justifyContent: 'center',
392
- }, children: (0, jsx_runtime_1.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: (0, jsx_runtime_1.jsx)("polyline", { points: "9 18 15 12 9 6" }) }) })] })) : null] }), (0, jsx_runtime_1.jsxs)("div", { className: "gifs\u00EDa-layout", children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column', gap: '12px' }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center', gap: '8px' }, children: [(0, jsx_runtime_1.jsx)(CameraBadge, { color: th.primaryColor }), (0, jsx_runtime_1.jsx)("span", { style: { fontSize: '16px', fontWeight: 700, color: th.primaryColor }, children: t.photoSectionTitle })] }), (0, jsx_runtime_1.jsxs)("div", { className: "gifs\u00EDa-checker", onDrop: handleDrop, onDragOver: handleDragOver, style: {
491
+ cursor: 'pointer', boxShadow: '0 2px 8px rgba(0,0,0,0.5)',
492
+ transition: 'background-color 0.2s',
493
+ }, onMouseEnter: (e) => { e.currentTarget.style.backgroundColor = th.primaryColor; }, onMouseLeave: (e) => { e.currentTarget.style.backgroundColor = `${th.primaryColor}dd`; }, children: (0, jsx_runtime_1.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: (0, jsx_runtime_1.jsx)("polyline", { points: "9 18 15 12 9 6" }) }) })] })) : null] }), (0, jsx_runtime_1.jsxs)("div", { className: "gifs\u00EDa-layout", children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column', gap: '12px' }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center', gap: '8px' }, children: [(0, jsx_runtime_1.jsx)(CameraBadge, { color: th.primaryColor }), (0, jsx_runtime_1.jsx)("span", { style: { fontSize: '16px', fontWeight: 700, color: th.primaryColor }, children: t.photoSectionTitle })] }), (0, jsx_runtime_1.jsxs)("div", { className: "gifs\u00EDa-checker", onDrop: handleDrop, onDragOver: handleDragOver, style: {
393
494
  position: 'relative', borderRadius: '10px', border: `2px dashed ${th.borderColor}`,
394
495
  minHeight: '320px', display: 'flex', alignItems: 'center', justifyContent: 'center',
395
496
  overflow: 'hidden', cursor: uploadedImageBase64 ? 'default' : 'pointer',
@@ -399,7 +500,7 @@ function GifsIa({ config, galleryItems: galleryProp, theme = {}, texts = {}, ima
399
500
  backgroundColor: th.primaryColor, color: '#FFFFFF',
400
501
  display: 'flex', alignItems: 'center', justifyContent: 'center',
401
502
  cursor: 'pointer', boxShadow: '0 2px 8px rgba(0,0,0,0.3)',
402
- }, children: uploadedImageBase64 ? ((0, jsx_runtime_1.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [(0, jsx_runtime_1.jsx)("polyline", { points: "1 4 1 10 7 10" }), (0, jsx_runtime_1.jsx)("path", { d: "M3.51 15a9 9 0 1 0 .49-3" })] })) : ((0, jsx_runtime_1.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [(0, jsx_runtime_1.jsx)("path", { d: "M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2" }), (0, jsx_runtime_1.jsx)("rect", { x: "8", y: "2", width: "8", height: "4", rx: "1", ry: "1" })] })) }), uploadedImageBase64 ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("img", { src: uploadedImageBase64, alt: "Foto subida", style: { width: '100%', height: '100%', objectFit: 'contain', position: 'absolute', inset: 0 } }), isGenerating && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: { position: 'absolute', inset: 0, backgroundColor: 'rgba(0,0,0,0.3)', zIndex: 9 } }), (0, jsx_runtime_1.jsx)("div", { className: "gifs\u00EDa-scan-line" })] }))] })) : ((0, jsx_runtime_1.jsxs)("button", { onClick: handleUploadClick, style: {
503
+ }, children: uploadedImageBase64 ? ((0, jsx_runtime_1.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [(0, jsx_runtime_1.jsx)("polyline", { points: "1 4 1 10 7 10" }), (0, jsx_runtime_1.jsx)("path", { d: "M3.51 15a9 9 0 1 0 .49-3" })] })) : ((0, jsx_runtime_1.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [(0, jsx_runtime_1.jsx)("path", { d: "M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2" }), (0, jsx_runtime_1.jsx)("rect", { x: "8", y: "2", width: "8", height: "4", rx: "1", ry: "1" })] })) }), uploadedImageBase64 ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("img", { src: uploadedImageBase64, alt: "Uploaded photo", style: { width: '100%', height: '100%', objectFit: 'contain', position: 'absolute', inset: 0 } }), isGenerating && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: { position: 'absolute', inset: 0, backgroundColor: 'rgba(0,0,0,0.3)', zIndex: 9 } }), (0, jsx_runtime_1.jsx)("div", { className: "gifs\u00EDa-scan-line" })] }))] })) : ((0, jsx_runtime_1.jsxs)("button", { onClick: handleUploadClick, style: {
403
504
  padding: '12px 24px', borderRadius: '24px', border: 'none',
404
505
  backgroundColor: th.primaryColor, color: '#FFFFFF',
405
506
  fontSize: '14px', fontWeight: 600, cursor: 'pointer',
@@ -413,17 +514,18 @@ function GifsIa({ config, galleryItems: galleryProp, theme = {}, texts = {}, ima
413
514
  transition: 'background-color 0.2s',
414
515
  }, onMouseEnter: (e) => { if (uploadedImageBase64 && !isGenerating)
415
516
  e.currentTarget.style.backgroundColor = th.primaryHoverColor; }, onMouseLeave: (e) => { if (uploadedImageBase64 && !isGenerating)
416
- e.currentTarget.style.backgroundColor = createBtnColor; }, children: isGenerating ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: { width: '16px', height: '16px', border: '2px solid rgba(255,255,255,0.3)', borderTop: '2px solid #FFFFFF', borderRadius: '50%', animation: 'gifsía-spin 1s linear infinite' } }), t.creatingGifButton] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: (0, jsx_runtime_1.jsx)("polygon", { points: "13 2 3 14 12 14 11 22 21 10 12 10 13 2" }) }), t.createGifButton] })) })] }), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column', gap: '12px' }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center', gap: '8px' }, children: [(0, jsx_runtime_1.jsx)(GifBadge, { color: th.primaryColor }), (0, jsx_runtime_1.jsx)("span", { style: { fontSize: '16px', fontWeight: 700, color: th.primaryColor }, children: t.gifSectionTitle })] }), (0, jsx_runtime_1.jsx)("div", { className: "gifs\u00EDa-checker", style: {
517
+ e.currentTarget.style.backgroundColor = createBtnColor; }, children: isGenerating ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: { width: '16px', height: '16px', border: '2px solid rgba(255,255,255,0.3)', borderTop: '2px solid #FFFFFF', borderRadius: '50%', animation: 'gifsía-spin 1s linear infinite' } }), t.creatingGifButton] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: (0, jsx_runtime_1.jsx)("polygon", { points: "13 2 3 14 12 14 11 22 21 10 12 10 13 2" }) }), t.createGifButton] })) })] }), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column', gap: '12px' }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center', gap: '8px' }, children: [(0, jsx_runtime_1.jsx)(GifBadge, { color: th.primaryColor }), (0, jsx_runtime_1.jsx)("span", { style: { fontSize: '16px', fontWeight: 700, color: th.primaryColor }, children: t.gifSectionTitle })] }), (0, jsx_runtime_1.jsx)("div", { style: {
417
518
  position: 'relative', borderRadius: '10px', border: `2px dashed ${th.borderColor}`,
418
519
  minHeight: '320px', display: 'flex', alignItems: 'center', justifyContent: 'center',
419
520
  overflow: 'hidden', flex: 1,
420
- }, children: genError ? ((0, jsx_runtime_1.jsx)("p", { style: { color: '#F87171', fontSize: '14px', textAlign: 'center', padding: '24px' }, children: genError })) : generatedGifUrl ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("img", { src: generatedGifUrl, alt: "GIF generado", style: { width: '100%', height: '100%', objectFit: 'contain', position: 'absolute', inset: 0 } }), (0, jsx_runtime_1.jsx)("button", { onClick: () => window.open(generatedGifUrl, '_blank'), style: {
521
+ backgroundColor: gifBg,
522
+ }, children: genError ? ((0, jsx_runtime_1.jsx)("p", { style: { color: '#F87171', fontSize: '14px', textAlign: 'center', padding: '24px' }, children: genError })) : generatedGifUrl ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("img", { src: generatedGifUrl, alt: "Generated GIF", style: { width: '100%', height: '100%', objectFit: 'contain', position: 'absolute', inset: 0 }, unselectable: "on" }), (0, jsx_runtime_1.jsx)("button", { onClick: () => window.open(generatedGifUrl, '_blank'), style: {
421
523
  position: 'absolute', bottom: '12px', right: '12px', zIndex: 20,
422
524
  width: '40px', height: '40px', borderRadius: '50%', border: 'none',
423
525
  backgroundColor: th.primaryColor, color: '#FFFFFF',
424
526
  display: 'flex', alignItems: 'center', justifyContent: 'center',
425
527
  cursor: 'pointer', boxShadow: '0 2px 8px rgba(0,0,0,0.3)',
426
- }, children: (0, jsx_runtime_1.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: (0, jsx_runtime_1.jsx)("path", { d: "M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" }) }) })] })) : isGenerating ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [selectedGalleryId !== null && gallery.find(g => g.id === selectedGalleryId) && ((0, jsx_runtime_1.jsx)("img", { src: gallery.find(g => g.id === selectedGalleryId).imageUrl, alt: "", style: { position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', filter: 'blur(4px)', opacity: 0.5 } })), (0, jsx_runtime_1.jsxs)("div", { style: { position: 'relative', zIndex: 10, width: '80%', textAlign: 'center' }, children: [(0, jsx_runtime_1.jsx)("div", { style: { backgroundColor: 'rgba(0,0,0,0.6)', borderRadius: '8px', padding: '4px 12px', marginBottom: '8px' }, children: (0, jsx_runtime_1.jsx)("span", { style: { fontSize: '14px', color: '#FFFFFF', fontWeight: 600 }, children: queuePosition !== null && queuePosition > 0
528
+ }, children: (0, jsx_runtime_1.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: (0, jsx_runtime_1.jsx)("path", { d: "M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" }) }) })] })) : isGenerating ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [selectedGalleryId !== null && gallery.find(g => g.id === selectedGalleryId) && ((0, jsx_runtime_1.jsx)("img", { src: gallery.find(g => g.id === selectedGalleryId).imageUrl, alt: "", style: { position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', filter: 'blur(4px)', opacity: 0.3 } })), (0, jsx_runtime_1.jsxs)("div", { style: { position: 'relative', zIndex: 10, width: '80%', textAlign: 'center' }, children: [(0, jsx_runtime_1.jsx)("div", { style: { backgroundColor: 'rgba(0,0,0,0.6)', borderRadius: '8px', padding: '4px 12px', marginBottom: '8px' }, children: (0, jsx_runtime_1.jsx)("span", { style: { fontSize: '14px', color: '#FFFFFF', fontWeight: 600 }, children: queuePosition !== null && queuePosition > 0
427
529
  ? `${t.queueText} #${queuePosition}`
428
530
  : `${progressPercent !== null && progressPercent !== void 0 ? progressPercent : 0}%` }) }), (0, jsx_runtime_1.jsx)("div", { style: { width: '100%', height: '8px', backgroundColor: 'rgba(255,255,255,0.2)', borderRadius: '4px', overflow: 'hidden' }, children: (0, jsx_runtime_1.jsx)("div", { style: {
429
531
  height: '100%', width: `${progressPercent !== null && progressPercent !== void 0 ? progressPercent : 0}%`,