Compare commits
15 Commits
705a1c4910
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
f1afc57f45
|
|||
|
1e4751f8cf
|
|||
|
805b553038
|
|||
|
89459caca1
|
|||
|
c7fcdcf81b
|
|||
|
5e35ecd921
|
|||
|
ee43f5241b
|
|||
|
2836ca3530
|
|||
|
93b5543017
|
|||
|
e8ffb3e3e5
|
|||
|
d38b3eeab2
|
|||
|
c8caacf1e2
|
|||
|
e47dcf5983
|
|||
|
d1f3e0f514
|
|||
|
7ed1b207b4
|
@@ -12,6 +12,9 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.DEPLOY_TOKEN }}
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
@@ -26,3 +29,30 @@ jobs:
|
||||
|
||||
- name: Build
|
||||
run: npm run build
|
||||
|
||||
- name: Push dist to release branch
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
run: |
|
||||
git config user.name "ci"
|
||||
git config user.email "git@limelight.de"
|
||||
|
||||
# Save distributable files before switching branch
|
||||
mkdir -p /tmp/release
|
||||
cp package.json theme.css font.css /tmp/release/
|
||||
cp -r fonts assets /tmp/release/
|
||||
|
||||
# Create a clean orphan branch (no source files)
|
||||
git checkout --orphan release
|
||||
git rm -rf .
|
||||
|
||||
# Restore distributable files (dist/ survived as it was gitignored)
|
||||
cp /tmp/release/package.json .
|
||||
npm pkg delete scripts.prepare
|
||||
cp /tmp/release/theme.css .
|
||||
cp /tmp/release/font.css .
|
||||
cp -r /tmp/release/fonts .
|
||||
cp -r /tmp/release/assets .
|
||||
|
||||
git add package.json theme.css font.css dist/ fonts/ assets/
|
||||
git commit -m "release: $(git log origin/main -1 --pretty=%s)" || echo "nothing to commit"
|
||||
git push origin release --force
|
||||
|
||||
10
.oxlintrc.json
Normal file
10
.oxlintrc.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": ["eslint", "typescript", "unicorn", "oxc", "vue"],
|
||||
"env": {
|
||||
"browser": true
|
||||
},
|
||||
"categories": {
|
||||
"correctness": "error"
|
||||
}
|
||||
}
|
||||
6
.prettierrc.json
Normal file
6
.prettierrc.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/prettierrc",
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"printWidth": 100
|
||||
}
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Limelight GmbH Veranstaltungstechnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
12
README.md
12
README.md
@@ -1,2 +1,14 @@
|
||||
# CommonWebComponents
|
||||
|
||||

