2026-03-31 05:00:33 +07:00
|
|
|
/**
|
|
|
|
|
* ExampleLoaderPage — loads an example by ID from the URL and redirects to the editor.
|
|
|
|
|
*
|
|
|
|
|
* Route: /examples/:exampleId
|
|
|
|
|
* Example: /examples/blink-led
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import React, { useEffect, useState } from 'react';
|
|
|
|
|
import { useParams, useNavigate, Link } from 'react-router-dom';
|
feat(i18n): translate small editor remates + admin internals (Blocks 11+12)
Block 11 — small editor surfaces
- PinPickerDialog: close, filter pins, no-match, rotate / delete
action buttons.
- RaspberryPiWorkspace: connection status (Connected / Starting…
/ Offline), Start Pi button + tooltip, Connect / Disconnect
buttons + tooltips, Terminal tab label, file-tab close, the
full offline overlay (title / subtitle / start CTA / two-line
note about the staging area), terminal-loading + no-file-
selected fallbacks.
- GitHubStarBanner: aria-label, title, body copy, Star CTA,
dismiss button.
- ExampleLoaderPage: "Loading example…" status, "Example {{id}}
not found." 404 line, "Browse all examples" recovery link.
/editor and /examples links wrapped in localize().
Block 12 — admin-only internals (only admins ever see these)
- AdminBoardsTab: section headings ("By board family" / "By
exact FQBN"), full table column headers (Family / FQBN /
Compiles / Errors / Success rate / Runs / Distinct users /
Distinct projects), range selector label, no-data fallback,
load-failed error.
- AdminDashboardTab: 8 KPI cards (Total users / Total projects
/ Compiles / Runs / DAU / WAU / MAU / Public-Private), all
chart titles + subtitles (Activity over time, Compiles by
board family, Board diversity for pricing signal, Top FQBNs,
Top countries with Cloudflare disclaimer, Top users / Top
projects), table column headers, no-data fallbacks, load
errors. Pluralised "{{count}} board(s)" via i18next plurals
in the diversity pie chart.
- UserActivityModal: title with username interpolation, subtitle,
range selector label, table column headers (Date / Project /
Compiles / Errors / Runs / Saves), pluralised
"{{count}} project(s)" line, deleted-project / no-project
placeholder strings, no-activity empty state, load-failed.
All 8 non-English locales auto-translated via the
`scripts/translate-i18n.mjs` DeepSeek pipeline (one --force run,
~7 min). sameShape() validation passed on every output.
2026-05-10 02:22:16 +07:00
|
|
|
import { useTranslation } from 'react-i18next';
|
2026-03-31 05:00:33 +07:00
|
|
|
import { exampleProjects } from '../data/examples';
|
|
|
|
|
import { loadExample, type LibraryInstallProgress } from '../utils/loadExample';
|
|
|
|
|
import { AppHeader } from '../components/layout/AppHeader';
|
feat(i18n): translate small editor remates + admin internals (Blocks 11+12)
Block 11 — small editor surfaces
- PinPickerDialog: close, filter pins, no-match, rotate / delete
action buttons.
- RaspberryPiWorkspace: connection status (Connected / Starting…
/ Offline), Start Pi button + tooltip, Connect / Disconnect
buttons + tooltips, Terminal tab label, file-tab close, the
full offline overlay (title / subtitle / start CTA / two-line
note about the staging area), terminal-loading + no-file-
selected fallbacks.
- GitHubStarBanner: aria-label, title, body copy, Star CTA,
dismiss button.
- ExampleLoaderPage: "Loading example…" status, "Example {{id}}
not found." 404 line, "Browse all examples" recovery link.
/editor and /examples links wrapped in localize().
Block 12 — admin-only internals (only admins ever see these)
- AdminBoardsTab: section headings ("By board family" / "By
exact FQBN"), full table column headers (Family / FQBN /
Compiles / Errors / Success rate / Runs / Distinct users /
Distinct projects), range selector label, no-data fallback,
load-failed error.
- AdminDashboardTab: 8 KPI cards (Total users / Total projects
/ Compiles / Runs / DAU / WAU / MAU / Public-Private), all
chart titles + subtitles (Activity over time, Compiles by
board family, Board diversity for pricing signal, Top FQBNs,
Top countries with Cloudflare disclaimer, Top users / Top
projects), table column headers, no-data fallbacks, load
errors. Pluralised "{{count}} board(s)" via i18next plurals
in the diversity pie chart.
- UserActivityModal: title with username interpolation, subtitle,
range selector label, table column headers (Date / Project /
Compiles / Errors / Runs / Saves), pluralised
"{{count}} project(s)" line, deleted-project / no-project
placeholder strings, no-activity empty state, load-failed.
All 8 non-English locales auto-translated via the
`scripts/translate-i18n.mjs` DeepSeek pipeline (one --force run,
~7 min). sameShape() validation passed on every output.
2026-05-10 02:22:16 +07:00
|
|
|
import { useLocalizedHref } from '../i18n/useLocalizedNavigate';
|
2026-03-31 05:00:33 +07:00
|
|
|
|
|
|
|
|
export const ExampleLoaderPage: React.FC = () => {
|
feat(i18n): translate small editor remates + admin internals (Blocks 11+12)
Block 11 — small editor surfaces
- PinPickerDialog: close, filter pins, no-match, rotate / delete
action buttons.
- RaspberryPiWorkspace: connection status (Connected / Starting…
/ Offline), Start Pi button + tooltip, Connect / Disconnect
buttons + tooltips, Terminal tab label, file-tab close, the
full offline overlay (title / subtitle / start CTA / two-line
note about the staging area), terminal-loading + no-file-
selected fallbacks.
- GitHubStarBanner: aria-label, title, body copy, Star CTA,
dismiss button.
- ExampleLoaderPage: "Loading example…" status, "Example {{id}}
not found." 404 line, "Browse all examples" recovery link.
/editor and /examples links wrapped in localize().
Block 12 — admin-only internals (only admins ever see these)
- AdminBoardsTab: section headings ("By board family" / "By
exact FQBN"), full table column headers (Family / FQBN /
Compiles / Errors / Success rate / Runs / Distinct users /
Distinct projects), range selector label, no-data fallback,
load-failed error.
- AdminDashboardTab: 8 KPI cards (Total users / Total projects
/ Compiles / Runs / DAU / WAU / MAU / Public-Private), all
chart titles + subtitles (Activity over time, Compiles by
board family, Board diversity for pricing signal, Top FQBNs,
Top countries with Cloudflare disclaimer, Top users / Top
projects), table column headers, no-data fallbacks, load
errors. Pluralised "{{count}} board(s)" via i18next plurals
in the diversity pie chart.
- UserActivityModal: title with username interpolation, subtitle,
range selector label, table column headers (Date / Project /
Compiles / Errors / Runs / Saves), pluralised
"{{count}} project(s)" line, deleted-project / no-project
placeholder strings, no-activity empty state, load-failed.
All 8 non-English locales auto-translated via the
`scripts/translate-i18n.mjs` DeepSeek pipeline (one --force run,
~7 min). sameShape() validation passed on every output.
2026-05-10 02:22:16 +07:00
|
|
|
const { t } = useTranslation();
|
|
|
|
|
const localize = useLocalizedHref();
|
2026-03-31 05:00:33 +07:00
|
|
|
const { exampleId } = useParams<{ exampleId: string }>();
|
|
|
|
|
const navigate = useNavigate();
|
|
|
|
|
const [error, setError] = useState(false);
|
|
|
|
|
const [installing, setInstalling] = useState<LibraryInstallProgress | null>(null);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
2026-04-22 02:45:45 +07:00
|
|
|
if (!exampleId) {
|
|
|
|
|
setError(true);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-03-31 05:00:33 +07:00
|
|
|
|
|
|
|
|
const example = exampleProjects.find((e) => e.id === exampleId);
|
2026-04-22 02:45:45 +07:00
|
|
|
if (!example) {
|
|
|
|
|
setError(true);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-03-31 05:00:33 +07:00
|
|
|
|
|
|
|
|
let cancelled = false;
|
|
|
|
|
(async () => {
|
|
|
|
|
await loadExample(example, setInstalling);
|
feat(i18n): translate small editor remates + admin internals (Blocks 11+12)
Block 11 — small editor surfaces
- PinPickerDialog: close, filter pins, no-match, rotate / delete
action buttons.
- RaspberryPiWorkspace: connection status (Connected / Starting…
/ Offline), Start Pi button + tooltip, Connect / Disconnect
buttons + tooltips, Terminal tab label, file-tab close, the
full offline overlay (title / subtitle / start CTA / two-line
note about the staging area), terminal-loading + no-file-
selected fallbacks.
- GitHubStarBanner: aria-label, title, body copy, Star CTA,
dismiss button.
- ExampleLoaderPage: "Loading example…" status, "Example {{id}}
not found." 404 line, "Browse all examples" recovery link.
/editor and /examples links wrapped in localize().
Block 12 — admin-only internals (only admins ever see these)
- AdminBoardsTab: section headings ("By board family" / "By
exact FQBN"), full table column headers (Family / FQBN /
Compiles / Errors / Success rate / Runs / Distinct users /
Distinct projects), range selector label, no-data fallback,
load-failed error.
- AdminDashboardTab: 8 KPI cards (Total users / Total projects
/ Compiles / Runs / DAU / WAU / MAU / Public-Private), all
chart titles + subtitles (Activity over time, Compiles by
board family, Board diversity for pricing signal, Top FQBNs,
Top countries with Cloudflare disclaimer, Top users / Top
projects), table column headers, no-data fallbacks, load
errors. Pluralised "{{count}} board(s)" via i18next plurals
in the diversity pie chart.
- UserActivityModal: title with username interpolation, subtitle,
range selector label, table column headers (Date / Project /
Compiles / Errors / Runs / Saves), pluralised
"{{count}} project(s)" line, deleted-project / no-project
placeholder strings, no-activity empty state, load-failed.
All 8 non-English locales auto-translated via the
`scripts/translate-i18n.mjs` DeepSeek pipeline (one --force run,
~7 min). sameShape() validation passed on every output.
2026-05-10 02:22:16 +07:00
|
|
|
if (!cancelled) navigate(localize('/editor'), { replace: true });
|
2026-03-31 05:00:33 +07:00
|
|
|
})();
|
|
|
|
|
|
2026-04-22 02:45:45 +07:00
|
|
|
return () => {
|
|
|
|
|
cancelled = true;
|
|
|
|
|
};
|
2026-03-31 05:00:33 +07:00
|
|
|
}, [exampleId, navigate]);
|
|
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
|
return (
|
2026-04-22 02:45:45 +07:00
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
display: 'flex',
|
|
|
|
|
flexDirection: 'column',
|
|
|
|
|
minHeight: '100vh',
|
|
|
|
|
background: '#1e1e1e',
|
|
|
|
|
}}
|
|
|
|
|
>
|
2026-03-31 05:00:33 +07:00
|
|
|
<AppHeader />
|
2026-04-22 02:45:45 +07:00
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
flex: 1,
|
|
|
|
|
display: 'flex',
|
|
|
|
|
flexDirection: 'column',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
justifyContent: 'center',
|
|
|
|
|
gap: 16,
|
|
|
|
|
}}
|
|
|
|
|
>
|
2026-03-31 05:00:33 +07:00
|
|
|
<div style={{ fontSize: 48, color: '#555' }}>404</div>
|
feat(i18n): translate small editor remates + admin internals (Blocks 11+12)
Block 11 — small editor surfaces
- PinPickerDialog: close, filter pins, no-match, rotate / delete
action buttons.
- RaspberryPiWorkspace: connection status (Connected / Starting…
/ Offline), Start Pi button + tooltip, Connect / Disconnect
buttons + tooltips, Terminal tab label, file-tab close, the
full offline overlay (title / subtitle / start CTA / two-line
note about the staging area), terminal-loading + no-file-
selected fallbacks.
- GitHubStarBanner: aria-label, title, body copy, Star CTA,
dismiss button.
- ExampleLoaderPage: "Loading example…" status, "Example {{id}}
not found." 404 line, "Browse all examples" recovery link.
/editor and /examples links wrapped in localize().
Block 12 — admin-only internals (only admins ever see these)
- AdminBoardsTab: section headings ("By board family" / "By
exact FQBN"), full table column headers (Family / FQBN /
Compiles / Errors / Success rate / Runs / Distinct users /
Distinct projects), range selector label, no-data fallback,
load-failed error.
- AdminDashboardTab: 8 KPI cards (Total users / Total projects
/ Compiles / Runs / DAU / WAU / MAU / Public-Private), all
chart titles + subtitles (Activity over time, Compiles by
board family, Board diversity for pricing signal, Top FQBNs,
Top countries with Cloudflare disclaimer, Top users / Top
projects), table column headers, no-data fallbacks, load
errors. Pluralised "{{count}} board(s)" via i18next plurals
in the diversity pie chart.
- UserActivityModal: title with username interpolation, subtitle,
range selector label, table column headers (Date / Project /
Compiles / Errors / Runs / Saves), pluralised
"{{count}} project(s)" line, deleted-project / no-project
placeholder strings, no-activity empty state, load-failed.
All 8 non-English locales auto-translated via the
`scripts/translate-i18n.mjs` DeepSeek pipeline (one --force run,
~7 min). sameShape() validation passed on every output.
2026-05-10 02:22:16 +07:00
|
|
|
<div style={{ fontSize: 16, color: '#999' }}>{t('examples.notFound', { id: exampleId })}</div>
|
2026-03-31 05:00:33 +07:00
|
|
|
<Link
|
feat(i18n): translate small editor remates + admin internals (Blocks 11+12)
Block 11 — small editor surfaces
- PinPickerDialog: close, filter pins, no-match, rotate / delete
action buttons.
- RaspberryPiWorkspace: connection status (Connected / Starting…
/ Offline), Start Pi button + tooltip, Connect / Disconnect
buttons + tooltips, Terminal tab label, file-tab close, the
full offline overlay (title / subtitle / start CTA / two-line
note about the staging area), terminal-loading + no-file-
selected fallbacks.
- GitHubStarBanner: aria-label, title, body copy, Star CTA,
dismiss button.
- ExampleLoaderPage: "Loading example…" status, "Example {{id}}
not found." 404 line, "Browse all examples" recovery link.
/editor and /examples links wrapped in localize().
Block 12 — admin-only internals (only admins ever see these)
- AdminBoardsTab: section headings ("By board family" / "By
exact FQBN"), full table column headers (Family / FQBN /
Compiles / Errors / Success rate / Runs / Distinct users /
Distinct projects), range selector label, no-data fallback,
load-failed error.
- AdminDashboardTab: 8 KPI cards (Total users / Total projects
/ Compiles / Runs / DAU / WAU / MAU / Public-Private), all
chart titles + subtitles (Activity over time, Compiles by
board family, Board diversity for pricing signal, Top FQBNs,
Top countries with Cloudflare disclaimer, Top users / Top
projects), table column headers, no-data fallbacks, load
errors. Pluralised "{{count}} board(s)" via i18next plurals
in the diversity pie chart.
- UserActivityModal: title with username interpolation, subtitle,
range selector label, table column headers (Date / Project /
Compiles / Errors / Runs / Saves), pluralised
"{{count}} project(s)" line, deleted-project / no-project
placeholder strings, no-activity empty state, load-failed.
All 8 non-English locales auto-translated via the
`scripts/translate-i18n.mjs` DeepSeek pipeline (one --force run,
~7 min). sameShape() validation passed on every output.
2026-05-10 02:22:16 +07:00
|
|
|
to={localize('/examples')}
|
2026-03-31 05:00:33 +07:00
|
|
|
style={{
|
2026-04-22 02:45:45 +07:00
|
|
|
color: '#4fc3f7',
|
|
|
|
|
textDecoration: 'none',
|
|
|
|
|
border: '1px solid #4fc3f7',
|
|
|
|
|
borderRadius: 4,
|
|
|
|
|
padding: '8px 20px',
|
|
|
|
|
fontSize: 14,
|
2026-03-31 05:00:33 +07:00
|
|
|
}}
|
|
|
|
|
>
|
feat(i18n): translate small editor remates + admin internals (Blocks 11+12)
Block 11 — small editor surfaces
- PinPickerDialog: close, filter pins, no-match, rotate / delete
action buttons.
- RaspberryPiWorkspace: connection status (Connected / Starting…
/ Offline), Start Pi button + tooltip, Connect / Disconnect
buttons + tooltips, Terminal tab label, file-tab close, the
full offline overlay (title / subtitle / start CTA / two-line
note about the staging area), terminal-loading + no-file-
selected fallbacks.
- GitHubStarBanner: aria-label, title, body copy, Star CTA,
dismiss button.
- ExampleLoaderPage: "Loading example…" status, "Example {{id}}
not found." 404 line, "Browse all examples" recovery link.
/editor and /examples links wrapped in localize().
Block 12 — admin-only internals (only admins ever see these)
- AdminBoardsTab: section headings ("By board family" / "By
exact FQBN"), full table column headers (Family / FQBN /
Compiles / Errors / Success rate / Runs / Distinct users /
Distinct projects), range selector label, no-data fallback,
load-failed error.
- AdminDashboardTab: 8 KPI cards (Total users / Total projects
/ Compiles / Runs / DAU / WAU / MAU / Public-Private), all
chart titles + subtitles (Activity over time, Compiles by
board family, Board diversity for pricing signal, Top FQBNs,
Top countries with Cloudflare disclaimer, Top users / Top
projects), table column headers, no-data fallbacks, load
errors. Pluralised "{{count}} board(s)" via i18next plurals
in the diversity pie chart.
- UserActivityModal: title with username interpolation, subtitle,
range selector label, table column headers (Date / Project /
Compiles / Errors / Runs / Saves), pluralised
"{{count}} project(s)" line, deleted-project / no-project
placeholder strings, no-activity empty state, load-failed.
All 8 non-English locales auto-translated via the
`scripts/translate-i18n.mjs` DeepSeek pipeline (one --force run,
~7 min). sameShape() validation passed on every output.
2026-05-10 02:22:16 +07:00
|
|
|
{t('examples.browseAll')}
|
2026-03-31 05:00:33 +07:00
|
|
|
</Link>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
2026-04-22 02:45:45 +07:00
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
display: 'flex',
|
|
|
|
|
flexDirection: 'column',
|
|
|
|
|
minHeight: '100vh',
|
|
|
|
|
background: '#1e1e1e',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
justifyContent: 'center',
|
|
|
|
|
}}
|
|
|
|
|
>
|
2026-03-31 05:00:33 +07:00
|
|
|
<div style={{ textAlign: 'center' }}>
|
feat(i18n): translate small editor remates + admin internals (Blocks 11+12)
Block 11 — small editor surfaces
- PinPickerDialog: close, filter pins, no-match, rotate / delete
action buttons.
- RaspberryPiWorkspace: connection status (Connected / Starting…
/ Offline), Start Pi button + tooltip, Connect / Disconnect
buttons + tooltips, Terminal tab label, file-tab close, the
full offline overlay (title / subtitle / start CTA / two-line
note about the staging area), terminal-loading + no-file-
selected fallbacks.
- GitHubStarBanner: aria-label, title, body copy, Star CTA,
dismiss button.
- ExampleLoaderPage: "Loading example…" status, "Example {{id}}
not found." 404 line, "Browse all examples" recovery link.
/editor and /examples links wrapped in localize().
Block 12 — admin-only internals (only admins ever see these)
- AdminBoardsTab: section headings ("By board family" / "By
exact FQBN"), full table column headers (Family / FQBN /
Compiles / Errors / Success rate / Runs / Distinct users /
Distinct projects), range selector label, no-data fallback,
load-failed error.
- AdminDashboardTab: 8 KPI cards (Total users / Total projects
/ Compiles / Runs / DAU / WAU / MAU / Public-Private), all
chart titles + subtitles (Activity over time, Compiles by
board family, Board diversity for pricing signal, Top FQBNs,
Top countries with Cloudflare disclaimer, Top users / Top
projects), table column headers, no-data fallbacks, load
errors. Pluralised "{{count}} board(s)" via i18next plurals
in the diversity pie chart.
- UserActivityModal: title with username interpolation, subtitle,
range selector label, table column headers (Date / Project /
Compiles / Errors / Runs / Saves), pluralised
"{{count}} project(s)" line, deleted-project / no-project
placeholder strings, no-activity empty state, load-failed.
All 8 non-English locales auto-translated via the
`scripts/translate-i18n.mjs` DeepSeek pipeline (one --force run,
~7 min). sameShape() validation passed on every output.
2026-05-10 02:22:16 +07:00
|
|
|
<div style={{ fontSize: 16, color: '#ccc', marginBottom: 12 }}>{t('examples.loadingExample')}</div>
|
2026-03-31 05:00:33 +07:00
|
|
|
{installing && (
|
|
|
|
|
<div style={{ maxWidth: 300, margin: '0 auto' }}>
|
|
|
|
|
<div style={{ fontSize: 13, color: '#999', marginBottom: 8 }}>
|
feat(i18n): translate small editor remates + admin internals (Blocks 11+12)
Block 11 — small editor surfaces
- PinPickerDialog: close, filter pins, no-match, rotate / delete
action buttons.
- RaspberryPiWorkspace: connection status (Connected / Starting…
/ Offline), Start Pi button + tooltip, Connect / Disconnect
buttons + tooltips, Terminal tab label, file-tab close, the
full offline overlay (title / subtitle / start CTA / two-line
note about the staging area), terminal-loading + no-file-
selected fallbacks.
- GitHubStarBanner: aria-label, title, body copy, Star CTA,
dismiss button.
- ExampleLoaderPage: "Loading example…" status, "Example {{id}}
not found." 404 line, "Browse all examples" recovery link.
/editor and /examples links wrapped in localize().
Block 12 — admin-only internals (only admins ever see these)
- AdminBoardsTab: section headings ("By board family" / "By
exact FQBN"), full table column headers (Family / FQBN /
Compiles / Errors / Success rate / Runs / Distinct users /
Distinct projects), range selector label, no-data fallback,
load-failed error.
- AdminDashboardTab: 8 KPI cards (Total users / Total projects
/ Compiles / Runs / DAU / WAU / MAU / Public-Private), all
chart titles + subtitles (Activity over time, Compiles by
board family, Board diversity for pricing signal, Top FQBNs,
Top countries with Cloudflare disclaimer, Top users / Top
projects), table column headers, no-data fallbacks, load
errors. Pluralised "{{count}} board(s)" via i18next plurals
in the diversity pie chart.
- UserActivityModal: title with username interpolation, subtitle,
range selector label, table column headers (Date / Project /
Compiles / Errors / Runs / Saves), pluralised
"{{count}} project(s)" line, deleted-project / no-project
placeholder strings, no-activity empty state, load-failed.
All 8 non-English locales auto-translated via the
`scripts/translate-i18n.mjs` DeepSeek pipeline (one --force run,
~7 min). sameShape() validation passed on every output.
2026-05-10 02:22:16 +07:00
|
|
|
{t('examples.installing', { done: installing.done + 1, total: installing.total })}
|
2026-03-31 05:00:33 +07:00
|
|
|
</div>
|
|
|
|
|
<div style={{ fontSize: 14, color: '#00e5ff', fontWeight: 600, marginBottom: 12 }}>
|
|
|
|
|
{installing.current}
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{ height: 4, borderRadius: 2, background: '#333', overflow: 'hidden' }}>
|
2026-04-22 02:45:45 +07:00
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
height: '100%',
|
|
|
|
|
borderRadius: 2,
|
|
|
|
|
background: '#00b8d4',
|
|
|
|
|
width: `${((installing.done + 1) / installing.total) * 100}%`,
|
|
|
|
|
transition: 'width 0.3s ease',
|
|
|
|
|
}}
|
|
|
|
|
/>
|
2026-03-31 05:00:33 +07:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|