import { findMedia } from '~/data/repositories/media'
import { renderPng, renderVariant } from '~/lib/media-images'
import { uploadMedia } from '~/lib/media-upload'
import { getStorage, objectPath } from '~/lib/storage'
export const sampleWidth = 2000
export const sampleHeight = 1125
export type SampleImage = {
key: string
id: string
project: string
filename: string
alt: string
caption: string
svg: () => string
}
function rng(seed: number): () => number {
let state = seed % 4294967296
return () => {
state = (state * 1664525 + 1013904223) % 4294967296
return state / 4294967296
}
}
function round(value: number): number {
return Math.round(value * 100) / 100
}
function frame(body: string, tint: string): string {
return [
`',
].join('')
}
function ruleGrid(): string {
const lines: string[] = []
for (let y = 150; y < 1040; y += 74) {
lines.push(``)
}
return lines.join('')
}
function ruleEngine(): string {
const tint = '#2e7d5b'
const parts: string[] = [ruleGrid()]
for (let index = 0; index < 3; index += 1) {
const y = 240 + index * 250
parts.push(``)
parts.push(``)
parts.push(``)
parts.push(``)
parts.push(``)
parts.push(
``,
)
parts.push(``)
}
return frame(parts.join(''), tint)
}
function columnMenu(): string {
const tint = '#2b4a9b'
const parts: string[] = []
const columns = [180, 560, 940, 1320, 1620]
const widths = [340, 340, 340, 260, 220]
parts.push('')
columns.forEach((x, column) => {
const width = widths[column] ?? 300
parts.push(``)
for (let row = 0; row < 9; row += 1) {
const y = 260 + row * 84
const bar = Math.round(width * (0.45 + ((row + column) % 4) * 0.13))
const fill = column === 3 ? tint : '#dedcd3'
const opacity = column === 3 ? round(0.85 - (row % 4) * 0.15) : 1
parts.push(``)
}
})
for (let row = 0; row < 9; row += 1) {
const y = 244 + row * 84
parts.push(``)
}
parts.push(``)
for (let entry = 0; entry < 4; entry += 1) {
parts.push(``)
}
return frame(parts.join(''), tint)
}
function trackerMap(): string {
const tint = '#b4761a'
const parts: string[] = []
const random = rng(20260730)
for (let x = 180; x < 1880; x += 106) {
parts.push(``)
}
for (let y = 150; y < 1020; y += 96) {
parts.push(``)
}
for (let index = 0; index < 220; index += 1) {
const x = round(160 + random() * 1700)
const y = round(140 + random() * 860)
const radius = round(3 + random() * 4)
parts.push(``)
}
const clusters = [
{ x: 520, y: 400, size: 96 },
{ x: 1180, y: 620, size: 132 },
{ x: 1560, y: 320, size: 74 },
]
for (const cluster of clusters) {
parts.push(``)
parts.push(``)
parts.push(``)
}
parts.push(``)
return frame(parts.join(''), tint)
}
function slaClock(): string {
const tint = '#2e7d5b'
const parts: string[] = []
const pauses = [
{ x: 700, width: 220 },
{ x: 1420, width: 220 },
]
for (const pause of pauses) {
parts.push(``)
}
for (let index = 0; index < 7; index += 1) {
const y = 250 + index * 110
const start = 180 + index * 42
const width = 420 + ((index * 7) % 5) * 190
parts.push(``)
parts.push(``)
parts.push(``)
}
parts.push('')
for (let tick = 0; tick < 12; tick += 1) {
parts.push(``)
}
return frame(parts.join(''), tint)
}
function inbox(): string {
const tint = '#6b4ba8'
const parts: string[] = []
const lanes = [200, 700, 1200]
lanes.forEach((x, lane) => {
for (let row = 0; row < 4; row += 1) {
const y = 210 + row * 120
parts.push(``)
parts.push(``)
parts.push(``)
parts.push(``)
}
parts.push(
``,
)
})
parts.push(``)
parts.push('')
parts.push('')
return frame(parts.join(''), tint)
}
export const sampleImages: SampleImage[] = [
{
key: 'regel-engine',
id: '0b6f0f4a-1c1f-4a51-9b2f-1d0a41f00001',
project: 'trakk',
filename: 'regel-engine-bedingung-aktion.png',
alt: 'Schema der Regel-Engine: links drei Bedingungen, rechts drei Aktionen, jeweils mit einer Linie verbunden',
caption: 'Jede Bedingung zeigt auf genau eine Aktion.',
svg: ruleEngine,
},
{
key: 'spaltenmenue',
id: '0b6f0f4a-1c1f-4a51-9b2f-1d0a41f00002',
project: 'mta360',
filename: 'spaltenmenue-rechtsklick.png',
alt: 'Tabelle mit fünf Spalten, über der vierten Spalte ist ein Menü mit vier Einträgen geöffnet',
caption: 'Das Spaltenmenü öffnet sich über der Spalte, die es betrifft.',
svg: columnMenu,
},
{
key: 'tracker-karte',
id: '0b6f0f4a-1c1f-4a51-9b2f-1d0a41f00003',
project: 'mta-telematik',
filename: 'tracker-karte-cluster.png',
alt: 'Kartenausschnitt mit vielen kleinen Punkten und drei hervorgehobenen Ballungen, die mit einer gestrichelten Linie verbunden sind',
caption: 'Dicht beieinander liegende Tracker werden zu Ballungen zusammengefasst.',
svg: trackerMap,
},
{
key: 'sla-uhr',
id: '0b6f0f4a-1c1f-4a51-9b2f-1d0a41f00004',
project: 'trakk',
filename: 'sla-uhr-pausiert.png',
alt: 'Zeitleiste mit sieben Balken, zwei helle senkrechte Bänder markieren die Zeiten, in denen die Uhr steht',
caption: 'Die hellen Bänder sind Wochenenden und Feiertage, dort läuft die Uhr nicht.',
svg: slaClock,
},
{
key: 'eingang',
id: '0b6f0f4a-1c1f-4a51-9b2f-1d0a41f00005',
project: 'orbit',
filename: 'kommentare-ein-eingang.png',
alt: 'Drei Spalten mit Kommentaren laufen über geschwungene Linien in einen gemeinsamen Eingang unten zusammen',
caption: 'Drei Kanäle, ein Eingang.',
svg: inbox,
},
]
export async function ensureSampleMedia(projectIds: Map): Promise