-
+
+
@@ -9,8 +9,8 @@
-
diff --git a/ui/src/components/StepSelectionAct.vue b/ui/src/components/StepSelectionAct.vue
index c2da143..0d40a3f 100644
--- a/ui/src/components/StepSelectionAct.vue
+++ b/ui/src/components/StepSelectionAct.vue
@@ -1,25 +1,25 @@
-
-
-
- {{ act.name }}
-
-
-
-
-
-
+
+
+
+ {{ act.name }}
+
+
+
+
+
+
-
\ No newline at end of file
diff --git a/ui/src/components/StepSelectionScene.vue b/ui/src/components/StepSelectionScene.vue
index c6b012c..99a4dfd 100644
--- a/ui/src/components/StepSelectionScene.vue
+++ b/ui/src/components/StepSelectionScene.vue
@@ -1,26 +1,26 @@
-
-
- {{ scene.name }}
-
-
-
-
-
+
+
+ {{ scene.name }}
+
+
+
+
+
-
\ No newline at end of file
diff --git a/ui/src/components/StepSelectionStep.vue b/ui/src/components/StepSelectionStep.vue
index 1c5b0ca..574db45 100644
--- a/ui/src/components/StepSelectionStep.vue
+++ b/ui/src/components/StepSelectionStep.vue
@@ -1,43 +1,43 @@
-
-
-
-
-
-
+
+
+
+
+
+
-
\ No newline at end of file
diff --git a/ui/src/components/TimeDisplay.vue b/ui/src/components/TimeDisplay.vue
index e8277ac..3bd42d6 100755
--- a/ui/src/components/TimeDisplay.vue
+++ b/ui/src/components/TimeDisplay.vue
@@ -1,6 +1,6 @@
-
+
{{ format.format(syncedTime) }}
@@ -9,7 +9,7 @@
-
diff --git a/ui/src/pages/control.vue b/ui/src/pages/control.vue
deleted file mode 100755
index 150668a..0000000
--- a/ui/src/pages/control.vue
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
- {{ current.act === null ? "" : `${current.act.name} — `}}{{ current.scene.name }}
-
-
-
-
-
-
Vorhang: {{ current.step.curtainState === "open" ? "auf" : "geschlossen"}}
-
-
-
-
-
-
-
-
-
-
diff --git a/ui/src/pages/for/audio-operator.vue b/ui/src/pages/for/audio-operator.vue
new file mode 100755
index 0000000..f3974d9
--- /dev/null
+++ b/ui/src/pages/for/audio-operator.vue
@@ -0,0 +1,25 @@
+
+
+
+ {{ current.act === null ? "" : `${current.act.name} — ` }}{{ current.scene.name }}
+
+
+
+
+
+
+
diff --git a/ui/src/pages/for/show-operator.vue b/ui/src/pages/for/show-operator.vue
new file mode 100755
index 0000000..a48ae90
--- /dev/null
+++ b/ui/src/pages/for/show-operator.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+ Vorhang
+
+
+ {{ current.step.curtainState === "open" ? "öffnen" : "schließen" }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ui/src/pages/for/spot-operator.vue b/ui/src/pages/for/spot-operator.vue
new file mode 100644
index 0000000..b46aea3
--- /dev/null
+++ b/ui/src/pages/for/spot-operator.vue
@@ -0,0 +1,71 @@
+
+
+
+
+ Aktuelles Ziel
+
+
+ {{ currentTarget ?? "Niemand" }}
+
+
+
+
+ Nächstes Ziel
+
+ [{{
+ nextStepWithChange.delta === 0
+ ? "in dieser Szene"
+ : nextStepWithChange.delta === 1
+ ? "in der nächsten Szene"
+ : `in ${nextStepWithChange.delta} Szenen`
+ }}]
+
+
+
{{ nextStepWithChange.target }}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ui/src/pages/index.vue b/ui/src/pages/index.vue
new file mode 100644
index 0000000..59b278c
--- /dev/null
+++ b/ui/src/pages/index.vue
@@ -0,0 +1,13 @@
+
+
+ audio operator
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ui/src/pages/kiosk/stage.vue b/ui/src/pages/kiosk/stage.vue
index 537a62f..5750574 100755
--- a/ui/src/pages/kiosk/stage.vue
+++ b/ui/src/pages/kiosk/stage.vue
@@ -1,8 +1,8 @@
-
-
- {{ current.act === null ? "" : `${current.act.name} — `}}{{ current.scene.name }}
-
+
+
+ {{ current.act === null ? "" : `${current.act.name} — ` }}{{ current.scene.name }}
+
@@ -14,7 +14,7 @@
-
diff --git a/ui/src/pages/spot-m.vue b/ui/src/pages/spot-m.vue
deleted file mode 100644
index f20698e..0000000
--- a/ui/src/pages/spot-m.vue
+++ /dev/null
@@ -1,77 +0,0 @@
-
-
-
- {{ current.act === null ? "" : `${current.act.name} — `}}{{ current.scene.name }}
-
-
-
-
- Aktuelles Ziel:
-
-
- {{ currentTarget ?? "Niemand" }}
-
-
-
-
-
Nächstes Ziel:
-
{{ nextStepWithChange.target }}
-
-
- {{ nextStepWithChange.delta === 0
- ? "in dieser Szene (rechtzeitig positionieren!)"
- : nextStepWithChange.delta === 1
- ? "in der nächsten Szene"
- : `in ${nextStepWithChange.delta} Szenen`
- }}
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/ui/src/pages/spot.vue b/ui/src/pages/spot.vue
deleted file mode 100644
index d2de4fc..0000000
--- a/ui/src/pages/spot.vue
+++ /dev/null
@@ -1,77 +0,0 @@
-
-
-
- {{ current.act === null ? "" : `${current.act.name} — `}}{{ current.scene.name }}
-
-
-
-
- Aktuelles Ziel:
-
-
- {{ currentTarget ?? "Niemand" }}
-
-
-
-
-
Nächstes Ziel:
-
{{ nextStepWithChange.target }}
-
-
- {{ nextStepWithChange.delta === 0
- ? "in dieser Szene (rechtzeitig positionieren!)"
- : nextStepWithChange.delta === 1
- ? "in der nächsten Szene"
- : `in ${nextStepWithChange.delta} Szenen`
- }}
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/ui/src/state.ts b/ui/src/state.ts
index 7066a2e..3334903 100755
--- a/ui/src/state.ts
+++ b/ui/src/state.ts
@@ -2,246 +2,246 @@ import { reactive, shallowRef } from "vue"
import { reactiveComputed } from "@vueuse/core"
export interface Act {
- name: string
- scenes: Scene[]
+ name: string
+ scenes: Scene[]
}
export interface Scene {
- name: string
- steps: Step[]
+ name: string
+ steps: Step[]
}
export interface Step {
- position: ShowPosition
- cue: StepCue
- actorEntrances: string[]
- actorExits: string[]
- actorsOnStage: string[]
- props: PropMap
- hasChangedProps: boolean
- leftSpotTarget: string | null
- rightSpotTarget: string | null
- curtainState: "open" | "closed"
+ position: ShowPosition
+ cue: StepCue
+ actorEntrances: string[]
+ actorExits: string[]
+ actorsOnStage: string[]
+ props: PropMap
+ hasChangedProps: boolean
+ leftSpotTarget: string | null
+ rightSpotTarget: string | null
+ curtainState: "open" | "closed"
}
export type StepCue = {
- type: "TEXT",
- speaker: string
- text: string
- clarification?: string
+ type: "TEXT",
+ speaker: string
+ text: string
+ clarification?: string
} | {
- type: "MUSIC_START",
- title: string
- duration: number
+ type: "MUSIC_START",
+ title: string
+ duration: number
} | {
- type: "MUSIC_END"
+ type: "MUSIC_END"
} | {
- type: "CURTAIN",
- state: "open" | "closed"
- whileMoving: boolean
+ type: "CURTAIN",
+ state: "open" | "closed"
+ whileMoving: boolean
} | {
- type: "LIGHTS"
- state: "on" | "off"
- whileFading: boolean
+ type: "LIGHTS"
+ state: "on" | "off"
+ whileFading: boolean
} | {
- type: "CUSTOM"
- text: string
+ type: "CUSTOM"
+ text: string
}
export type PropMap = Record
export type PropPosition =
- | "PROSCENIUM_LEFT"
- | "PROSCENIUM_CENTER"
- | "PROSCENIUM_RIGHT"
- | "CENTER"
- | "LEFT"
- | "RIGHT"
- | "BACKDROP"
+ | "PROSCENIUM_LEFT"
+ | "PROSCENIUM_CENTER"
+ | "PROSCENIUM_RIGHT"
+ | "CENTER"
+ | "LEFT"
+ | "RIGHT"
+ | "BACKDROP"
export interface ShowState {
- position: ShowPosition
- message: string
- activeMusic: ShowMusic | null
- musicStartTime: number
- isLightBehindCurtainOn: boolean
+ position: ShowPosition
+ message: string
+ activeMusic: ShowMusic | null
+ musicStartTime: number
+ isLightBehindCurtainOn: boolean
}
export interface ShowMusic {
- title: string
- duration: number
+ title: string
+ duration: number
}
export interface ShowPosition {
- act: number
- scene: number
- step: number
+ act: number
+ scene: number
+ step: number
}
export interface Show {
- acts: Act[]
+ acts: Act[]
}
export const START_STEP: Step = {
- position: { act: -1, scene: 0, step: 0 },
- actorsOnStage: [],
- cue: {
- type: "CUSTOM",
- text: "Start"
- },
- props: {
- BACKDROP: null,
- LEFT: null,
- CENTER: null,
- RIGHT: null,
- PROSCENIUM_LEFT: null,
- PROSCENIUM_CENTER: null,
- PROSCENIUM_RIGHT: null
- },
- hasChangedProps: false,
- actorEntrances: [],
- actorExits: [],
- leftSpotTarget: null,
- rightSpotTarget: null,
- curtainState: "closed"
+ position: { act: -1, scene: 0, step: 0 },
+ actorsOnStage: [],
+ cue: {
+ type: "CUSTOM",
+ text: "Start"
+ },
+ props: {
+ BACKDROP: null,
+ LEFT: null,
+ CENTER: null,
+ RIGHT: null,
+ PROSCENIUM_LEFT: null,
+ PROSCENIUM_CENTER: null,
+ PROSCENIUM_RIGHT: null
+ },
+ hasChangedProps: false,
+ actorEntrances: [],
+ actorExits: [],
+ leftSpotTarget: null,
+ rightSpotTarget: null,
+ curtainState: "closed"
}
const START_SCENE: Scene = {
- name: "Start",
- steps: [START_STEP]
+ name: "Start",
+ steps: [START_STEP]
}
export const show = shallowRef({
- acts: []
+ acts: []
})
export const state = reactive({
- position: START_STEP.position,
- message: "",
- activeMusic: null,
- musicStartTime: 0,
- isLightBehindCurtainOn: false
+ position: START_STEP.position,
+ message: "",
+ activeMusic: null,
+ musicStartTime: 0,
+ isLightBehindCurtainOn: false
})
export function getStep(position: ShowPosition) {
- if (position.act === -1) return START_STEP
- return getScene(position).steps[position.step]
+ if (position.act === -1) return START_STEP
+ return getScene(position).steps[position.step]
}
export function getScene(position: ShowPosition) {
- if (position.act === -1) return START_SCENE
- return getAct(position)!.scenes[position.scene]
+ if (position.act === -1) return START_SCENE
+ return getAct(position)!.scenes[position.scene]
}
export function getAct(position: ShowPosition) {
- if (position.act === -1) return null
- return show.value.acts[position.act]
+ if (position.act === -1) return null
+ return show.value.acts[position.act]
}
export function getSceneIndex(position: ShowPosition) {
- let index = position.scene
+ let index = position.scene
- for (let actIndex = 0; actIndex < position.act; actIndex++) {
- index += show.value.acts[actIndex]!.scenes.length
- }
+ for (let actIndex = 0; actIndex < position.act; actIndex++) {
+ index += show.value.acts[actIndex]!.scenes.length
+ }
- return index
+ return index
}
export function getActiveMusicAt(position: ShowPosition): ShowMusic | null {
- let activeMusic: ShowMusic | null = null
+ let activeMusic: ShowMusic | null = null
- for (let actIndex = 0; actIndex < show.value.acts.length; actIndex++) {
- const scenes = show.value.acts[actIndex].scenes
+ for (let actIndex = 0; actIndex < show.value.acts.length; actIndex++) {
+ const scenes = show.value.acts[actIndex].scenes
- for (let sceneIndex = 0; sceneIndex < scenes.length; sceneIndex++) {
- const scene = scenes[sceneIndex]
+ for (let sceneIndex = 0; sceneIndex < scenes.length; sceneIndex++) {
+ const scene = scenes[sceneIndex]
- for (let stepIndex = 0; stepIndex < scene.steps.length; stepIndex++) {
- const step = scene.steps[stepIndex]
+ for (let stepIndex = 0; stepIndex < scene.steps.length; stepIndex++) {
+ const step = scene.steps[stepIndex]
- // SONG
- if (step.cue.type === "MUSIC_START") {
- activeMusic = {
- title: step.cue.title,
- duration: step.cue.duration
- }
- } else if (step.cue.type === "MUSIC_END") {
- activeMusic = null
+ // SONG
+ if (step.cue.type === "MUSIC_START") {
+ activeMusic = {
+ title: step.cue.title,
+ duration: step.cue.duration
+ }
+ } else if (step.cue.type === "MUSIC_END") {
+ activeMusic = null
+ }
+
+ if (sceneIndex == position.scene && stepIndex == position.step) return activeMusic
+ }
}
-
- if (sceneIndex == position.scene && stepIndex == position.step) return activeMusic
- }
}
- }
- return null
+ return null
}
export const current = reactiveComputed<{
- act: Act | null
- scene: Scene
- sceneIndex: number
- step: Step
- activeMusic: ShowMusic | null
- allScenes: Scene[]
+ act: Act | null
+ scene: Scene
+ sceneIndex: number
+ step: Step
+ activeMusic: ShowMusic | null
+ allScenes: Scene[]
}>(() => ({
- act: getAct(state.position),
- scene: getScene(state.position),
- sceneIndex: getSceneIndex(state.position),
- step: getStep(state.position),
- activeMusic: state.activeMusic,
- allScenes: show.value.acts.flatMap(act => act.scenes)
+ act: getAct(state.position),
+ scene: getScene(state.position),
+ sceneIndex: getSceneIndex(state.position),
+ step: getStep(state.position),
+ activeMusic: state.activeMusic,
+ allScenes: show.value.acts.flatMap(act => act.scenes)
}))
export function parseStringWithDetails(string: string) {
- const parts = string.split(" / ")
- if (parts.length === 1) return { main: parts[0], details: "" }
- return { main: parts[0], details: parts.slice(1).join(" / ") }
+ const parts = string.split(" / ")
+ if (parts.length === 1) return { main: parts[0], details: "" }
+ return { main: parts[0], details: parts.slice(1).join(" / ") }
}
export function getNextValidPosition(start: ShowPosition): ShowPosition | null {
- if (start.act === START_STEP.position.act) return { act: 0, scene: 0, step: 0 }
- const acts = show.value.acts
- let { act, scene, step } = start
+ if (start.act === START_STEP.position.act) return { act: 0, scene: 0, step: 0 }
+ const acts = show.value.acts
+ let { act, scene, step } = start
- step++
+ step++
- if (step >= acts[start.act].scenes[start.scene].steps.length) {
- step = 0
- scene++
+ if (step >= acts[start.act].scenes[start.scene].steps.length) {
+ step = 0
+ scene++
- if (scene >= acts[start.act].scenes.length) {
- scene = 0
- act++
+ if (scene >= acts[start.act].scenes.length) {
+ scene = 0
+ act++
- if (act >= acts.length) {
- return null
- }
+ if (act >= acts.length) {
+ return null
+ }
+ }
}
- }
- return { act, scene, step }
+ return { act, scene, step }
}
export function getPreviousValidPosition(start: ShowPosition): ShowPosition | null {
- let { act, scene, step } = start
- step--
+ let { act, scene, step } = start
+ step--
- if (step < 0) {
- scene--
+ if (step < 0) {
+ scene--
- if (scene < 0) {
- act--
+ if (scene < 0) {
+ act--
- if (act < 0) {
- return START_STEP.position
- }
+ if (act < 0) {
+ return START_STEP.position
+ }
- scene = show.value.acts[act].scenes.length - 1
+ scene = show.value.acts[act].scenes.length - 1
+ }
+
+ step = show.value.acts[act].scenes[scene].steps.length - 1
}
- step = show.value.acts[act].scenes[scene].steps.length - 1
- }
-
- return { act, scene, step }
+ return { act, scene, step }
}
diff --git a/ui/src/syncing.ts b/ui/src/syncing.ts
index 00486a7..76a8345 100755
--- a/ui/src/syncing.ts
+++ b/ui/src/syncing.ts
@@ -9,50 +9,50 @@ export const getSyncedTime = () => Date.now() - timeDifference
export const syncedTime = ref(Date.now())
const setSyncedTimeRef = () => {
- syncedTime.value = getSyncedTime()
- requestAnimationFrame(setSyncedTimeRef)
+ syncedTime.value = getSyncedTime()
+ requestAnimationFrame(setSyncedTimeRef)
}
requestAnimationFrame(setSyncedTimeRef)
export const connect = () => new Promise(resolve => {
- if (socket !== null) return
+ if (socket !== null) return
- const url = new URL(window.location.toString())
- url.protocol = "ws"
- url.pathname = "/api/ws"
- socket = new ReconnectingWebSocket(url.toString(), [], {
- reconnectionDelayGrowFactor: 1,
- minReconnectionDelay: 1000
- })
+ const url = new URL(window.location.toString())
+ url.protocol = "ws"
+ url.pathname = "/api/ws"
+ socket = new ReconnectingWebSocket(url.toString(), [], {
+ reconnectionDelayGrowFactor: 1,
+ minReconnectionDelay: 1000
+ })
- let isFirstMessage = true
+ let isFirstMessage = true
- socket.addEventListener("open", () => {
- isFirstMessage = true
- })
+ socket.addEventListener("open", () => {
+ isFirstMessage = true
+ })
- socket.addEventListener("message", event => {
- const data = JSON.parse(event.data as string)
+ socket.addEventListener("message", event => {
+ const data = JSON.parse(event.data as string)
- if (isFirstMessage) {
- isFirstMessage = false
- show.value = data
- console.log("Show:", data)
- } else {
- Object.assign(state, data.state)
- timeDifference = Date.now() - data.timestamp
- console.log("New state:", data.state)
- console.log("New time difference:", timeDifference)
- resolve()
- }
- })
+ if (isFirstMessage) {
+ isFirstMessage = false
+ show.value = data
+ console.log("Show:", data)
+ } else {
+ Object.assign(state, data.state)
+ timeDifference = Date.now() - data.timestamp
+ console.log("New state:", data.state)
+ console.log("New time difference:", timeDifference)
+ resolve()
+ }
+ })
})
export async function goToPosition(position: ShowPosition) {
- await fetch("/api/go", { method: "POST", body: JSON.stringify(position), headers: { "Content-Type": "application/json" } })
+ await fetch("/api/go", { method: "POST", body: JSON.stringify(position), headers: { "Content-Type": "application/json" } })
}
export async function setMessage(message: string) {
- await fetch("/api/message", { method: "POST", body: message })
+ await fetch("/api/message", { method: "POST", body: message })
}
diff --git a/ui/src/vite-env.d.ts b/ui/src/vite-env.d.ts
deleted file mode 100755
index a40b464..0000000
--- a/ui/src/vite-env.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-///
-///
-///
diff --git a/ui/tsconfig.json b/ui/tsconfig.json
index 27044d3..f594370 100755
--- a/ui/tsconfig.json
+++ b/ui/tsconfig.json
@@ -1,20 +1,37 @@
{
"compilerOptions": {
- "baseUrl": ".",
- "module": "ESNext",
- "target": "ES2021",
- "lib": ["DOM", "ESNext"],
- "strict": true,
+ "declaration": false,
"esModuleInterop": true,
- "skipLibCheck": false,
- "moduleResolution": "node",
+ "forceConsistentCasingInFileNames": true,
+ "lib": [
+ "esnext",
+ "dom",
+ ],
+ "module": "esnext",
+ "moduleResolution": "Bundler",
+ "allowJs": true,
"resolveJsonModule": true,
- "strictNullChecks": true,
- "downlevelIteration": true,
- "forceConsistentCasingInFileNames": true
+ "isolatedModules": true,
+ "rootDir": "src",
+ "skipLibCheck": true,
+ "sourceMap": true,
+ "strict": true,
+ "stripInternal": true,
+ "noUncheckedIndexedAccess": false,
+ "target": "esnext",
+ "types": [
+ "vite/client",
+ "unplugin-vue-router/client",
+ "unplugin-icons/types/vue"
+ ],
+ "paths": {
+ "@/*": [
+ "./src/*"
+ ]
+ }
},
"include": [
- "node_modules/**/*",
- "src/**/*"
+ "src/**/*.ts",
+ "src/**/*.vue",
]
}
diff --git a/ui/unocss.config.ts b/ui/unocss.config.ts
new file mode 100755
index 0000000..2da2f4a
--- /dev/null
+++ b/ui/unocss.config.ts
@@ -0,0 +1,44 @@
+import { defineConfig, transformerDirectives } from "unocss"
+import { presetWind, colors } from "@unocss/preset-wind3"
+
+const generateValues = (max: number, fn: (step: number) => any) => {
+ const object: Record = {}
+
+ for (let i = 1; i <= max; i++) {
+ object[i] = fn(i)
+ }
+
+ return object
+}
+
+export default defineConfig({
+ presets: [
+ presetWind({
+ arbitraryVariants: true,
+ preflight: true
+ })
+ ],
+ theme: {
+ fontFamily: {
+ sans: `"Manrope Variable", sans-serif`,
+ system: "sans-serif"
+ },
+ colors: {
+ black: colors.black,
+ white: colors.white,
+ gray: colors.stone,
+ red: colors.red,
+ yellow: colors.amber,
+ orange: colors.orange,
+ green: colors.green,
+ blue: colors.blue,
+ violet: colors.fuchsia,
+ light: colors.light,
+ dark: colors.dark,
+ transparent: colors.transparent
+ }
+ },
+ transformers: [
+ transformerDirectives()
+ ]
+})
diff --git a/ui/vite.config.ts b/ui/vite.config.ts
index 3ef5368..53ec8a0 100755
--- a/ui/vite.config.ts
+++ b/ui/vite.config.ts
@@ -1,28 +1,39 @@
-import { defineConfig, splitVendorChunkPlugin } from "vite"
+import { defineConfig } from "vite"
import vuePlugin from "@vitejs/plugin-vue"
-import windicssPlugin from "vite-plugin-windicss"
-import pagesPlugin from "vite-plugin-pages"
import iconsPlugin from "unplugin-icons/vite"
+import vueRouterPlugin from "unplugin-vue-router/vite"
+import unocssPlugin from "unocss/vite"
+import { resolve } from "node:path"
export default defineConfig({
plugins: [
- splitVendorChunkPlugin(),
- vuePlugin(),
- pagesPlugin({
- importMode: "sync"
+ vueRouterPlugin({
+ dts: "./src/generated-types/router.d.ts",
+ routesFolder: "./src/pages",
}),
- windicssPlugin(),
- iconsPlugin()
+ unocssPlugin(),
+ iconsPlugin(),
+ vuePlugin()
],
+ resolve: {
+ alias: {
+ "@": resolve(__dirname, "./src")
+ }
+ },
+ css: {
+ preprocessorOptions: {
+ scss: {
+ api: "modern-compiler"
+ }
+ }
+ },
server: {
proxy: {
"/api": {
target: "http://localhost:8000",
ws: true
}
- }
- },
- build: {
- reportCompressedSize: false
+ },
+ allowedHosts: true
}
})
diff --git a/ui/windi.config.ts b/ui/windi.config.ts
deleted file mode 100755
index 8d4511d..0000000
--- a/ui/windi.config.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { defineConfig } from "windicss/helpers"
-import colors from "windicss/colors"
-import lineClampPlugin from "windicss/plugin/line-clamp"
-
-const generateValues = (max: number, fn: (step: number) => any) => {
- const object: Record = {}
-
- for (let i = 1; i <= max; i++) {
- object[i] = fn(i)
- }
-
- return object
-}
-
-export default defineConfig({
- theme: {
- colors: {
- black: colors.black,
- white: colors.white,
- gray: colors.stone,
- red: colors.red,
- yellow: colors.amber,
- orange: colors.orange,
- green: colors.green,
- blue: colors.blue,
- violet: colors.fuchsia,
- light: colors.light,
- dark: colors.dark,
- transparent: colors.transparent
- },
- fontSize: {
- ...generateValues(30, step => `${step * 0.25}rem`),
- 4: "1.2rem",
- 3: "1.1rem",
- 2: "1rem",
- s1: "0.9rem",
- s2: "0.8rem",
- s3: "0.7rem"
- }
- },
- plugins: [
- lineClampPlugin
- ]
-})