[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of docs-bot/node/handlers/event.ts from the docs-bot VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {
  json
} from 'co-body'
import Github from '../clients/github'
import { getAppConfigs } from '../utils/utils'

const ANSWER_LATER_PATTERN = '[x] I\'ll do it later'
let appPem: any = null

export async function handleEvent(ctx: Context, next: () => Promise < any > ) {
  const {
    header: {
      'x-github-event': event,
    },
  } = ctx

  const body = await json(ctx.req)

  const {
    action,
  } = body

  if (!appPem) {
    appPem = (await getAppConfigs(ctx)).pem
  }

  ctx.set('cache-control', 'no-cache,no-store')

  ctx.clients.github.setAppPEM(appPem)

  ctx.vtex.logger.info({
    body: {
      action,
      event_type: event,
    },
    subject: 'github event',
  })

  if (event === 'pull_request') {
    if (action === 'closed') {
      ctx.vtex.logger.info({subject: 'pr closed', ...body})
      handleClosedPullRequest(body, ctx.clients.github)
    } else if (action === 'opened') {
      ctx.vtex.logger.info({subject: 'pr opened', ...body})
      handleNewPullRequest(body, ctx.clients.github)
    } else if (action === 'synchronize') {
      ctx.vtex.logger.info({subject: 'pr synchronized', ...body})
      handleSyncPullRequest(body, ctx.clients.github)
    }
  } else if (event === 'issue_comment' && action === 'edited') {
    ctx.vtex.logger.info({subject: 'comment edited', ...body})
    handleCommentEdit(body, ctx.clients.github)
  }

  ctx.status = 200
  ctx.body = 'ok'

  await next()
}

const handleSyncPullRequest = async (
  reqBody: any,
  gitClient: Github
): Promise < void > => {
  const {
    pull_request: {
      number: prNumber,
      head: {
        sha,
      },
    },
    repository: {
      full_name: repoName,
    },
  } = reqBody

  const changedDocs = checkDocsChanges(await gitClient.getPRFileChanges(repoName, prNumber))

  if (changedDocs) {
    await gitClient.createCommitStatus(
      repoName,
      'Docs in track',
      'vtex-io/docs-outdated-select',
      'success',
      sha
    )
  }
}

const handleClosedPullRequest = async (
  reqBody: any,
  gitClient: Github
): Promise < void > => {
  const {
    number: prNumber,
    pull_request: {
      title: prTitle,
      html_url: prUrl,
      merged,
      user: {
        login: prOwnerLogin,
      },
    },
    repository: {
      full_name: repoName,
      html_url: repoUrl,
    },
  } = reqBody

  if (!merged) {
    return
  }

  const comments = await gitClient.getPRComments(repoName, prNumber)

  for (const comment of comments) {
    const {
      user: {
        login,
      },
      body,
    } = comment

    if (login !== 'vtex-io-docs-bot[bot]') {
      continue
    }

    if (body.includes(ANSWER_LATER_PATTERN)) {
      await createUpcomingDocumentation(
        prTitle,
        prUrl,
        repoName,
        repoUrl,
        prOwnerLogin,
        prNumber,
        gitClient
      )

      return
    }
  }
}

const handleNewPullRequest = async (
  reqBody: any,
  gitClient: Github
): Promise < boolean > => {
  const {
    pull_request: {
      number: prNumber,
      head: {
        sha,
      },
    },
    repository: {
      full_name: repoName,
    },
  } = reqBody

  try {
    await gitClient.getFileContents(repoName, '/docs/README.md')
  } catch (e) {
    await gitClient.writeComment(
      repoName,
      prNumber,
      'Beep boop :robot:\n\n' +
      'I noticed you\'re not using the Docs Builder properly yet, '+
      'if you need help to set that up please go to [IO Documentation](https://github.com/vtex-apps/io-documentation)'
    )

    return true
  }

  const changedDocs = checkDocsChanges(await gitClient.getPRFileChanges(repoName, prNumber))

  if (!changedDocs) {
    await gitClient.writeComment(
      repoName,
      prNumber,
      'Beep boop :robot:\n\n' +
      'I noticed you didn\'t make any changes at the `docs/` folder\n' +
      '- [ ] There\'s nothing new to document :thinking:\n' +
      '- [ ] I\'ll do it later :disappointed:\n' +
      '\nIn order to keep track, I\'ll create an issue if you decide now is not a good time\n\n' +
      '- [ ] I just updated :tada::tada:')

    await gitClient.createCommitStatus(
      repoName,
      'Forgot to select the reason for not updating docs',
      'vtex-io/docs-outdated-select',
      'failure',
      sha
    )
  } else {
    await gitClient.writeComment(
      repoName,
      prNumber,
      'Beep boop :robot:\n\n Thank you so much for keeping our documentation up-to-date :heart:')

    await gitClient.createCommitStatus(
      repoName,
      'Docs in track',
      'vtex-io/docs-outdated-select',
      'success',
      sha
    )
  }

  return true
}

const handleCommentEdit = async (
  reqBody: any,
  gitClient: Github
): Promise < boolean > => {
  const {
    issue: {
      number: prNumber,
    },
    repository: {
      full_name: repoName,
    },
    comment: {
      user: {
        login: commentOwner,
      },
      body,
    },
  } = reqBody

  if (commentOwner !== 'vtex-io-docs-bot[bot]') {
    return true
  }

  const {
    head: {
      sha,
    },
  } = await gitClient.getPR(repoName, prNumber)

  await gitClient.createCommitStatus(
    repoName,
    'Justified docs update absence',
    'vtex-io/docs-outdated-select',
    'success',
    sha
  )

  if (!body.includes(ANSWER_LATER_PATTERN)) {
    return true
  }

  return true
}

const checkDocsChanges = (fileChanges: any): boolean => {
  for (const {
      filename,
    } of fileChanges) {
    if (filename.includes('docs/')) {
      return true
    }
  }
  return false
}

const createUpcomingDocumentation = async (
  issueTitle: string,
  issueUrl: string,
  repoName: string,
  repoUrl: string,
  editor: string,
  prNumber: string,
  gitClient: Github
): Promise < void > => {
  const issueLinkLabel = `[${issueTitle}](${issueUrl})`

  const docIssue = await gitClient.createNewIssue(
    'vtex-apps/io-documentation',
    `Upcoming docs in ${repoName}`,
    `@${editor} is going to update soon a new feature/enhancement on [${repoName}](${repoUrl})\n` +
    `For more information go to:\n` +
    issueLinkLabel,
    ['upcoming-docs'])

  await gitClient.writeComment(
    repoName,
    prNumber,
    `Beep boop :robot: That\'s ok, I created an [issue](${docIssue.html_url}) for this so we don\'t forget`)

  const readme = await gitClient.getFileContents(
    repoName,
    '/docs/README.md'
  )

  let updateContent = readme.content

  updateContent +=
    `${!updateContent.includes('Upcoming documentation') ? `\n\n**Upcoming documentation:**\n` : ''}` +
    `\n - ${issueLinkLabel}`

  await gitClient.updateFileContents(
    repoName,
    '/docs/README.md',
    'Upcoming docs',
    updateContent,
    readme.sha
  )
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/messages/it-IT.json from the store-image VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.image-list.description": "Mostra un elenco di immagini",
  "admin/editor.image-list.height.title": "Altezza massima per ciascuna immagine (px)",
  "admin/editor.image-list.images.description.title": "Descrizione alternativa dell'immagine",
  "admin/editor.image-list.images.image.title": "Immagine",
  "admin/editor.image-list.images.link.noFollow.title": "Link nofollow",
  "admin/editor.image-list.images.link.openNewTab.title": "Aprire in una nuova scheda",
  "admin/editor.image-list.images.link.title.title": "Titolo del link",
  "admin/editor.image-list.images.link.url.title": "URL del link dell'immagine",
  "admin/editor.image-list.images.mobileImage.title": "Immagine per dispositivi mobili",
  "admin/editor.image-list.images.title.title": "Titolo dell'immagine",
  "admin/editor.image-list.images.title": "Immagini",
  "admin/editor.image-list.images.width.description": "Larghezza per singola immagine (% o px)",
  "admin/editor.image-list.images.height.title": "Altezza dell'immagine",
  "admin/editor.image-list.images.height.description": "Altezza dell'immagine per una singola immagine (px)",
  "admin/editor.image-list.images.width.title": "Larghezza immagine",
  "admin/editor.image-list.title": "Elenco di immagini",
  "admin/editor.image-slider.description": "Slider di immagini",
  "admin/editor.image-slider.slider.infinite": "Infinito",
  "admin/editor.image-slider.slider.showNavigation": "Mostra frecce di navigazione",
  "admin/editor.image-slider.slider.showPaginationDots": "Mostra punti di impaginazione",
  "admin/editor.image-slider.slider.title": "Opzioni dello slider",
  "admin/editor.image-slider.slider.usePagination": "Utilizza impaginazione",
  "admin/editor.image-slider.title": "Slider di immagini",
  "admin/editor.image.analytics.none": "No",
  "admin/editor.image.analytics.promotionId": "ID della promozione",
  "admin/editor.image.analytics.promotionName": "Nome della promozione",
  "admin/editor.image.analytics.promotionPosition": "Posizione creativa",
  "admin/editor.image.analytics.promotionProductId": "ID del prodotto",
  "admin/editor.image.analytics.promotionProductName": "Nome del prodotto",
  "admin/editor.image.analytics.provide": "Sì",
  "admin/editor.image.analytics.title": "Evento di \"Analisi\"",
  "admin/editor.store-image.alt.title": "Descrizione alternativa",
  "admin/editor.store-image.fetchpriority.auto": "Lascia che il browser decida la priorità",
  "admin/editor.store-image.fetchpriority.high": "Priorità alta",
  "admin/editor.store-image.fetchpriority.low": "Priorità bassa",
  "admin/editor.store-image.fetchpriority.title": "Suggerisci la priorità di caricamento",
  "admin/editor.store-image.loading.eager": "Durante il caricamento della pagina",
  "admin/editor.store-image.loading.lazy": "Quando ci si avvicina al riquadro di visualizzazione",
  "admin/editor.store-image.loading.title": "Strategia di caricamento",
  "admin/editor.store-image.src.title": "Immagine",
  "admin/editor.store-image.title.description": "Titolo da mostrare al passaggio del mouse",
  "admin/editor.store-image.title.title": "Titolo dell'immagine",
  "admin/editor.store-image.title": "Immagine"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/messages/th-TH.json from the store-image VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.image-list.description": "แสดงรายการรูป",
  "admin/editor.image-list.height.title": "ความสูงมากสุดสำหรับแต่ละรูป (px)",
  "admin/editor.image-list.images.description.title": "alt text ของรูป",
  "admin/editor.image-list.images.image.title": "รูป",
  "admin/editor.image-list.images.link.noFollow.title": "ควรเป็นลิงก์ Nofollow",
  "admin/editor.image-list.images.link.openNewTab.title": "ควรเปิดเป็นแท็บใหม่",
  "admin/editor.image-list.images.link.title.title": "คำเรียกลิงก์",
  "admin/editor.image-list.images.link.url.title": "URL ลิงก์รูป",
  "admin/editor.image-list.images.mobileImage.title": "รูปสำหรับมือถือ",
  "admin/editor.image-list.images.title.title": "ชื่อรูป",
  "admin/editor.image-list.images.title": "รูป",
  "admin/editor.image-list.images.width.description": "ความกว้างรูปสำหรับรูปหนึ่งใบ (% หรือ px)",
  "admin/editor.image-list.images.height.title": "ความสูงรูปภาพ",
  "admin/editor.image-list.images.height.description": "ความกว้างรูปสำหรับรูปหนึ่งใบ (px)",
  "admin/editor.image-list.images.width.title": "ความกว้างรูป",
  "admin/editor.image-list.title": "รายการรูป",
  "admin/editor.image-slider.description": "ตัวเลื่อนดูภาพ",
  "admin/editor.image-slider.slider.infinite": "ไม่จำกัด",
  "admin/editor.image-slider.slider.showNavigation": "แสดงลูกศรการนำทาง",
  "admin/editor.image-slider.slider.showPaginationDots": "แสดงจุดประการแบ่งหน้า",
  "admin/editor.image-slider.slider.title": "ทางเลือกตัวเลื่อน",
  "admin/editor.image-slider.slider.usePagination": "ใช้การแบ่งหน้า",
  "admin/editor.image-slider.title": "ตัวเลื่อนดูภาพ",
  "admin/editor.image.analytics.none": "ไม่",
  "admin/editor.image.analytics.promotionId": "ID โปรโมชัน",
  "admin/editor.image.analytics.promotionName": "ชื่อโปรโมชัน",
  "admin/editor.image.analytics.promotionPosition": "ตำแหน่งครีเอทีฟ",
  "admin/editor.image.analytics.promotionProductId": "รหัสผลิตภัณฑ์",
  "admin/editor.image.analytics.promotionProductName": "ชื่อผลิตภัณฑ์",
  "admin/editor.image.analytics.provide": "ใช่",
  "admin/editor.image.analytics.title": "อีเวนต์การวิเคราะห์",
  "admin/editor.store-image.alt.title": "ข้อความสำรอง",
  "admin/editor.store-image.fetchpriority.auto": "ให้เบราว์เซอร์เป็นตัวกำหนดลำดับความสำคัญ",
  "admin/editor.store-image.fetchpriority.high": "ลำดับความสำคัญสูง",
  "admin/editor.store-image.fetchpriority.low": "ลำดับความสำคัญต่ำ",
  "admin/editor.store-image.fetchpriority.title": "แนะนำลำดับความสำคัญ",
  "admin/editor.store-image.loading.eager": "เมื่อโหลดหน้าเพจ",
  "admin/editor.store-image.loading.lazy": "เมื่อใกล้เคียงกับขนาด Viewport มากกว่า",
  "admin/editor.store-image.loading.title": "กลยุทธ์การโหลด",
  "admin/editor.store-image.src.title": "รูป",
  "admin/editor.store-image.title.description": "ชื่อที่จะแสดงเมื่อลากเมาส์ผ่าน",
  "admin/editor.store-image.title.title": "ชื่อรูป",
  "admin/editor.store-image.title": "รูป"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/messages/ko-KR.json from the store-image VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.image-list.description": "이미지 목록 표시",
  "admin/editor.image-list.height.title": "각 이미지의 최대 높이(px)",
  "admin/editor.image-list.images.description.title": "이미지 alt 텍스트",
  "admin/editor.image-list.images.image.title": "이미지",
  "admin/editor.image-list.images.link.noFollow.title": "nofollow 링크여야 함",
  "admin/editor.image-list.images.link.openNewTab.title": "새 탭에서 열어야 함",
  "admin/editor.image-list.images.link.title.title": "링크 제목",
  "admin/editor.image-list.images.link.url.title": "이미지 링크 URL",
  "admin/editor.image-list.images.mobileImage.title": "모바일용 이미지",
  "admin/editor.image-list.images.title.title": "이미지 제목",
  "admin/editor.image-list.images.title": "이미지",
  "admin/editor.image-list.images.width.description": "단일 이미지의 이미지 너비(% 또는 px)",
  "admin/editor.image-list.images.height.title": "이미지 높이",
  "admin/editor.image-list.images.height.description": "단일 이미지의 이미지 높이(px)",
  "admin/editor.image-list.images.width.title": "이미지 너비",
  "admin/editor.image-list.title": "이미지 목록",
  "admin/editor.image-slider.description": "이미지 슬라이더",
  "admin/editor.image-slider.slider.infinite": "무한",
  "admin/editor.image-slider.slider.showNavigation": "탐색 화살표 표시",
  "admin/editor.image-slider.slider.showPaginationDots": "페이지 번호 점 표시",
  "admin/editor.image-slider.slider.title": "슬라이더 옵션",
  "admin/editor.image-slider.slider.usePagination": "페이지 번호 사용",
  "admin/editor.image-slider.title": "이미지 슬라이더",
  "admin/editor.image.analytics.none": "아니요",
  "admin/editor.image.analytics.promotionId": "프로모션 ID",
  "admin/editor.image.analytics.promotionName": "프로모션 이름",
  "admin/editor.image.analytics.promotionPosition": "창의적 위치",
  "admin/editor.image.analytics.promotionProductId": "제품 ID",
  "admin/editor.image.analytics.promotionProductName": "제품 이름",
  "admin/editor.image.analytics.provide": "예",
  "admin/editor.image.analytics.title": "애널리틱스 이벤트",
  "admin/editor.store-image.alt.title": "대체 텍스트",
  "admin/editor.store-image.fetchpriority.auto": "브라우저에서 우선순위를 결정하게 하세요",
  "admin/editor.store-image.fetchpriority.high": "높은 우선순위",
  "admin/editor.store-image.fetchpriority.low": "낮은 우선순위",
  "admin/editor.store-image.fetchpriority.title": "우선순위 힌트 가져오기",
  "admin/editor.store-image.loading.eager": "페이지 로드 시",
  "admin/editor.store-image.loading.lazy": "뷰포트에 가까워질시",
  "admin/editor.store-image.loading.title": "로드 전략",
  "admin/editor.store-image.src.title": "이미지",
  "admin/editor.store-image.title.description": "가리키면 표시할 제목",
  "admin/editor.store-image.title.title": "이미지 제목",
  "admin/editor.store-image.title": "이미지"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/messages/ja-JP.json from the store-image VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.image-list.description": "画像のリストを表示する",
  "admin/editor.image-list.height.title": "それぞれの画像の最大高 (px)",
  "admin/editor.image-list.images.description.title": "画像代替テキスト",
  "admin/editor.image-list.images.image.title": "画像",
  "admin/editor.image-list.images.link.noFollow.title": "フォローのないリンクにしてください",
  "admin/editor.image-list.images.link.openNewTab.title": "新しいタブで開いてください",
  "admin/editor.image-list.images.link.title.title": "リンクのタイトル",
  "admin/editor.image-list.images.link.url.title": "画像リンク URL",
  "admin/editor.image-list.images.mobileImage.title": "モバイル用画像",
  "admin/editor.image-list.images.title.title": "画像のタイトル",
  "admin/editor.image-list.images.title": "画像",
  "admin/editor.image-list.images.width.description": "1つの画像に対する画像幅 (% または px)",
  "admin/editor.image-list.images.height.title": "画像の高さ",
  "admin/editor.image-list.images.height.description": "1つの画像に対する画像高さ（px）",
  "admin/editor.image-list.images.width.title": "画像幅",
  "admin/editor.image-list.title": "画像リスト",
  "admin/editor.image-slider.description": "画像スライダ",
  "admin/editor.image-slider.slider.infinite": "上限なし",
  "admin/editor.image-slider.slider.showNavigation": "方向矢印を表示する",
  "admin/editor.image-slider.slider.showPaginationDots": "ページネーションドットを表示する",
  "admin/editor.image-slider.slider.title": "スライダオプション",
  "admin/editor.image-slider.slider.usePagination": "ページネーションを使う",
  "admin/editor.image-slider.title": "画像スライダ",
  "admin/editor.image.analytics.none": "いいえ",
  "admin/editor.image.analytics.promotionId": "プロモーション ID",
  "admin/editor.image.analytics.promotionName": "プロモーション名",
  "admin/editor.image.analytics.promotionPosition": "クリエイティブポジション",
  "admin/editor.image.analytics.promotionProductId": "商品ID",
  "admin/editor.image.analytics.promotionProductName": "商品名",
  "admin/editor.image.analytics.provide": "はい",
  "admin/editor.image.analytics.title": "アナリティクスイベント",
  "admin/editor.store-image.alt.title": "代替テキスト",
  "admin/editor.store-image.fetchpriority.auto": "ブラウザに優先順位を決めさせる",
  "admin/editor.store-image.fetchpriority.high": "高い優先順位",
  "admin/editor.store-image.fetchpriority.low": "低い優先順位",
  "admin/editor.store-image.fetchpriority.title": "優先順位のヒントを取得",
  "admin/editor.store-image.loading.eager": "ページ読み込み時",
  "admin/editor.store-image.loading.lazy": "ビューポートに近づいた時",
  "admin/editor.store-image.loading.title": "読み込み戦略",
  "admin/editor.store-image.src.title": "画像",
  "admin/editor.store-image.title.description": "重ねて生じされるタイトル",
  "admin/editor.store-image.title.title": "画像のタイトル",
  "admin/editor.store-image.title": "画像"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/messages/bg-BG.json from the store-image VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.image-list.description": "Показва списък с изображения",
  "admin/editor.image-list.height.title": "Максимална височина за всяко изображение (px)",
  "admin/editor.image-list.images.description.title": "Алтернативен текст за изображение",
  "admin/editor.image-list.images.image.title": "Изображение",
  "admin/editor.image-list.images.link.noFollow.title": "Би трябвало да е nofollow линк",
  "admin/editor.image-list.images.link.openNewTab.title": "Би трябвало да се отваря в нов раздел",
  "admin/editor.image-list.images.link.title.title": "Заглавие на линка",
  "admin/editor.image-list.images.link.url.title": "URL адрес с линк за изображението",
  "admin/editor.image-list.images.mobileImage.title": "Изображение за мобилно устройство",
  "admin/editor.image-list.images.title.title": "Заглавие на изображение",
  "admin/editor.image-list.images.title": "Изображения",
  "admin/editor.image-list.images.width.description": "Широчина на изображението за единично изображение (% или px)",
  "admin/editor.image-list.images.height.title": "Височина на изображението",
  "admin/editor.image-list.images.height.description": "Височина на изображението за едно изображение (% или px)",
  "admin/editor.image-list.images.width.title": "Широчина на изображението",
  "admin/editor.image-list.title": "Списък с изображения",
  "admin/editor.image-slider.description": "Слайдер на изображението",
  "admin/editor.image-slider.slider.infinite": "Безкрайно",
  "admin/editor.image-slider.slider.showNavigation": "Показване на навигационни стрелки",
  "admin/editor.image-slider.slider.showPaginationDots": "Показване на точки за страниране",
  "admin/editor.image-slider.slider.title": "Опции на слайдера",
  "admin/editor.image-slider.slider.usePagination": "Използване на страниране",
  "admin/editor.image-slider.title": "Слайдер на изображението",
  "admin/editor.image.analytics.none": "Не",
  "admin/editor.image.analytics.promotionId": "ИД на промоция",
  "admin/editor.image.analytics.promotionName": "Име на промоция",
  "admin/editor.image.analytics.promotionPosition": "Креативно позициониране",
  "admin/editor.image.analytics.promotionProductId": "ИД на продукт",
  "admin/editor.image.analytics.promotionProductName": "Име на продукта",
  "admin/editor.image.analytics.provide": "Да",
  "admin/editor.image.analytics.title": "Събитие за анализ",
  "admin/editor.store-image.alt.title": "Алтернативен текст",
  "admin/editor.store-image.fetchpriority.auto": "Оставете браузъра да определи приоритета",
  "admin/editor.store-image.fetchpriority.high": "Висок приоритет",
  "admin/editor.store-image.fetchpriority.low": "Нисък приоритет",
  "admin/editor.store-image.fetchpriority.title": "Извличане на подсказване за приоритет",
  "admin/editor.store-image.loading.eager": "При зареждане на страницата",
  "admin/editor.store-image.loading.lazy": "Когато е по-близо до погледа",
  "admin/editor.store-image.loading.title": "Стратегия за зареждане",
  "admin/editor.store-image.src.title": "Изображение",
  "admin/editor.store-image.title.description": "Заглавието се показва при задържане на мишката",
  "admin/editor.store-image.title.title": "Заглавие на изображението",
  "admin/editor.store-image.title": "Изображение"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/messages/pt.json from the store-image VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.image-list.description": "Exibe uma lista de imagens",
  "admin/editor.image-list.height.title": "Altura máxima de cada imagem (px)",
  "admin/editor.image-list.images.description.title": "Descrição alternativa para a imagem",
  "admin/editor.image-list.images.image.title": "Imagem",
  "admin/editor.image-list.images.link.noFollow.title": "Link nofollow",
  "admin/editor.image-list.images.link.openNewTab.title": "Abrir em uma nova aba",
  "admin/editor.image-list.images.link.title.title": "Título para o link",
  "admin/editor.image-list.images.link.url.title": "URL do link da imagem",
  "admin/editor.image-list.images.mobileImage.title": "Imagem para dispositivos móveis",
  "admin/editor.image-list.images.title.title": "Título da imagem",
  "admin/editor.image-list.images.title": "Imagens",
  "admin/editor.image-list.images.width.description": "Largura de imagem para uma única imagem (% ou px)",
  "admin/editor.image-list.images.height.title": "Altura da imagem",
  "admin/editor.image-list.images.height.description": "Altura de imagem para uma única imagem (px)",
  "admin/editor.image-list.images.width.title": "Largura da imagem",
  "admin/editor.image-list.title": "Lista de imagens",
  "admin/editor.image-slider.description": "Slider de imagens",
  "admin/editor.image-slider.slider.infinite": "Infinito",
  "admin/editor.image-slider.slider.showNavigation": "Mostrar setas para navegação",
  "admin/editor.image-slider.slider.showPaginationDots": "Mostrar indicadores de paginação",
  "admin/editor.image-slider.slider.title": "Configurações do slider",
  "admin/editor.image-slider.slider.usePagination": "Usar paginação",
  "admin/editor.image-slider.title": "Slider de imagens",
  "admin/editor.image.analytics.none": "Não",
  "admin/editor.image.analytics.promotionId": "ID da promoção",
  "admin/editor.image.analytics.promotionName": "Nome da promoção",
  "admin/editor.image.analytics.promotionPosition": "Posição do criativo",
  "admin/editor.image.analytics.promotionProductId": "ID do produto",
  "admin/editor.image.analytics.promotionProductName": "Nome do produto",
  "admin/editor.image.analytics.provide": "Sim",
  "admin/editor.image.analytics.title": "Evento do Analytics",
  "admin/editor.store-image.alt.title": "Texto alternativo",
  "admin/editor.store-image.fetchpriority.auto": "Deixar o navegador definir a prioridade",
  "admin/editor.store-image.fetchpriority.high": "Prioridade alta",
  "admin/editor.store-image.fetchpriority.low": "Prioridade baixa",
  "admin/editor.store-image.fetchpriority.title": "Sugestão de prioridade de carga",
  "admin/editor.store-image.loading.eager": "Ao carregar a página",
  "admin/editor.store-image.loading.lazy": "Ao se aproximar da janela de visualização",
  "admin/editor.store-image.loading.title": "Estratégia de carregamento",
  "admin/editor.store-image.src.title": "Imagem",
  "admin/editor.store-image.title.description": "Título a ser mostrado ao passar o mouse pela imagem",
  "admin/editor.store-image.title.title": "Título da imagem",
  "admin/editor.store-image.title": "Imagem"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/messages/en.json from the store-image VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.image-list.description": "Show a list of images",
  "admin/editor.image-list.height.title": "Maximum height for each image (px)",
  "admin/editor.image-list.images.description.title": "Image alt text",
  "admin/editor.image-list.images.image.title": "Image",
  "admin/editor.image-list.images.link.noFollow.title": "Nofollow link",
  "admin/editor.image-list.images.link.openNewTab.title": "Open in new tab",
  "admin/editor.image-list.images.link.title.title": "Title for the link",
  "admin/editor.image-list.images.link.url.title": "Image link URL",
  "admin/editor.image-list.images.mobileImage.title": "Image for mobile",
  "admin/editor.image-list.images.title.title": "Image title",
  "admin/editor.image-list.images.title": "Images",
  "admin/editor.image-list.images.width.description": "Image width for a single image (% or px)",
  "admin/editor.image-list.images.height.title": "Image height",
  "admin/editor.image-list.images.height.description": "Image height for a single image (px)",
  "admin/editor.image-list.images.width.title": "Image width",
  "admin/editor.image-list.title": "Image List",
  "admin/editor.image-slider.description": "Image slider",
  "admin/editor.image-slider.slider.infinite": "Infinite",
  "admin/editor.image-slider.slider.showNavigation": "Show navigation arrows",
  "admin/editor.image-slider.slider.showPaginationDots": "Show pagination dots",
  "admin/editor.image-slider.slider.title": "Slider options",
  "admin/editor.image-slider.slider.usePagination": "Use pagination",
  "admin/editor.image-slider.title": "Image Slider",
  "admin/editor.image.analytics.none": "No",
  "admin/editor.image.analytics.promotionId": "Promotion ID",
  "admin/editor.image.analytics.promotionName": "Promotion name",
  "admin/editor.image.analytics.promotionPosition": "Creative position",
  "admin/editor.image.analytics.promotionProductId": "Product ID",
  "admin/editor.image.analytics.promotionProductName": "Product Name",
  "admin/editor.image.analytics.provide": "Yes",
  "admin/editor.image.analytics.title": "Analytics event",
  "admin/editor.store-image.alt.title": "Alternative text",
  "admin/editor.store-image.fetchpriority.auto": "Let the browser decide the priority",
  "admin/editor.store-image.fetchpriority.high": "High priority",
  "admin/editor.store-image.fetchpriority.low": "Low priority",
  "admin/editor.store-image.fetchpriority.title": "Fetch priority hint",
  "admin/editor.store-image.loading.eager": "When page loads",
  "admin/editor.store-image.loading.lazy": "When closer to the viewport",
  "admin/editor.store-image.loading.title": "Loading strategy",
  "admin/editor.store-image.src.title": "Image",
  "admin/editor.store-image.title.description": "Title shown on hover",
  "admin/editor.store-image.title.title": "Image title",
  "admin/editor.store-image.title": "Image"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/messages/ro-RO.json from the store-image VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.image-list.description": "Arată o listă de imagini",
  "admin/editor.image-list.height.title": "Înălțime maximă pentru fiecare imagine (px)",
  "admin/editor.image-list.images.description.title": "Text imagine alternativă",
  "admin/editor.image-list.images.image.title": "Imagine",
  "admin/editor.image-list.images.link.noFollow.title": "Trebuie să fie un link nofollow",
  "admin/editor.image-list.images.link.openNewTab.title": "Trebuie să se deschidă într-o filă nouă",
  "admin/editor.image-list.images.link.title.title": "Titlul link-ului",
  "admin/editor.image-list.images.link.url.title": "URL link imagine",
  "admin/editor.image-list.images.mobileImage.title": "Imagini pentru mobil",
  "admin/editor.image-list.images.title.title": "Titlu imagine",
  "admin/editor.image-list.images.title": "Imagini",
  "admin/editor.image-list.images.width.description": "Lățimea maximă a imaginii pentru o singură imagine (% sau px)",
  "admin/editor.image-list.images.height.title": "Înălțime imagine",
  "admin/editor.image-list.images.height.description": "Lățimea imaginii pentru o singură imagine (px)",
  "admin/editor.image-list.images.width.title": "Lățime imagine",
  "admin/editor.image-list.title": "Listă imagine",
  "admin/editor.image-slider.description": "Glisor imagine",
  "admin/editor.image-slider.slider.infinite": "Infinit",
  "admin/editor.image-slider.slider.showNavigation": "Arată săgețile de navigare",
  "admin/editor.image-slider.slider.showPaginationDots": "Arată punctele de paginație",
  "admin/editor.image-slider.slider.title": "Opțiuni glisor",
  "admin/editor.image-slider.slider.usePagination": "Folosește paginația",
  "admin/editor.image-slider.title": "Glisor imagine",
  "admin/editor.image.analytics.none": "Nu",
  "admin/editor.image.analytics.promotionId": "ID Promoție",
  "admin/editor.image.analytics.promotionName": "Denumire Promoție",
  "admin/editor.image.analytics.promotionPosition": "Poziție creativă",
  "admin/editor.image.analytics.promotionProductId": "ID produs",
  "admin/editor.image.analytics.promotionProductName": "Denumirea produsului",
  "admin/editor.image.analytics.provide": "Da",
  "admin/editor.image.analytics.title": "Eveniment Analytics",
  "admin/editor.store-image.alt.title": "Text alternativ",
  "admin/editor.store-image.fetchpriority.auto": "Lasă browserul să decidă prioritatea",
  "admin/editor.store-image.fetchpriority.high": "Prioritate ridicată",
  "admin/editor.store-image.fetchpriority.low": "Prioritate scăzută",
  "admin/editor.store-image.fetchpriority.title": "Indicație cu privire la prioritatea de preluare",
  "admin/editor.store-image.loading.eager": "La încărcarea paginii",
  "admin/editor.store-image.loading.lazy": "Când este mai aproape de vizualizare",
  "admin/editor.store-image.loading.title": "Strategie de încărcare",
  "admin/editor.store-image.src.title": "Imagine",
  "admin/editor.store-image.title.description": "Titlul va fi afișat prin trecere",
  "admin/editor.store-image.title.title": "Titlu imagine",
  "admin/editor.store-image.title": "Imagine"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/messages/context.json from the store-image VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.image-list.description": "Show a list of images",
  "admin/editor.image-list.height.title": "Maximum height for each image (px)",
  "admin/editor.image-list.images.description.title": "Image alt text",
  "admin/editor.image-list.images.image.title": "Image",
  "admin/editor.image-list.images.link.noFollow.title": "Should be a nofollow link",
  "admin/editor.image-list.images.link.openNewTab.title": "Should open on new tab",
  "admin/editor.image-list.images.link.title.title": "Title for the link",
  "admin/editor.image-list.images.link.url.title": "Image link URL",
  "admin/editor.image-list.images.mobileImage.title": "Image for mobile",
  "admin/editor.image-list.images.title.title": "Image title",
  "admin/editor.image-list.images.title": "Images",
  "admin/editor.image-list.images.width.description": "Image width for a single image (% or px)",
  "admin/editor.image-list.images.height.title": "Image height",
  "admin/editor.image-list.images.height.description": "Image height for a single image (px)",
  "admin/editor.image-list.images.width.title": "Image width",
  "admin/editor.image-list.title": "Image List",
  "admin/editor.image-slider.description": "Image Slider",
  "admin/editor.image-slider.slider.infinite": "Infinite",
  "admin/editor.image-slider.slider.showNavigation": "Show navigation arrows",
  "admin/editor.image-slider.slider.showPaginationDots": "Show pagination dots",
  "admin/editor.image-slider.slider.title": "Slider options",
  "admin/editor.image-slider.slider.usePagination": "Use pagination",
  "admin/editor.image-slider.title": "Image Slider",
  "admin/editor.image.analytics.none": "No",
  "admin/editor.image.analytics.promotionId": "Promotion ID",
  "admin/editor.image.analytics.promotionName": "Promotion Name",
  "admin/editor.image.analytics.promotionPosition": "Creative position",
  "admin/editor.image.analytics.promotionProductId": "Product ID",
  "admin/editor.image.analytics.promotionProductName": "Product Name",
  "admin/editor.image.analytics.provide": "Yes",
  "admin/editor.image.analytics.title": "Analytics event",
  "admin/editor.store-image.alt.title": "Alternative text",
  "admin/editor.store-image.fetchpriority.auto": "Let the browser decide the priority.",
  "admin/editor.store-image.fetchpriority.high": "High priority",
  "admin/editor.store-image.fetchpriority.low": "Low priority",
  "admin/editor.store-image.fetchpriority.title": "Fetch priority hint",
  "admin/editor.store-image.loading.eager": "When page loads",
  "admin/editor.store-image.loading.lazy": "When closer to the viewport",
  "admin/editor.store-image.loading.title": "Loading strategy",
  "admin/editor.store-image.src.title": "Image",
  "admin/editor.store-image.title.description": "Title to be shown on hover",
  "admin/editor.store-image.title.title": "Image title",
  "admin/editor.store-image.title": "Image"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/messages/de-DE.json from the store-image VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.image-list.description": "Eine Liste von Bildern anzeigen",
  "admin/editor.image-list.height.title": "Maximale Höhe für jedes Bild (px)",
  "admin/editor.image-list.images.description.title": "Bild Alt-Text",
  "admin/editor.image-list.images.image.title": "Bild",
  "admin/editor.image-list.images.link.noFollow.title": "Sollte ein Nofollow-Link sein",
  "admin/editor.image-list.images.link.openNewTab.title": "Soll in neuem Tab öffnen",
  "admin/editor.image-list.images.link.title.title": "Titel für den Link",
  "admin/editor.image-list.images.link.url.title": "URL des Bild-Links",
  "admin/editor.image-list.images.mobileImage.title": "Bild für Handy",
  "admin/editor.image-list.images.title.title": "Bildtitel",
  "admin/editor.image-list.images.title": "Bilder",
  "admin/editor.image-list.images.width.description": "Bildbreite für ein einzelnes Bild (% oder px)",
  "admin/editor.image-list.images.height.title": "Bildhöhe",
  "admin/editor.image-list.images.height.description": "Bildhöhe für ein einzelnes Bild (px)",
  "admin/editor.image-list.images.width.title": "Bildbreite",
  "admin/editor.image-list.title": "Bildliste",
  "admin/editor.image-slider.description": "Bilder Slider",
  "admin/editor.image-slider.slider.infinite": "Unendlich",
  "admin/editor.image-slider.slider.showNavigation": "Navigationspfeile anzeigen",
  "admin/editor.image-slider.slider.showPaginationDots": "Punktenavigation anzeigen",
  "admin/editor.image-slider.slider.title": "Slider-Optionen",
  "admin/editor.image-slider.slider.usePagination": "Seitennavigation verwenden",
  "admin/editor.image-slider.title": "Bilder Slider",
  "admin/editor.image.analytics.none": "Nein",
  "admin/editor.image.analytics.promotionId": "Promotion-ID",
  "admin/editor.image.analytics.promotionName": "Promotionsname",
  "admin/editor.image.analytics.promotionPosition": "Kreative Position",
  "admin/editor.image.analytics.promotionProductId": "Produkt-ID",
  "admin/editor.image.analytics.promotionProductName": "Produktname",
  "admin/editor.image.analytics.provide": "Ja",
  "admin/editor.image.analytics.title": "Analytik-Ereignis",
  "admin/editor.store-image.alt.title": "Alternativer Text",
  "admin/editor.store-image.fetchpriority.auto": "Lassen Sie den Browser über die Priorität entscheiden",
  "admin/editor.store-image.fetchpriority.high": "Hohe Priorität",
  "admin/editor.store-image.fetchpriority.low": "Niedrige Priorität",
  "admin/editor.store-image.fetchpriority.title": "Hinweis auf die Abrufpriorität",
  "admin/editor.store-image.loading.eager": "Wenn die Seite geladen wird",
  "admin/editor.store-image.loading.lazy": "Bei Annäherung an das Ansichtsfenster",
  "admin/editor.store-image.loading.title": "Ladestrategie",
  "admin/editor.store-image.src.title": "Bild",
  "admin/editor.store-image.title.description": "Titel, der bei Mausverschiebung angezeigt wird",
  "admin/editor.store-image.title.title": "Bildtitel",
  "admin/editor.store-image.title": "Bild"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/messages/fr-FR.json from the store-image VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.image-list.description": "Afficher une liste d’images",
  "admin/editor.image-list.height.title": "Hauteur maximale pour chaque image (px)",
  "admin/editor.image-list.images.description.title": "Texte de remplacement de l’image",
  "admin/editor.image-list.images.image.title": "Photo",
  "admin/editor.image-list.images.link.noFollow.title": "Devrait être un lien nofollow",
  "admin/editor.image-list.images.link.openNewTab.title": "Devrait s’ouvrir dans un nouvel onglet",
  "admin/editor.image-list.images.link.title.title": "Titre pour le lien",
  "admin/editor.image-list.images.link.url.title": "URL du lien de l’image",
  "admin/editor.image-list.images.mobileImage.title": "Image pour mobile",
  "admin/editor.image-list.images.title.title": "Titre de l’mage",
  "admin/editor.image-list.images.title": "Images",
  "admin/editor.image-list.images.width.description": "Largeur de l’image pour une seule image (% ou px)",
  "admin/editor.image-list.images.height.title": "Hauteur de l'image",
  "admin/editor.image-list.images.height.description": "Hauteur de l’image pour une seule image (px)",
  "admin/editor.image-list.images.width.title": "Largeur de l’image",
  "admin/editor.image-list.title": "Liste d’images",
  "admin/editor.image-slider.description": "Curseur image",
  "admin/editor.image-slider.slider.infinite": "Infini",
  "admin/editor.image-slider.slider.showNavigation": "Afficher les flèches de navigation",
  "admin/editor.image-slider.slider.showPaginationDots": "Afficher les points de pagination",
  "admin/editor.image-slider.slider.title": "Options du curseur",
  "admin/editor.image-slider.slider.usePagination": "Utiliser la pagination",
  "admin/editor.image-slider.title": "Curseur image",
  "admin/editor.image.analytics.none": "Non",
  "admin/editor.image.analytics.promotionId": "ID de promotion",
  "admin/editor.image.analytics.promotionName": "Nom de promotion",
  "admin/editor.image.analytics.promotionPosition": "Position créative",
  "admin/editor.image.analytics.promotionProductId": "ID produit",
  "admin/editor.image.analytics.promotionProductName": "Nom du produit",
  "admin/editor.image.analytics.provide": "Oui",
  "admin/editor.image.analytics.title": "Évènement d’analyse",
  "admin/editor.store-image.alt.title": "Texte alternatif",
  "admin/editor.store-image.fetchpriority.auto": "Laisser le navigateur décider de la priorité",
  "admin/editor.store-image.fetchpriority.high": "Priorité élevée",
  "admin/editor.store-image.fetchpriority.low": "Priorité basse",
  "admin/editor.store-image.fetchpriority.title": "Récupérer l'indice de priorité",
  "admin/editor.store-image.loading.eager": "Lors du chargement de la page",
  "admin/editor.store-image.loading.lazy": "En se rapprochant de la fenêtre d'affichage",
  "admin/editor.store-image.loading.title": "Stratégie de chargement",
  "admin/editor.store-image.src.title": "Photo",
  "admin/editor.store-image.title.description": "Titre à afficher par pointage",
  "admin/editor.store-image.title.title": "Titre de l’image",
  "admin/editor.store-image.title": "Photo"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/messages/nl-NL.json from the store-image VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.image-list.description": "Toon een lijst van afbeeldingen",
  "admin/editor.image-list.height.title": "Maximale hoogte voor elke afbeelding (px)",
  "admin/editor.image-list.images.description.title": "Afbeelding alt-tekst",
  "admin/editor.image-list.images.image.title": "Afbeelding",
  "admin/editor.image-list.images.link.noFollow.title": "Moet een nofollow link zijn",
  "admin/editor.image-list.images.link.openNewTab.title": "Moet openen op een nieuwe tab",
  "admin/editor.image-list.images.link.title.title": "Titel voor de link",
  "admin/editor.image-list.images.link.url.title": "URL van afbeeldingslink",
  "admin/editor.image-list.images.mobileImage.title": "Afbeelding voor mobiel",
  "admin/editor.image-list.images.title.title": "Titel van de afbeelding",
  "admin/editor.image-list.images.title": "Afbeeldingen",
  "admin/editor.image-list.images.width.description": "Afbeeldingsbreedte voor één afbeelding (% of px)",
  "admin/editor.image-list.images.height.title": "Beeldhoogte",
  "admin/editor.image-list.images.height.description": "Beeldhoogte voor één afbeelding (px)",
  "admin/editor.image-list.images.width.title": "Afbeeldingsbreedte",
  "admin/editor.image-list.title": "Afbeeldinglijst",
  "admin/editor.image-slider.description": "Afbeelding schuifregelaar",
  "admin/editor.image-slider.slider.infinite": "Oneindig",
  "admin/editor.image-slider.slider.showNavigation": "Toon navigatiepijlen",
  "admin/editor.image-slider.slider.showPaginationDots": "Toon pagineringstippen",
  "admin/editor.image-slider.slider.title": "Schuifregelaar opties",
  "admin/editor.image-slider.slider.usePagination": "Gebruik paginering",
  "admin/editor.image-slider.title": "Afbeelding schuifregelaar",
  "admin/editor.image.analytics.none": "Nee",
  "admin/editor.image.analytics.promotionId": "Promotie-id",
  "admin/editor.image.analytics.promotionName": "Promotienaam",
  "admin/editor.image.analytics.promotionPosition": "Creatieve positie",
  "admin/editor.image.analytics.promotionProductId": "Product-ID",
  "admin/editor.image.analytics.promotionProductName": "Productnaam",
  "admin/editor.image.analytics.provide": "Ja",
  "admin/editor.image.analytics.title": "Analytics-gebeurtenis",
  "admin/editor.store-image.alt.title": "Alternatieve tekst",
  "admin/editor.store-image.fetchpriority.auto": "Laat de browser de prioriteit bepalen",
  "admin/editor.store-image.fetchpriority.high": "Hoge prioriteit",
  "admin/editor.store-image.fetchpriority.low": "Lage prioriteit",
  "admin/editor.store-image.fetchpriority.title": "Hint voor prioriteit ophalen",
  "admin/editor.store-image.loading.eager": "Wanneer de pagina wordt geladen",
  "admin/editor.store-image.loading.lazy": "Wanneer dichter bij de viewport",
  "admin/editor.store-image.loading.title": "Laden van strategie",
  "admin/editor.store-image.src.title": "Afbeelding",
  "admin/editor.store-image.title.description": "Titel die moet worden weergegeven bij zweven",
  "admin/editor.store-image.title.title": "Titel van de afbeelding",
  "admin/editor.store-image.title": "Afbeelding"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/messages/es.json from the store-image VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.image-list.description": "Mostrar una lista de imágenes",
  "admin/editor.image-list.height.title": "Altura máxima de cada imagen (px)",
  "admin/editor.image-list.images.description.title": "Texto alternativo de la imagen",
  "admin/editor.image-list.images.image.title": "Imagen",
  "admin/editor.image-list.images.link.noFollow.title": "Debe ser un enlace nofollow",
  "admin/editor.image-list.images.link.openNewTab.title": "Abrir en una nueva pestaña",
  "admin/editor.image-list.images.link.title.title": "Título del enlace",
  "admin/editor.image-list.images.link.url.title": "URL del enlace de la imagen",
  "admin/editor.image-list.images.mobileImage.title": "Imagen para móvil",
  "admin/editor.image-list.images.title.title": "Título de la imagen",
  "admin/editor.image-list.images.title": "Imágenes",
  "admin/editor.image-list.images.width.description": "Anchura de la imagen para una sola imagen (% o px)",
  "admin/editor.image-list.images.height.title": "Altura de la imagen",
  "admin/editor.image-list.images.height.description": "Altura de la imagen para una única imagen (px)",
  "admin/editor.image-list.images.width.title": "Anchura de la imagen",
  "admin/editor.image-list.title": "Lista de imágenes",
  "admin/editor.image-slider.description": "Control deslizante de imágenes",
  "admin/editor.image-slider.slider.infinite": "Infinito",
  "admin/editor.image-slider.slider.showNavigation": "Mostrar flechas de navegación",
  "admin/editor.image-slider.slider.showPaginationDots": "Mostrar puntos de paginación",
  "admin/editor.image-slider.slider.title": "Opciones del control deslizante",
  "admin/editor.image-slider.slider.usePagination": "Usar paginación",
  "admin/editor.image-slider.title": "Control deslizante de imágenes",
  "admin/editor.image.analytics.none": "No",
  "admin/editor.image.analytics.promotionId": "ID de la promoción",
  "admin/editor.image.analytics.promotionName": "Nombre de la promoción",
  "admin/editor.image.analytics.promotionPosition": "Posición creativa",
  "admin/editor.image.analytics.promotionProductId": "ID del producto",
  "admin/editor.image.analytics.promotionProductName": "Nombre del producto",
  "admin/editor.image.analytics.provide": "Sí",
  "admin/editor.image.analytics.title": "Evento de Analytics",
  "admin/editor.store-image.alt.title": "Texto alternativo",
  "admin/editor.store-image.fetchpriority.auto": "Dejar que el navegador decida la prioridad",
  "admin/editor.store-image.fetchpriority.high": "Prioridad alta",
  "admin/editor.store-image.fetchpriority.low": "Prioridad baja",
  "admin/editor.store-image.fetchpriority.title": "Sugerencia de prioridad de carga",
  "admin/editor.store-image.loading.eager": "Al cargar la página",
  "admin/editor.store-image.loading.lazy": "Al estar cerca de la zona de visualización",
  "admin/editor.store-image.loading.title": "Estrategia de carga",
  "admin/editor.store-image.src.title": "Imagen",
  "admin/editor.store-image.title.description": "Título que se mostrará al pasar el mouse sobre la imagen",
  "admin/editor.store-image.title.title": "Título de la imagen",
  "admin/editor.store-image.title": "Imagen"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/docs/README.md from the store-image VTEX app.

[Assistant]
Here's the implementation:

```markdown
📢 Use this project, [contribute](https://github.com/vtex-apps/store-image) to it or open issues to help evolve it using [Store Discussion](https://github.com/vtex-apps/store-discussion).

# Store Image

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->

[![All Contributors](https://img.shields.io/badge/all_contributors-0-orange.svg?style=flat-square)](#contributors-)

<!-- ALL-CONTRIBUTORS-BADGE:END -->

The Store Image app exports the `list-context.image-list` block, which is responsible for the image content in the store theme.

![store-image](https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/images/vtex-store-image-0.png)

## Configuring the store image

1. Add the `store-image` app to your theme dependencies in the `manifest.json`. For example:

```diff
 "dependencies ": {
+  "vtex.store-image": "0.x"
 }
```

You can now use the `list-context.image-list` block exported by the Store Image app. This block allows you to display images in your store with more composability since you can use it along with other `list-context` blocks to create a more flexible and customizable image slider.

2. In any desired theme template, add the `list-context.image-list` block, declaring the `slider-layout` as a child block. For example:

```json
  "list-context.image-list#demo": {
    "children": ["slider-layout#demo-images"],
    "props": {
      "preload": true,
      "height": 650,
      "images": [
        {
          "loading": "eager",
          "image": "https://storecomponents.vteximg.com.br/arquivos/banner-infocard2.png",
          "description": "something something"
        },
        {
          "loading": "lazy",
          "image": "https://storecomponents.vteximg.com.br/assets/vtex.file-manager-graphql/images/Group%207%20(1)%20(1)%20(1)%20(1)%20(1)___c6b3ed853fb16a08b265753b50e0c57a.png",
          "description": "something something"
        }
      ]
    }
  },

  "slider-layout#demo-images": {
    "props": {
      "itemsPerPage": {
        "desktop": 1,
        "tablet": 1,
        "phone": 1
      },
      "infinite": true
    }
  },
```

Note that the `slider-layout` block exported from the Slider Layout app is a child block of `list-context.image-list`. It defines which images will be displayed and their behavior when rendered.

### `list-context.image-list` props

| Prop name                           | Type      | Description                                                                                | Default value |
| ----------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------- | ------------- |
| `images`                            | `array`   | Array of objects that declares all the images to be rendered.                                                         | `undefined`   |
| `height`                            | `number`  | Image height for all images declared in the `image` object (in `px`).                                                 | `undefined`   |
| `preload`                           | `boolean` | Preloads the first image in a list, prioritizing the image display over other assets.                                 | `false`       |
| `experimentalSetExplicitDimensions` | `boolean` | Sets explicit `width` and/or `height` attributes for an image, if `width` and/or `height` props are provided in `px`. |

### `image-list` props

| Prop name                        | Type      | Description                                                                                | Default value |
| -------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------- | ------------- |
| `images`                         | `array`   | Array of objects that declares all the images to be rendered.                                                         | `undefined`   |
| `height`                         | `number`  | Image height for all images declared in the `image` object (in `px`).                                                 | `undefined`   |
| `experimentalPreventLayoutShift` | `boolean` | Wraps the image in a `<span>` tag with a preset `width` and/or `height` to minimize layout shift during page loading. |

- **`images` array:**

| Prop name              | Type                | Description                                                                                | Default value |
| ---------------------- | ------------------- | --------------------------------------------------------------------------------------------------- | ------------- |
| `image`                | `string`            | Image URL.                                                                                | `undefined`   |
| `mobileImage`          | `string`            | Mobile image URL.                                                                                | `undefined`   |
| `description`          | `string`            | Image description.                                                                                | `undefined`   |
| `link`                 | `object`            | Links a URL to the image being rendered.                                                            | `undefined`   |
| `width`                | `string` / `number` | Image width (in `%` or `px`).                                                                       | `100%`        |
| `loading`              | `string`            | Loading strategy, either when the page loads (`'eager'`) or when closer to the viewport (`'lazy'`). | `'eager'`     |
| `fetchpriority`        | `string`            | The fetch priority hint (`'high'`, `'low'`, or `'auto'`).                                           | `'auto'`      |
| `analyticsProperties`  | `string`            | Whether analytics props should be set (`'provided'`) or not (`'none'`).                             | `'none'`      |
| `promotionId`          | `string`            | The ID of the promotion associated with the event.                                                  | `undefined`   |
| `promotionName`        | `string`            | The name of the promotion associated with the event.                                                | `undefined`   |
| `promotionPosition`    | `string`            | The name of the promotional creative slot associated with the event.                                | `undefined`   |
| `promotionProductId`   | `string`            | The ID of the product associated with the event.                                                    | `undefined`   |
| `promotionProductName` | `string`            | The name of the product associated with the event.                                                  | `undefined`   |

- **`link` object:**

| Prop name    | Type      | Description                                                                                | Default value |
| ------------ | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `url`        | `string`  | URL users will be redirected to when they click the image.                                                                                | `undefined`   |
| `noFollow`   | `boolean` | Whether the page owner endorses the linked URL the user was navigating on, i.e., if there is a business relationship between both pages (`true`) or (`false`). | `false`       |
| `openNewTab` | `string`  | Whether a new tab will be opened on the browser (`true`) or (`false`).                                                                                | `undefined`   |
| `title`      | `string`  | Text label used to identify the image in the Admin Site Editor.                                                                                | `undefined`   |

> ℹ Use the **Admin Site Editor** to manage all images declared in the `list-context.image-list` block.

## Customization

The block does not have CSS handles for specific customization.

All CSS handles available for the Image block are available for the `slider-layout` block. Take a look at the Customization section in the [**Slider Layout documentation**](https://developers.vtex.com/docs/apps/vtex.slider-layout). Note that the `image-slider` uses our `vtex.slider-layout` app, so all the CSS namespaces defined by it are also available for `image-slider`. Learn more in [Slider Layout](https://developers.vtex.com/docs/apps/vtex.slider-layout).

## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind are welcome!

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/react/ImageList.tsx from the store-image VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import type { PropsWithChildren } from 'react'
import { useDevice } from 'vtex.device-detector'
import { ListContextProvider, useListContext } from 'vtex.list-context'

import { IMAGE_LIST_SCHEMA } from './modules/schema'
import { getImagesAsJSXList } from './modules/imageAsList'
import type { ImagesSchema } from './ImageTypes'

export interface ImageListProps {
  images: ImagesSchema
  height?: number | string
  preload?: boolean
  experimentalPreventLayoutShift?: boolean
  experimentalSetExplicitDimensions?: boolean
}

function ImageList({
  images,
  height = 420,
  children,
  preload,
  experimentalPreventLayoutShift,
  experimentalSetExplicitDimensions,
}: PropsWithChildren<ImageListProps>) {
  const list = useListContext()?.list ?? []
  const { isMobile } = useDevice()

  const imageListContent = getImagesAsJSXList(
    images,
    isMobile,
    height,
    preload,
    experimentalPreventLayoutShift,
    experimentalSetExplicitDimensions
  )

  const newListContextValue = list.concat(imageListContent)

  return (
    <ListContextProvider list={newListContextValue}>
      {children}
    </ListContextProvider>
  )
}

ImageList.schema = IMAGE_LIST_SCHEMA

export default ImageList

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/react/ImageTypes.ts from the store-image VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { ImageProps } from './Image'
import type { ImageListProps } from './ImageList'
import type { ImageSliderProps } from './ImageSlider'

export { ImageProps, ImageListProps, ImageSliderProps }

export interface ImageSchema {
  src?: string
  link?: Link
  alt?: string
  title?: string
  analyticsProperties?: 'none' | 'provide'
  promotionId?: string
  promotionName?: string
  promotionPosition?: string
  promotionProductId?: string
  promotionProductName?: string
}

export type ImagesSchema = Array<{
  image: string
  mobileImage: string
  link?: Link
  title?: string
  description: string
  experimentalPreventLayoutShift?: boolean
  experimentalSetExplicitDimensions?: boolean
  loading?: 'eager' | 'lazy'
  width?: number | string
  height?: number | string
  analyticsProperties?: 'none' | 'provide'
  promotionId?: string
  promotionName?: string
  promotionPosition?: string
  promotionProductId?: string
  promotionProductName?: string
}>

interface Link {
  url: string
  attributeNofollow: boolean
  attributeTitle?: string
  /**
   * These two properties need to both exist because
   * there was a mismatch in the API defined by this component,
   * which exposes a openNewTab prop, and the native link type
   * from vtex.native-types, which expects a newTab property
   * instead of openNewTab.
   */
  openNewTab?: boolean
  newTab?: boolean
}

export interface SliderConfig {
  itemsPerPage: {
    desktop: number
    tablet: number
    phone: number
  }
  showNavigationArrows: 'mobileOnly' | 'desktopOnly' | 'always' | 'never'
  showPaginationDots: 'mobileOnly' | 'desktopOnly' | 'always' | 'never'
  usePagination: boolean
  infinite: boolean
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/react/package.json from the store-image VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "scripts": {
    "lint": "tsc --noEmit && eslint --quiet --fix --ext ts,tsx .",
    "test": "vtex-test-tools test"
  },
  "dependencies": {
    "react": "^16.13.1",
    "react-intl": "^4.5.0"
  },
  "devDependencies": {
    "@types/jest": "^25.2.1",
    "@types/react": "^16.9.34",
    "@vtex/test-tools": "^3.1.0",
    "typescript": "3.9.7",
    "vtex.css-handles": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.css-handles@1.0.1/public/@types/vtex.css-handles",
    "vtex.device-detector": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.device-detector@0.2.6/public/@types/vtex.device-detector",
    "vtex.list-context": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.list-context@0.2.0/public/@types/vtex.list-context",
    "vtex.native-types": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.native-types@0.10.1/public/@types/vtex.native-types",
    "vtex.on-view": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.on-view@1.0.0/public/@types/vtex.on-view",
    "vtex.pixel-manager": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.pixel-manager@1.9.0/public/@types/vtex.pixel-manager",
    "vtex.render-runtime": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.render-runtime@8.135.1/public/@types/vtex.render-runtime",
    "vtex.slider-layout": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.slider-layout@0.24.6/public/@types/vtex.slider-layout",
    "vtex.store-image": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.store-image@0.22.3/public/@types/vtex.store-image"
  },
  "version": "0.24.0"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/react/ImageListWithoutContext.tsx from the store-image VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { useDevice } from 'vtex.device-detector'

import { IMAGE_LIST_SCHEMA } from './modules/schema'
import { getImagesAsJSXList } from './modules/imageAsList'
import type { ImageListProps } from './ImageList'

const ImageListWithoutContext = (props: ImageListProps) => {
  const { images, height = '420' } = props
  const { isMobile } = useDevice()

  const imageListContent = getImagesAsJSXList(images, isMobile, height)

  return <React.Fragment>{imageListContent}</React.Fragment>
}

ImageListWithoutContext.schema = IMAGE_LIST_SCHEMA

export default ImageListWithoutContext

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/react/Image.tsx from the store-image VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Fragment, useState, useRef, useEffect } from 'react'
import type { ImgHTMLAttributes, RefObject } from 'react'
import { useOnView } from 'vtex.on-view'
import { useCssHandles } from 'vtex.css-handles'
import type { CssHandlesTypes } from 'vtex.css-handles'
import { useIntl, defineMessages } from 'react-intl'
import { formatIOMessage } from 'vtex.native-types'
import { Link } from 'vtex.render-runtime'
import { usePixel } from 'vtex.pixel-manager'

import type { ImageSchema } from './ImageTypes'

const CSS_HANDLES = ['imageElement', 'imageElementLink'] as const

export interface ImageProps
  extends ImageSchema,
    ImgHTMLAttributes<HTMLImageElement> {
  maxWidth?: string | number
  maxHeight?: string | number
  minWidth?: string | number
  minHeight?: string | number
  blockClass?: string
  experimentalPreventLayoutShift?: boolean
  experimentalSetExplicitDimensions?: boolean
  classes?: CssHandlesTypes.CustomClasses<typeof CSS_HANDLES>
  preload?: boolean
  loading?: 'eager' | 'lazy'
  fetchpriority?: 'high' | 'low' | 'auto'
  width?: string | number
  height?: string | number
  specificHeight?: string | number
  /**
   * Warning: This property is for internal usage, please avoid using it.
   * This property is used when the Image is children of the SliderTrack component and it prevents triggering the promoView event twice for cloned images.
   * https://github.com/vtex-apps/slider-layout/blob/master/react/components/SliderTrack.tsx
   */
  __isDuplicated?: boolean
}

const useImageLoad = (
  imageRef: RefObject<HTMLImageElement | null>,
  { bailOut = false } = {}
) => {
  const [isLoaded, setLoaded] = useState(false)

  useEffect(() => {
    if (bailOut) {
      return
    }

    const imageElement = imageRef.current

    if (!imageElement) {
      return
    }

    if (imageElement.complete) {
      setLoaded(true)

      return
    }

    const handleLoad = () => {
      setLoaded(true)
    }

    imageElement.addEventListener('load', handleLoad)

    return () => {
      imageElement.removeEventListener('load', handleLoad)
    }
  }, [imageRef, bailOut])

  return isLoaded
}

function Image(props: ImageProps) {
  const {
    src,
    alt = '',
    maxWidth,
    maxHeight,
    minWidth,
    minHeight,
    width,
    height: genericHeight,
    specificHeight,
    srcSet = '',
    sizes = '',
    link,
    title,
    experimentalPreventLayoutShift,
    experimentalSetExplicitDimensions,
    analyticsProperties = 'none',
    promotionId,
    promotionName,
    promotionPosition,
    promotionProductId,
    promotionProductName,
    classes,
    preload,
    loading = 'eager',
    fetchpriority = 'auto',
    // eslint-disable-next-line
    __isDuplicated,
  } = props

  const imageRef = useRef<HTMLImageElement | null>(null)
  const isLoaded = useImageLoad(imageRef, {
    bailOut: !experimentalPreventLayoutShift,
  })

  const intl = useIntl()
  const { handles } = useCssHandles(CSS_HANDLES, {
    migrationFrom: 'vtex.store-components@3.x',
    classes,
  })

  const imageDimensionsWithoutExplicitDimensions = {
    minWidth,
    minHeight,
    maxWidth,
    maxHeight,
  }

  const imageDimensionsWithExplicitDimensions = {
    ...imageDimensionsWithoutExplicitDimensions,
    height: genericHeight,
    width,
  }

  const placeholderSize =
    specificHeight ?? genericHeight ?? maxHeight ?? minHeight ?? 'auto'

  const allowedExplicitDimensionsRegex = /(auto|inherit|initial|unset)|[^\d]/g

  const explicitDimensions = (dimension: string | number | undefined) =>
    dimension !== '' && dimension
      ? dimension.toString().replace(allowedExplicitDimensionsRegex, '$1')
      : null

  const widthWithoutUnits = explicitDimensions(width)

  const heightWithoutUnits =
    explicitDimensions(specificHeight) ??
    explicitDimensions(genericHeight) ??
    explicitDimensions(maxHeight)

  const hasPercentage = (dimension: string | number | undefined) =>
    dimension?.toString().includes('%')

  const explicitDimensionsAreAvailable =
    !!width &&
    (!!specificHeight || !!maxHeight || !!genericHeight) &&
    !hasPercentage(width) &&
    (!hasPercentage(specificHeight) ||
      !hasPercentage(maxHeight) ||
      !hasPercentage(genericHeight))

  const formattedSrc = formatIOMessage({ id: src, intl })
  const formattedAlt = formatIOMessage({ id: alt, intl })

  const imgElement = (
    <img
      title={title}
      sizes={sizes}
      srcSet={srcSet}
      src={typeof formattedSrc === 'string' ? formattedSrc : ''}
      alt={typeof formattedAlt === 'string' ? formattedAlt : ''}
      ref={imageRef}
      className={handles.imageElement}
      loading={loading}
      fetchpriority={fetchpriority}
      {...(experimentalSetExplicitDimensions && explicitDimensionsAreAvailable
        ? {
            width: widthWithoutUnits ?? width ?? 'auto',
            height: heightWithoutUnits ?? 'auto',
            style: imageDimensionsWithoutExplicitDimensions,
          }
        : { style: imageDimensionsWithExplicitDimensions })}
      {...(preload
        ? {
            'data-vtex-preload': 'true',
          }
        : {})}
    />
  )

  /**
   * To understand why we need to check for both newTab and openNewTab
   * properties, check the Image type definition at './typings/image.d.ts'.
   */
  const shouldOpenLinkInNewTab = link?.newTab ?? link?.openNewTab

  const { push } = usePixel()

  const promotionEventData =
    analyticsProperties === 'provide'
      ? {
          id: promotionId,
          name: promotionName,
          creative: formattedSrc,
          position: promotionPosition,
          products: [
            {
              productId: promotionProductId,
              productName: promotionProductName,
            },
          ],
        }
      : undefined

  const formattedLink = formatIOMessage({ id: link?.url, intl })
  const formattedTitle = formatIOMessage({ id: link?.attributeTitle, intl })

  const maybeLink = link?.url ? (
    // The onClick function and the <Link> component are necessary,
    // knowing this, it seems good to disable the anchor-is-valid rule.
    // eslint-disable-next-line jsx-a11y/anchor-is-valid
    <Link
      to={typeof formattedLink === 'string' ? formattedLink : ''}
      title={typeof formattedTitle === 'string' ? formattedTitle : ''}
      rel={link.attributeNofollow ? 'nofollow' : ''}
      target={shouldOpenLinkInNewTab ? '_blank' : undefined}
      className={handles.imageElementLink}
      onClick={() => {
        if (analyticsProperties === 'none') return

        push({ event: 'promotionClick', promotions: [promotionEventData] })
      }}
    >
      {imgElement}
    </Link>
  ) : (
    <Fragment>{imgElement}</Fragment>
  )

  useOnView({
    ref: imageRef,
    onView: () => {
      if (analyticsProperties === 'none' || __isDuplicated) return

      push({
        event: 'promoView',
        promotions: [promotionEventData],
      })
    },
    once: true,
  })

  return experimentalPreventLayoutShift ? (
    <span
      className="dib"
      style={{
        height: isLoaded ? 'auto' : placeholderSize,
      }}
    >
      {maybeLink}
    </span>
  ) : (
    maybeLink
  )
}

const messages = defineMessages({
  title: {
    id: 'admin/editor.store-image.title',
  },
})

Image.schema = {
  title: messages.title.id,
}

Image.cssHandles = CSS_HANDLES

export default Image

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/react/ImageSlider.tsx from the store-image VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { defineMessages, useIntl } from 'react-intl'
import { SliderLayout } from 'vtex.slider-layout'
import { useDevice } from 'vtex.device-detector'
import { formatIOMessage } from 'vtex.native-types'

import Image from './Image'
import type { SliderConfig, ImagesSchema } from './ImageTypes'

export interface ImageSliderProps {
  images: ImagesSchema
  height: number
  sliderLayoutConfig: SliderConfig
  preload?: boolean
}

function getImageUrl(isMobile: boolean, image: string, mobileImage: string) {
  return !!mobileImage && isMobile ? mobileImage : image
}

function ImageSlider(props: ImageSliderProps) {
  const {
    images,
    height,
    sliderLayoutConfig = {
      itemsPerPage: {
        desktop: 1,
        tablet: 1,
        phone: 1,
      },
      infinite: true,
      showNavigationArrows: 'always',
      showPaginationDots: 'always',
      usePagination: true,
    },
    preload,
  } = props

  const { isMobile } = useDevice()
  const intl = useIntl()

  return (
    <SliderLayout {...sliderLayoutConfig} totalItems={images.length}>
      {images.map(
        ({ image, mobileImage, link, description, ...otherProps }, idx) => {
          const formattedImage = formatIOMessage({ id: image, intl })
          const formattedMobileImage = formatIOMessage({
            id: mobileImage,
            intl,
          })

          const imageUrl = getImageUrl(
            isMobile,
            typeof formattedImage === 'string' ? formattedImage : '',
            typeof formattedMobileImage === 'string' ? formattedMobileImage : ''
          )

          const formattedAltDescription = formatIOMessage({
            id: description,
            intl,
          })

          const formattedUrl = link
            ? formatIOMessage({ id: link.url, intl })
            : ''

          const formattedTitle = link
            ? formatIOMessage({
                id: link.attributeTitle,
                intl,
              })
            : ''

          const imageLink = link && {
            ...link,
            url: typeof formattedUrl === 'string' ? formattedUrl : '',
            title: typeof formattedTitle === 'string' ? formattedTitle : '',
          }

          return (
            <Image
              key={idx}
              src={imageUrl}
              alt={
                typeof formattedAltDescription === 'string'
                  ? formattedAltDescription
                  : ''
              }
              link={imageLink}
              maxHeight={height}
              width="100%"
              preload={preload && idx === 0}
              {...otherProps}
            />
          )
        }
      )}
    </SliderLayout>
  )
}

const messages = defineMessages({
  title: { id: 'admin/editor.image-slider.title', defaultMessage: '' },
  description: {
    id: 'admin/editor.image-slider.description',
    defaultMessage: '',
  },
  imagesImageTitle: {
    id: 'admin/editor.image-list.images.image.title',
    defaultMessage: '',
  },
  imagesMobileImageTitle: {
    id: 'admin/editor.image-list.images.mobileImage.title',
    defaultMessage: '',
  },
  imagesImageDescription: {
    id: 'admin/editor.image-list.images.description.title',
    defaultMessage: '',
  },
  imagesImageAttributeTitle: {
    id: 'admin/editor.image-list.images.title.title',
    defaultMessage: '',
  },
  imagesImageLinkUrl: {
    id: 'admin/editor.image-list.images.link.url.title',
    defaultMessage: '',
  },
  imagesImageLinkOpenNewTab: {
    id: 'admin/editor.image-list.images.link.openNewTab.title',
    defaultMessage: '',
  },
  imagesImageLinkNoFollow: {
    id: 'admin/editor.image-list.images.link.noFollow.title',
    defaultMessage: '',
  },
  imagesImageLinkTitle: {
    id: 'admin/editor.image-list.images.link.title.title',
    defaultMessage: '',
  },
  imagesTitle: {
    id: 'admin/editor.image-list.images.title',
    defaultMessage: '',
  },
  heightTitle: {
    id: 'admin/editor.image-list.height.title',
    defaultMessage: '',
  },
  sliderTitle: {
    id: 'admin/editor.image-slider.slider.title',
    defaultMessage: '',
  },
  sliderInfinite: {
    id: 'admin/editor.image-slider.slider.infinite',
    defaultMessage: '',
  },
  sliderShowNavigation: {
    id: 'admin/editor.image-slider.slider.showNavigation',
    defaultMessage: '',
  },
  sliderShowPaginationDots: {
    id: 'admin/editor.image-slider.slider.showPaginationDots',
    defaultMessage: '',
  },
  sliderUsePagination: {
    id: 'admin/editor.image-slider.slider.usePagination',
    defaultMessage: '',
  },
})

ImageSlider.schema = {
  title: messages.title.id,
  description: messages.description.id,
  type: 'object',
  properties: {
    height: {
      default: 420,
      enum: [420, 440],
      isLayout: true,
      title: messages.heightTitle.id,
      type: 'number',
    },
    sliderLayoutConfig: {
      title: messages.sliderTitle.id,
      properties: {
        infinite: {
          default: true,
          title: messages.sliderInfinite.id,
          type: 'boolean',
        },
        showNavigationArrows: {
          default: 'always',
          enum: ['mobileOnly', 'desktopOnly', 'always', 'never'],
          title: messages.sliderShowNavigation.id,
          type: 'string',
        },
        showPaginationDots: {
          default: 'always',
          enum: ['mobileOnly', 'desktopOnly', 'always', 'never'],
          title: messages.sliderShowPaginationDots.id,
          type: 'string',
        },
        usePagination: {
          default: true,
          title: messages.sliderUsePagination.id,
          type: 'boolean',
        },
      },
      type: 'object',
    },
  },
}

export default ImageSlider

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/store/contentSchemas.json from the store-image VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "definitions": {
    "Image": {
      "title": "admin/editor.store-image.title",
      "properties": {
        "src": {
          "title": "admin/editor.image.src.title",
          "$ref": "app:vtex.native-types#/definitions/url",
          "default": "",
          "widget": {
            "ui:widget": "image-uploader"
          }
        },
        "link": {
          "$ref": "app:vtex.native-types#/definitions/link",
          "default": ""
        },
        "alt": {
          "title": "admin/editor.image.alt.title",
          "$ref": "app:vtex.native-types#/definitions/text",
          "default": ""
        },
        "title": {
          "title": "admin/editor.image.title.title",
          "description": "admin/editor.image.title.description",
          "$ref": "app:vtex.native-types#/definitions/text",
          "default": ""
        },
        "loading": {
          "title": "admin/editor.store-image.loading.title",
          "enum": ["eager", "lazy"],
          "enumNames": [
            "admin/editor.store-image.loading.eager",
            "admin/editor.store-image.loading.lazy"
          ],
          "widget": {
            "ui:widget": "radio"
          },
          "default": "eager"
        },
        "fetchpriority": {
          "title": "admin/editor.store-image.fetchpriority.title",
          "enum": ["high", "low", "auto"],
          "enumNames": [
            "admin/editor.store-image.fetchpriority.high",
            "admin/editor.store-image.fetchpriority.low",
            "admin/editor.store-image.fetchpriority.auto"
          ],
          "widget": {
            "ui:widget": "radio"
          },
          "default": "auto"
        },
        "analyticsProperties": {
          "title": "admin/editor.image.analytics.title",
          "description": "admin/editor.image.analytics.description",
          "enum": ["none", "provide"],
          "enumNames": [
            "admin/editor.image.analytics.none",
            "admin/editor.image.analytics.provide"
          ],
          "widget": {
            "ui:widget": "radio"
          },
          "default": "none"
        }
      },
      "dependencies": {
        "analyticsProperties": {
          "oneOf": [
            {
              "properties": {
                "analyticsProperties": {
                  "enum": ["provide"]
                },
                "promotionId": {
                  "title": "admin/editor.image.analytics.promotionId",
                  "type": "string",
                  "default": ""
                },
                "promotionName": {
                  "title": "admin/editor.image.analytics.promotionName",
                  "type": "string",
                  "default": ""
                },
                "promotionPosition": {
                  "title": "admin/editor.image.analytics.promotionPosition",
                  "type": "string",
                  "default": ""
                },
                "promotionProductId": {
                  "title": "admin/editor.image.analytics.promotionProductId",
                  "type": "string",
                  "default": ""
                },
                "promotionProductName": {
                  "title": "admin/editor.image.analytics.promotionProductName",
                  "type": "string",
                  "default": ""
                }
              }
            },
            {
              "properties": {
                "analyticsProperties": {
                  "enum": ["none"]
                }
              }
            }
          ]
        }
      }
    },
    "Images": {
      "type": "array",
      "title": "admin/editor.image-list.images.title",
      "items": {
        "properties": {
          "image": {
            "$ref": "app:vtex.native-types#/definitions/url",
            "default": "",
            "title": "admin/editor.image-list.images.image.title",
            "widget": {
              "ui:widget": "image-uploader"
            }
          },
          "mobileImage": {
            "$ref": "app:vtex.native-types#/definitions/url",
            "default": "",
            "title": "admin/editor.image-list.images.mobileImage.title",
            "widget": {
              "ui:widget": "image-uploader"
            }
          },
          "description": {
            "$ref": "app:vtex.native-types#/definitions/text",
            "default": "",
            "title": "admin/editor.image-list.images.description.title"
          },
          "title": {
            "title": "admin/editor.image-list.images.title.title",
            "$ref": "app:vtex.native-types#/definitions/text",
            "default": ""
          },
          "link": {
            "default": "",
            "title": "",
            "$ref": "app:vtex.native-types#/definitions/link"
          },
          "width": {
            "title": "admin/editor.image-list.images.width.title",
            "description": "admin/editor.image-list.images.width.description",
            "$ref": "app:vtex.native-types#/definitions/text",
            "default": "100%"
          },
          "height": {
            "title": "admin/editor.image-list.images.height.title",
            "description": "admin/editor.image-list.images.height.description",
            "$ref": "app:vtex.native-types#/definitions/text",
            "default": ""
          },
          "loading": {
            "title": "admin/editor.store-image.loading.title",
            "enum": ["eager", "lazy"],
            "enumNames": [
              "admin/editor.store-image.loading.eager",
              "admin/editor.store-image.loading.lazy"
            ],
            "widget": {
              "ui:widget": "radio"
            },
            "default": "eager"
          },
          "fetchpriority": {
            "title": "admin/editor.store-image.fetchpriority.title",
            "enum": ["high", "low", "auto"],
            "enumNames": [
              "admin/editor.store-image.fetchpriority.high",
              "admin/editor.store-image.fetchpriority.low",
              "admin/editor.store-image.fetchpriority.auto"
            ],
            "widget": {
              "ui:widget": "radio"
            },
            "default": "auto"
          },
          "analyticsProperties": {
            "title": "admin/editor.image.analytics.title",
            "description": "admin/editor.image.analytics.description",
            "enum": ["none", "provide"],
            "enumNames": [
              "admin/editor.image.analytics.none",
              "admin/editor.image.analytics.provide"
            ],
            "widget": {
              "ui:widget": "radio"
            },
            "default": "none"
          }
        },
        "dependencies": {
          "analyticsProperties": {
            "oneOf": [
              {
                "properties": {
                  "analyticsProperties": {
                    "enum": ["provide"]
                  },
                  "promotionId": {
                    "title": "admin/editor.image.analytics.promotionId",
                    "type": "string",
                    "default": ""
                  },
                  "promotionName": {
                    "title": "admin/editor.image.analytics.promotionName",
                    "type": "string",
                    "default": ""
                  },
                  "promotionPosition": {
                    "title": "admin/editor.image.analytics.promotionPosition",
                    "type": "string",
                    "default": ""
                  },
                  "promotionProductId": {
                    "title": "admin/editor.image.analytics.promotionProductId",
                    "type": "string",
                    "default": ""
                  },
                  "promotionProductName": {
                    "title": "admin/editor.image.analytics.promotionProductName",
                    "type": "string",
                    "default": ""
                  }
                }
              },
              {
                "properties": {
                  "analyticsProperties": {
                    "enum": ["none"]
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/store/interfaces.json from the store-image VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "image-new": {
    "component": "Image",
    "content": {
      "$ref": "app:vtex.store-image#/definitions/Image"
    }
  },
  "image-slider": {
    "component": "ImageSlider",
    "content": {
      "properties": {
        "images": {
          "$ref": "app:vtex.store-image#/definitions/Images"
        }
      }
    }
  },
  "image-list": {
    "component": "ImageListWithoutContext",
    "content": {
      "properties": {
        "images": {
          "$ref": "app:vtex.store-image#/definitions/Images"
        }
      }
    }
  },
  "list-context.image-list": {
    "component": "ImageList",
    "composition": "children",
    "allowed": "*",
    "content": {
      "properties": {
        "images": {
          "$ref": "app:vtex.store-image#/definitions/Images"
        }
      }
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/react/typings/css.d.ts from the store-image VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.css' {
  const css: CSSHandles
  export default css
}

interface CSSHandles {
  imageElement: string
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/react/typings/image.d.ts from the store-image VTEX app.

[Assistant]
Here's the implementation:

```typescript
import React from 'react'

declare module 'react' {
  interface ImgHTMLAttributes<T> extends HTMLAttributes<T> {
    fetchpriority?: 'high' | 'low' | 'auto'
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/react/__tests__/index.test.tsx from the store-image VTEX app.

[Assistant]
Here's the implementation:

```tsx
describe('Orders List Scenarios', () => {
  it('should work', () => {
    expect(1).toBe(1)
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/react/modules/schema.ts from the store-image VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { defineMessages } from 'react-intl'

const IMAGE_LIST_MESSAGES = defineMessages({
  title: { id: 'admin/editor.image-list.title' },
  description: {
    id: 'admin/editor.image-list.description',
  },
  imagesImageTitle: {
    id: 'admin/editor.image-list.images.image.title',
  },
  imagesMobileImageTitle: {
    id: 'admin/editor.image-list.images.mobileImage.title',
  },
  imagesImageDescription: {
    id: 'admin/editor.image-list.images.description.title',
  },
  imagesImageAttributeTitle: {
    id: 'admin/editor.image-list.images.title.title',
  },
  imagesImageLinkUrl: {
    id: 'admin/editor.image-list.images.link.url.title',
  },
  imagesImageLinkOpenNewTab: {
    id: 'admin/editor.image-list.images.link.openNewTab.title',
  },
  imagesImageLinkNoFollow: {
    id: 'admin/editor.image-list.images.link.noFollow.title',
  },
  imagesImageLinkTitle: {
    id: 'admin/editor.image-list.images.link.title.title',
  },
  imagesTitle: {
    id: 'admin/editor.image-list.images.title',
  },
  heightTitle: {
    id: 'admin/editor.image-list.height.title',
  },
  widthTitle: {
    id: 'admin/editor.image-list.images.width.title',
  },
  widthDescription: {
    id: 'admin/editor.image-list.images.width.description',
  },
  analyticsTitle: {
    id: 'admin/editor.image.analytics.title',
  },
  analyticsNone: {
    id: 'admin/editor.image.analytics.none',
  },
  analyticsProvide: {
    id: 'admin/editor.image.analytics.provide',
  },
  analyticsPromotionId: {
    id: 'admin/editor.image.analytics.promotionId',
  },
  analyticsPromotionName: {
    id: 'admin/editor.image.analytics.promotionName',
  },
  analyticsPromotionPosition: {
    id: 'admin/editor.image.analytics.promotionPosition',
  },
  analyticspromotionProductId: {
    id: 'admin/editor.image.analytics.promotionProductId',
  },
  analyticspromotionProductName: {
    id: 'admin/editor.image.analytics.promotionProductName',
  },
})

export const IMAGE_LIST_SCHEMA = {
  title: IMAGE_LIST_MESSAGES.title.id,
  description: IMAGE_LIST_MESSAGES.description.id,
  type: 'object',
  properties: {
    height: {
      default: '420',
      isLayout: false,
      title: IMAGE_LIST_MESSAGES.heightTitle.id,
      type: 'string',
    },
  },
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-image/react/modules/imageAsList.tsx from the store-image VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'

import Image from '../Image'
import type { ImagesSchema } from '../ImageTypes'

export const getImagesAsJSXList = (
  images: ImagesSchema,
  isMobile: boolean,
  height: number | string,
  preload?: boolean,
  experimentalPreventLayoutShift?: boolean,
  experimentalSetExplicitDimensions?: boolean
  // eslint-disable-next-line max-params
) => {
  return images.map(
    (
      {
        image,
        mobileImage,
        description,
        experimentalPreventLayoutShift: experimentalPreventLayoutShiftChild,
        experimentalSetExplicitDimensions: experimentalSetExplicitDimensionsChild,
        width = '100%',
        height: specificHeight,
        ...props
      },
      idx
    ) => (
      <Image
        key={idx}
        src={isMobile && mobileImage ? mobileImage : image}
        alt={description}
        maxHeight={height}
        width={width}
        specificHeight={specificHeight}
        experimentalPreventLayoutShift={
          experimentalPreventLayoutShift ?? experimentalPreventLayoutShiftChild
        }
        experimentalSetExplicitDimensions={
          experimentalSetExplicitDimensions ??
          experimentalSetExplicitDimensionsChild
        }
        preload={preload && idx === 0}
        {...props}
      />
    )
  )
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of logrocket/docs/README.md from the logrocket VTEX app.

[Assistant]
Here's the implementation:

```markdown
# LogRocket

VTEX LogRocket first-party app

## How to install

Open a terminal and type:

```sh
vtex install vtex.logrocket@1.x
```

Open your admin in the Apps section:

https://YOURSTORENAME.myvtex.com/admin/apps/vtex.logrocket@1.0.0/setup

Fill in your LogRocket's Account ID and click save.

### Setup in Cart and Checkout page

**This step will not be needed in a couple of months!**

Open your admin in the Checkout section in the `checkout6-custom.js`:

https://ACCOUNT.myvtexdev.com/admin/portal/#/sites/default/code/files/checkout6-custom.js

Add the following snippet in the file:

```js
// LogRocket
(function() {
  var accountId = 'YOURACCOUNTID';
  var b=document.createElement("script");b.onload=function(){window.LogRocket && window.LogRocket.init(accountId);};b.type="text/javascript";b.crossOrigin="anonymous";b.src="https://cdn.lr-ingest.io/LogRocket.min.js";a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(b,a);
})();
```

Click Save.

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of minicart-freeshipping-bar/messages/pt.json from the minicart-freeshipping-bar VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/minicartbar.text0": "Temos frete grátis de:",
  "store/minicartbar.text1": "Complete seu pedido para ter",
  "store/minicartbar.text2": "Frete GRÁTIS 24h",
  "store/minicartbar.text3": "Só faltam",
  "store/minicartbar.text4": "Você ganhou frete grátis!"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of minicart-freeshipping-bar/messages/en.json from the minicart-freeshipping-bar VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/minicartbar.text0": "We have free shipping from: ",
  "store/minicartbar.text1": "Complete your order to have",
  "store/minicartbar.text2": "FREE shipping",
  "store/minicartbar.text3": "Only left",
  "store/minicartbar.text4": "You won free shipping"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of minicart-freeshipping-bar/messages/it.json from the minicart-freeshipping-bar VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/minicartbar.text0": "SPEDIZIONE GRATUITA per ordini sopra: ",
  "store/minicartbar.text1": "Completa il tuo ordine per usufruire della",
  "store/minicartbar.text2": "SPEDIZIONE GRATUITA",
  "store/minicartbar.text3": "Per usufruire della SPEDIZIONE GRATUITA mancano solo: ",
  "store/minicartbar.text4": "Hai diritto alla SPEDIZIONE GRATUITA!"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of minicart-freeshipping-bar/messages/ro.json from the minicart-freeshipping-bar VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/minicartbar.text0": "Avem livrare gratuită la: ",
  "store/minicartbar.text1": "Completați comanda dvs. pentru ",
  "store/minicartbar.text2": "Livrare GRATUITĂ",
  "store/minicartbar.text3": "Au rămas doar",
  "store/minicartbar.text4": "Ai câștigat livrare gratuită"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of minicart-freeshipping-bar/messages/context.json from the minicart-freeshipping-bar VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/minicartbar.text0": "minicartbar.text0",
  "store/minicartbar.text1": "minicartbar.text1",
  "store/minicartbar.text2": "minicartbar.text2",
  "store/minicartbar.text3": "minicartbar.text3",
  "store/minicartbar.text4": "minicartbar.text4"
}

```