|
||||
|
||||
## CSS Import
|
||||
|
||||
create a css file with the following content:
|
||||
|
||||
```css
|
||||
@import 'tailwindcss';
|
||||
@source '@/../node_modules/limelight-common-web-components/src';
|
||||
@import 'limelight-common-web-components/theme.css';
|
||||
@import 'limelight-common-web-components/style.css';
|
||||
```
|
||||
|
||||
BIN
assets/preview.png
Normal file
BIN
assets/preview.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
26
eslint.config.ts
Normal file
26
eslint.config.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { globalIgnores } from 'eslint/config'
|
||||
import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript'
|
||||
import pluginVue from 'eslint-plugin-vue'
|
||||
import pluginOxlint from 'eslint-plugin-oxlint'
|
||||
import skipFormatting from 'eslint-config-prettier/flat'
|
||||
|
||||
// To allow more languages other than `ts` in `.vue` files, uncomment the following lines:
|
||||
// import { configureVueProject } from '@vue/eslint-config-typescript'
|
||||
// configureVueProject({ scriptLangs: ['ts', 'tsx'] })
|
||||
// More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup
|
||||
|
||||
export default defineConfigWithVueTs(
|
||||
{
|
||||
name: 'app/files-to-lint',
|
||||
files: ['**/*.{vue,ts,mts,tsx}'],
|
||||
},
|
||||
|
||||
globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
|
||||
|
||||
...pluginVue.configs['flat/essential'],
|
||||
vueTsConfigs.recommended,
|
||||
|
||||
...pluginOxlint.buildFromOxlintConfigFile('.oxlintrc.json'),
|
||||
|
||||
skipFormatting,
|
||||
)
|
||||
12
index.html
Normal file
12
index.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>CommonWebComponents — Demo</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
31
main.css
31
main.css
@@ -1,31 +0,0 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
@import "./font.css";
|
||||
|
||||
@theme {
|
||||
--color-black: #000;
|
||||
--color-white: #fff;
|
||||
|
||||
--color-primary: #ffff00;
|
||||
--color-primary-dark: #504e18;
|
||||
--color-primary-light: #ffff7b;
|
||||
|
||||
--color-secondary: #404040;
|
||||
--color-secondary-light: #6b6b6b;
|
||||
--color-secondary-dark: #2a2800;
|
||||
|
||||
--color-alive: oklch(69.6% 0.17 162.48); /* Tailwind emerald-500*/
|
||||
|
||||
--color-green: oklch(62.7% 0.194 149.214); /* Tailwind green-600 */
|
||||
--color-yellow: oklch(68.1% 0.162 75.834); /* Tailwind yellow-600 */
|
||||
--color-red: oklch(57.7% 0.245 27.325); /* Tailwind red-600 */
|
||||
|
||||
--color-on-primary: var(--color-secondary);
|
||||
--color-on-secondary: var(--color-white);
|
||||
--color-hover: var(--color-primary-dark);
|
||||
|
||||
--font-limelight: "Open Sans";
|
||||
--default-font-family: var(--font-limelight);
|
||||
--breakpoint-3xl: 112rem;
|
||||
--breakpoint-4xl: 128rem;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "limelight-common-web-components",
|
||||
"version": "0.1.0",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"files": [
|
||||
"dist",
|
||||
@@ -39,6 +40,7 @@
|
||||
"vue": "^3.5.0"
|
||||
},
|
||||
"scripts": {
|
||||
"serve": "vite",
|
||||
"prepare": "vite build",
|
||||
"build": "vite build",
|
||||
"dev": "vite build --watch",
|
||||
|
||||
193
src/App.vue
Normal file
193
src/App.vue
Normal file
@@ -0,0 +1,193 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<h1 class="title">CommonWebComponents</h1>
|
||||
<p class="sub">Gaffer Tape Edge Demo — LimelightButton</p>
|
||||
|
||||
<!-- Before / After -->
|
||||
<section class="section">
|
||||
<p class="section-label">Before / After</p>
|
||||
<div class="compare">
|
||||
<div class="compare-box">
|
||||
<span class="compare-box-label">Before — diagonal cut</span>
|
||||
<button class="btn-old btn-old--primary">Primary</button>
|
||||
<button class="btn-old btn-old--danger">Danger</button>
|
||||
</div>
|
||||
<div class="compare-box">
|
||||
<span class="compare-box-label">After — torn tape</span>
|
||||
<LimelightButton variant="primary">Primary</LimelightButton>
|
||||
<LimelightButton variant="danger">Danger</LimelightButton>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- All variants -->
|
||||
<section class="section">
|
||||
<p class="section-label">All Variants</p>
|
||||
<div class="row">
|
||||
<LimelightButton variant="primary">Primary</LimelightButton>
|
||||
<LimelightButton variant="outline">Outline</LimelightButton>
|
||||
<LimelightButton variant="ghost">Ghost</LimelightButton>
|
||||
<LimelightButton variant="danger">Danger</LimelightButton>
|
||||
<LimelightButton variant="primary" :disabled="true">Disabled</LimelightButton>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Interactive -->
|
||||
<section class="section">
|
||||
<p class="section-label">Interactive States</p>
|
||||
<div class="row">
|
||||
<LimelightButton variant="primary" @click="count++">
|
||||
Clicked {{ count }}×
|
||||
</LimelightButton>
|
||||
<LimelightButton variant="danger" @click="armed = !armed">
|
||||
{{ armed ? 'ARMED' : 'Arm' }}
|
||||
</LimelightButton>
|
||||
<LimelightButton variant="ghost" @click="live = !live">
|
||||
{{ live ? 'Go Offline' : 'Go Live' }}
|
||||
</LimelightButton>
|
||||
<LimelightButton variant="outline" :disabled="!live">
|
||||
{{ live ? 'Streaming' : 'Offline' }}
|
||||
</LimelightButton>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Production board -->
|
||||
<section class="section">
|
||||
<p class="section-label">Production Board</p>
|
||||
<div class="board">
|
||||
<div v-for="ch in channels" :key="ch.name" class="board-row">
|
||||
<span class="board-row-label">{{ ch.id }}</span>
|
||||
<span class="board-chip" :class="ch.hot ? 'board-chip--hot' : ''">{{ ch.name }}</span>
|
||||
<LimelightButton variant="ghost" class="btn-sm">Arm</LimelightButton>
|
||||
<LimelightButton :variant="ch.muted ? 'danger' : 'outline'" class="btn-sm" @click="ch.muted = !ch.muted">
|
||||
{{ ch.muted ? 'Muted' : 'Mute' }}
|
||||
</LimelightButton>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import LimelightButton from './components/LimelightButton.vue'
|
||||
|
||||
const count = ref(0)
|
||||
const armed = ref(false)
|
||||
const live = ref(false)
|
||||
|
||||
const channels = reactive([
|
||||
{ id: 'CH 01', name: 'Kick In', hot: false, muted: false },
|
||||
{ id: 'CH 02', name: 'Kick Out', hot: false, muted: false },
|
||||
{ id: 'CH 12', name: 'Vox Lead', hot: true, muted: false },
|
||||
{ id: 'CH 16', name: 'DI Bass', hot: false, muted: true },
|
||||
])
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@reference "tailwindcss";
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
background: #0f0f0f;
|
||||
color: #d0d0d0;
|
||||
font-family: 'Open Sans', 'Segoe UI', system-ui, sans-serif;
|
||||
min-height: 100vh;
|
||||
padding: 3rem 2rem;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: var(--color-primary);
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.sub {
|
||||
color: #3a3a3a;
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.15em;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.section { margin-bottom: 3rem; }
|
||||
.section-label {
|
||||
color: #3a3a3a;
|
||||
font-size: 0.62rem;
|
||||
letter-spacing: 0.15em;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 1rem;
|
||||
padding-bottom: 0.4rem;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
|
||||
.row { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; }
|
||||
|
||||
/* Before/after */
|
||||
.compare { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; max-width: 560px; }
|
||||
.compare-box {
|
||||
background: #141414;
|
||||
border: 1px solid #1e1e1e;
|
||||
padding: 1.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 1rem;
|
||||
}
|
||||
.compare-box-label { color: #333; font-size: 0.6rem; letter-spacing: 0.1em; text-transform: uppercase; }
|
||||
|
||||
.btn-old {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 1.5rem;
|
||||
height: 2.5rem;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
clip-path: polygon(8px 0%, 100% 0%, calc(100% - 8px) 100%, 0% 100%);
|
||||
}
|
||||
.btn-old--primary { background: var(--color-primary); color: var(--color-black); }
|
||||
.btn-old--danger { background: var(--color-red); color: #fff; }
|
||||
|
||||
/* Board */
|
||||
.board {
|
||||
background: #111;
|
||||
border: 1px solid #1a1a1a;
|
||||
padding: 1.5rem;
|
||||
max-width: 520px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.85rem;
|
||||
}
|
||||
.board-row { display: flex; align-items: center; gap: 0.75rem; }
|
||||
.board-row-label {
|
||||
color: #2e2e2e;
|
||||
font-size: 0.6rem;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
width: 60px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.board-chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 0.2rem 0.75rem;
|
||||
font-size: 0.62rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
background: #1a1a1a;
|
||||
color: #444;
|
||||
min-width: 90px;
|
||||
}
|
||||
.board-chip--hot { background: #2a2800; color: var(--color-primary); }
|
||||
|
||||
.btn-sm { font-size: 0.65rem !important; }
|
||||
</style>
|
||||
37
src/components/ErrorPopup.test.ts
Normal file
37
src/components/ErrorPopup.test.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { mount } from "@vue/test-utils";
|
||||
import ErrorPopup from "./ErrorPopup.vue";
|
||||
|
||||
describe("ErrorPopup", () => {
|
||||
it("renders nothing when show is false", () => {
|
||||
const w = mount(ErrorPopup, { props: { show: false, message: "error" } });
|
||||
expect(w.find("[class*=fixed]").exists()).toBe(false);
|
||||
});
|
||||
|
||||
it("renders nothing when message is null even if show is true", () => {
|
||||
const w = mount(ErrorPopup, { props: { show: true, message: null } });
|
||||
expect(w.find("[class*=fixed]").exists()).toBe(false);
|
||||
});
|
||||
|
||||
it("renders popup when show is true and message is set", () => {
|
||||
const w = mount(ErrorPopup, { props: { show: true, message: "Verbindung fehlgeschlagen" } });
|
||||
expect(w.text()).toContain("Verbindung fehlgeschlagen");
|
||||
});
|
||||
|
||||
it("emits close when backdrop is clicked", async () => {
|
||||
const w = mount(ErrorPopup, { props: { show: true, message: "err" } });
|
||||
await w.find(".absolute.inset-0").trigger("click");
|
||||
expect(w.emitted("close")).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("emits close when OK button is clicked", async () => {
|
||||
const w = mount(ErrorPopup, { props: { show: true, message: "err" } });
|
||||
await w.find("button").trigger("click");
|
||||
expect(w.emitted("close")).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("displays Verbindungsfehler heading", () => {
|
||||
const w = mount(ErrorPopup, { props: { show: true, message: "x" } });
|
||||
expect(w.text()).toContain("Verbindungsfehler");
|
||||
});
|
||||
});
|
||||
58
src/components/ErrorPopup.vue
Normal file
58
src/components/ErrorPopup.vue
Normal file
@@ -0,0 +1,58 @@
|
||||
<script setup lang="ts">
|
||||
import LimelightButton from "./LimelightButton.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
message: string | null;
|
||||
show: boolean;
|
||||
title?: string;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "close"): void;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-if="show && message"
|
||||
class="fixed inset-0 z-50 flex items-center justify-center"
|
||||
>
|
||||
<!-- backdrop -->
|
||||
<div class="absolute inset-0 bg-black/60" @click="$emit('close')" />
|
||||
|
||||
<!-- popup -->
|
||||
<div
|
||||
class="relative bg-secondary border border-red-500/40 rounded-2xl p-5 max-w-sm w-[90%] shadow-xl"
|
||||
>
|
||||
<div class="flex items-center gap-3 mb-3">
|
||||
<div
|
||||
class="w-10 h-10 rounded-full bg-red/15 flex items-center justify-center"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 text-red"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M12 9v2m0 4h.01M10.29 3.86l-8.2 14A1.5 1.5 0 003.3 20h16.4a1.5 1.5 0 001.21-2.14l-8.2-14a1.5 1.5 0 00-2.42 0z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<p class="text-white font-semibold">{{ title ?? "Verbindungsfehler" }}</p>
|
||||
</div>
|
||||
|
||||
<p class="text-white/80 text-sm whitespace-pre-line">
|
||||
{{ message }}
|
||||
</p>
|
||||
|
||||
<LimelightButton variant="danger" class="mt-4 w-full" @click="$emit('close')">
|
||||
OK
|
||||
</LimelightButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -11,13 +11,13 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
variant?: 'primary' | 'outline' | 'ghost' | 'danger'
|
||||
disabled?: boolean
|
||||
}>()
|
||||
variant?: 'primary' | 'outline' | 'ghost' | 'danger';
|
||||
disabled?: boolean;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@import 'tailwindcss';
|
||||
@reference "tailwindcss";
|
||||
.btn {
|
||||
@apply h-10 text-sm;
|
||||
padding: 0 1.5rem;
|
||||
@@ -37,7 +37,7 @@ defineProps<{
|
||||
}
|
||||
.btn--primary {
|
||||
background: var(--color-primary);
|
||||
color: var(--color-secondary-dark);
|
||||
color: var(--color-black);
|
||||
}
|
||||
.btn--primary:hover {
|
||||
background: var(--color-primary-light);
|
||||
@@ -81,4 +81,8 @@ defineProps<{
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.btn--disabled:hover {
|
||||
transform: scale(1) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
1
src/env.d.ts
vendored
1
src/env.d.ts
vendored
@@ -1 +1,2 @@
|
||||
/// <reference path="./utils/filemaker.d.ts" />
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export { default as LimelightButton } from './components/LimelightButton.vue'
|
||||
export { default as ErrorPopup } from './components/ErrorPopup.vue'
|
||||
export * from './utils/webviewer'
|
||||
|
||||
5
src/main.ts
Normal file
5
src/main.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import './style.css'
|
||||
|
||||
createApp(App).mount('#app')
|
||||
2
src/style.css
Normal file
2
src/style.css
Normal file
@@ -0,0 +1,2 @@
|
||||
@import "tailwindcss";
|
||||
@import "../theme.css";
|
||||
@@ -11,6 +11,9 @@ export interface FileMakerAPI {
|
||||
declare global {
|
||||
/** Available only inside a FileMaker web viewer. Always guard with `typeof FileMaker !== 'undefined'`. */
|
||||
const FileMaker: FileMakerAPI | undefined
|
||||
interface Window {
|
||||
resolveFileMakerCallback: typeof resolveFileMakerCallback
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user