Add project documentation: User Manual and System Administration Guide
PDF documents with Mermaid diagrams, styled with purple theme. Includes build script for regenerating PDFs from Markdown sources. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ff9cdffc32
commit
8cbe01dfa6
5 changed files with 1887 additions and 0 deletions
492
docs/01-User-Manual.md
Normal file
492
docs/01-User-Manual.md
Normal file
|
|
@ -0,0 +1,492 @@
|
|||
---
|
||||
pdf_options:
|
||||
format: A4
|
||||
margin: 25mm 20mm
|
||||
headerTemplate: '<div style="font-size:8px;color:#999;width:100%;text-align:right;margin-right:20mm;">Oliver DeckForge — User Manual</div>'
|
||||
footerTemplate: '<div style="font-size:8px;color:#999;width:100%;text-align:center;"><span class="pageNumber"></span> / <span class="totalPages"></span></div>'
|
||||
displayHeaderFooter: true
|
||||
stylesheet:
|
||||
- https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.5.1/github-markdown.min.css
|
||||
body_class: markdown-body
|
||||
css: |-
|
||||
body { font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; }
|
||||
.markdown-body { max-width: 100%; }
|
||||
h1 { color: #5146E5; border-bottom: 3px solid #5146E5; padding-bottom: 8px; }
|
||||
h2 { color: #3b3494; border-bottom: 1px solid #E9E8F8; padding-bottom: 6px; margin-top: 2em; }
|
||||
h3 { color: #4a4a4a; }
|
||||
table { width: 100%; }
|
||||
th { background: #5146E5; color: white; }
|
||||
td, th { padding: 8px 12px; }
|
||||
code { background: #f0eff8; color: #5146E5; padding: 2px 6px; border-radius: 4px; }
|
||||
pre code { background: #1e1e2e; color: #cdd6f4; display: block; padding: 16px; border-radius: 8px; }
|
||||
blockquote { border-left: 4px solid #5146E5; background: #f8f7ff; padding: 12px 16px; margin: 16px 0; }
|
||||
.tip { border-left: 4px solid #22c55e; background: #f0fdf4; padding: 12px 16px; margin: 16px 0; border-radius: 0 8px 8px 0; }
|
||||
.warning { border-left: 4px solid #f59e0b; background: #fffbeb; padding: 12px 16px; margin: 16px 0; border-radius: 0 8px 8px 0; }
|
||||
img { max-width: 100%; max-height: 280px; object-fit: contain; display: block; margin: 16px auto; }
|
||||
---
|
||||
|
||||
# Oliver DeckForge User Manual
|
||||
|
||||
**Version 1.0** | Enterprise AI Presentation Generator
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Getting Started](#1-getting-started)
|
||||
2. [Dashboard](#2-dashboard)
|
||||
3. [Creating a Presentation](#3-creating-a-presentation)
|
||||
4. [Working with the Outline](#4-working-with-the-outline)
|
||||
5. [Selecting a Template](#5-selecting-a-template)
|
||||
6. [Generation Progress](#6-generation-progress)
|
||||
7. [Editing Slides](#7-editing-slides)
|
||||
8. [Review Workflow](#8-review-workflow)
|
||||
9. [Exporting Presentations](#9-exporting-presentations)
|
||||
10. [Keyboard Shortcuts & Tips](#10-keyboard-shortcuts--tips)
|
||||
|
||||
---
|
||||
|
||||
## 1. Getting Started
|
||||
|
||||
### 1.1 Logging In
|
||||
|
||||
Oliver DeckForge supports two authentication methods:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[Open App] --> B{Auth Mode?}
|
||||
B -->|Production| C[Azure AD SSO]
|
||||
B -->|Development| D[Email + Password]
|
||||
C --> E[Microsoft Login]
|
||||
E --> F[Dashboard]
|
||||
D --> F
|
||||
```
|
||||
|
||||
**Production Mode (Azure AD SSO):**
|
||||
Click **"Sign in with Microsoft"** and authenticate with your organization's Microsoft 365 credentials.
|
||||
|
||||
**Development Mode:**
|
||||
When Azure AD is not configured, a development login form appears. Enter:
|
||||
- **Email:** Your email address (e.g., `admin@deckforge.dev`)
|
||||
- **Password:** The development password (default: `devpass123`)
|
||||
|
||||
> After successful authentication, you are redirected to the Dashboard.
|
||||
|
||||
### 1.2 User Interface Overview
|
||||
|
||||
The application has two main areas:
|
||||
|
||||
| Area | Access | Purpose |
|
||||
|------|--------|---------|
|
||||
| **Presentation Generator** | All users | Create, edit, and export presentations |
|
||||
| **Admin Panel** | Admins only | Manage users, clients, templates, settings |
|
||||
|
||||
---
|
||||
|
||||
## 2. Dashboard
|
||||
|
||||
The dashboard is your home screen after logging in. What you see depends on your account configuration.
|
||||
|
||||
### 2.1 Client Grid View
|
||||
|
||||
If your account is associated with one or more clients, you see a grid of **client cards**:
|
||||
|
||||
- Each card displays the client's **name** and **logo**
|
||||
- Click a card to view that client's templates and presentations
|
||||
- Click **"New Presentation"** to start creating
|
||||
|
||||
### 2.2 Client Detail View
|
||||
|
||||
After selecting a client, two tabs appear:
|
||||
|
||||
**Templates Tab**
|
||||
- Shows all available master deck templates for this client
|
||||
- Each template card shows a **thumbnail**, **name**, **layout count**, and **status**
|
||||
- Click a template to start a new presentation with that template pre-selected
|
||||
|
||||
**Presentations Tab**
|
||||
- Lists all presentations created under this client
|
||||
- Each card shows:
|
||||
- Presentation **title**
|
||||
- **Status badge**: Draft (yellow), In Review (blue), Approved (green)
|
||||
- **Last updated** date
|
||||
- Click any card to open it in the editor
|
||||
|
||||
### 2.3 Quick Actions
|
||||
|
||||
| Action | How |
|
||||
|--------|-----|
|
||||
| Create new presentation | Click **"New Presentation"** button (top-right) |
|
||||
| Open existing presentation | Click on any presentation card |
|
||||
| Switch client | Click breadcrumb "All Clients" to go back to client grid |
|
||||
|
||||
---
|
||||
|
||||
## 3. Creating a Presentation
|
||||
|
||||
### 3.1 Workflow Overview
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[Upload Page] --> B{Input}
|
||||
B -->|Topic| C[Text]
|
||||
B -->|File| D[DOCX/PDF/PPTX]
|
||||
B -->|URL| E[Web]
|
||||
C --> F[Configure]
|
||||
D --> F
|
||||
E --> F
|
||||
F --> G[Outline] --> H[Template] --> I[Generate] --> J[Edit] --> K[Export]
|
||||
```
|
||||
|
||||
### 3.2 The Upload Page
|
||||
|
||||
Navigate to **Create Presentation** to see the upload page. You have three ways to provide content:
|
||||
|
||||
#### Option A: Topic or Text Prompt
|
||||
Type your presentation topic or detailed content in the large text area:
|
||||
|
||||
> **Example:** "Quarterly business review for Q3 2026, focusing on revenue growth, customer acquisition, and product roadmap milestones"
|
||||
|
||||
#### Option B: Upload Documents
|
||||
Drag and drop files into the upload zone, or click **"Choose Files"**:
|
||||
|
||||
| Format | Notes |
|
||||
|--------|-------|
|
||||
| `.docx` | Word documents — structured content with tables extracted |
|
||||
| `.pptx` | PowerPoint files — existing slides used as reference |
|
||||
| `.pdf` | PDF documents — text and layout extracted (max 1 PDF) |
|
||||
| `.txt` | Plain text files — raw content |
|
||||
|
||||
Multiple files can be uploaded simultaneously (except PDFs — only one allowed).
|
||||
|
||||
#### Option C: Paste a URL
|
||||
Enter a web URL to extract content from a web page. The system fetches and processes the page content automatically.
|
||||
|
||||
### 3.3 Configuration Options
|
||||
|
||||
Before generating, configure these settings:
|
||||
|
||||
**Slide Count**
|
||||
- Choose from presets: 5, 8, 10, 12, 15, or 20 slides
|
||||
- Or enter a custom number
|
||||
|
||||
**Language**
|
||||
- Select the output language from a searchable dropdown
|
||||
- Default: English
|
||||
|
||||
**Advanced Settings** (click the sliders icon):
|
||||
|
||||
| Setting | Options | Default |
|
||||
|---------|---------|---------|
|
||||
| **Tone** | Default, Professional, Casual, Funny, Academic | Default |
|
||||
| **Verbosity** | Concise, Standard, Detailed | Standard |
|
||||
| **Table of Contents** | On/Off | Off |
|
||||
| **Title Slide** | On/Off | On |
|
||||
| **Web Search** | On/Off — allows AI to search the web for fresh data | Off |
|
||||
| **Custom Instructions** | Free text to guide the AI | — |
|
||||
|
||||
> **Tip:** Custom instructions are powerful. Use them to specify audience, emphasize particular topics, or set formatting preferences.
|
||||
|
||||
### 3.4 Document Preview
|
||||
|
||||
If you uploaded documents, a **Document Preview** page appears next:
|
||||
|
||||
- **Left sidebar** lists all uploaded files
|
||||
- Click a file to preview its extracted content in the main area
|
||||
- Content is rendered as formatted Markdown
|
||||
- Click **"Next"** to proceed to the outline
|
||||
|
||||
---
|
||||
|
||||
## 4. Working with the Outline
|
||||
|
||||
The outline page shows the AI-generated structure for your presentation.
|
||||
|
||||
### 4.1 Outline View
|
||||
|
||||
Each slide appears as an editable card with:
|
||||
|
||||
- **Slide number** badge (left side)
|
||||
- **Content editor** — editable Markdown content
|
||||
- **Attached files** — badges showing which uploaded documents are linked to this slide
|
||||
- **Drag handle** — reorder slides by dragging
|
||||
- **Delete button** — remove a slide (trash icon, right side)
|
||||
|
||||
### 4.2 Editing the Outline
|
||||
|
||||
| Action | How |
|
||||
|--------|-----|
|
||||
| **Edit slide content** | Click into the text area and modify |
|
||||
| **Reorder slides** | Drag the handle (dots icon) on the left |
|
||||
| **Delete a slide** | Click the trash icon on the right |
|
||||
| **Add a new slide** | Click **"+ Add Slide"** at the bottom |
|
||||
|
||||
### 4.3 Streaming Indicator
|
||||
|
||||
While the AI is generating the outline:
|
||||
- A **"Thinking"** spinner appears
|
||||
- Content streams in real-time with animation
|
||||
- The active slide auto-scrolls into view
|
||||
- Editing is disabled until streaming completes
|
||||
|
||||
> **Note:** Wait for streaming to finish before making edits to avoid conflicts.
|
||||
|
||||
---
|
||||
|
||||
## 5. Selecting a Template
|
||||
|
||||
Switch to the **"Select Template"** tab on the outline page.
|
||||
|
||||
### 5.1 Built-in Templates
|
||||
|
||||
Pre-configured templates ship with the system. Each card shows:
|
||||
- Template **name** and **description**
|
||||
- Preview images of 4 sample layouts
|
||||
- A **"Selected"** badge on the active choice
|
||||
|
||||
### 5.2 Custom AI Templates
|
||||
|
||||
If your organization has uploaded master decks (PPTX files parsed by AI), they appear under **"Custom AI Templates"**:
|
||||
- Shows the master deck **thumbnail** and **name**
|
||||
- Contains layouts specifically designed for your brand
|
||||
|
||||
### 5.3 Generating the Presentation
|
||||
|
||||
1. Select a template (border turns blue)
|
||||
2. Click **"Generate Presentation"** at the bottom
|
||||
3. You are redirected to the progress page
|
||||
|
||||
> **Important:** You must select a template before the Generate button becomes active.
|
||||
|
||||
---
|
||||
|
||||
## 6. Generation Progress
|
||||
|
||||
### 6.1 Progress Screen
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Processing
|
||||
Processing --> Completed: All slides generated
|
||||
Processing --> Failed: Error occurred
|
||||
Completed --> Editor: Auto-redirect (1.5s)
|
||||
Failed --> Outline: User clicks Retry
|
||||
```
|
||||
|
||||
The progress page shows:
|
||||
- **Status icon**: Animated hamster wheel (processing), green check (done), or red X (failed)
|
||||
- **Progress bar** with percentage
|
||||
- **Status message** describing the current step
|
||||
|
||||
### 6.2 Actions During Generation
|
||||
|
||||
| Status | Available Actions |
|
||||
|--------|-------------------|
|
||||
| **Processing** | **Cancel** — stops the job, returns to outline |
|
||||
| **Completed** | **Open Presentation** — auto-opens after 1.5 seconds |
|
||||
| **Failed** | **Retry** — returns to outline to try again |
|
||||
|
||||
### 6.3 Connection Method
|
||||
|
||||
The progress page uses **Server-Sent Events (SSE)** for real-time updates. If SSE fails, it falls back to **polling** every 3 seconds.
|
||||
|
||||
---
|
||||
|
||||
## 7. Editing Slides
|
||||
|
||||
### 7.1 Editor Layout
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph Editor
|
||||
A[Left Sidebar<br/>Slide Thumbnails] --- B[Main Content<br/>Slide Preview]
|
||||
end
|
||||
subgraph Header
|
||||
C[Logo] --- D[Actions<br/>Undo/Redo/Export]
|
||||
end
|
||||
```
|
||||
|
||||
The presentation editor has:
|
||||
- **Header bar** (purple) with actions
|
||||
- **Left sidebar** with slide thumbnails
|
||||
- **Main area** with full-size slide previews
|
||||
|
||||
### 7.2 Sidebar Navigation
|
||||
|
||||
Toggle between two views:
|
||||
- **Grid view** — thumbnail previews of all slides
|
||||
- **List view** — slide numbers and titles
|
||||
|
||||
Click any slide to navigate to it. Drag to reorder.
|
||||
|
||||
### 7.3 Slide Actions
|
||||
|
||||
Hover over any slide to reveal action overlays:
|
||||
|
||||
| Position | Action | Description |
|
||||
|----------|--------|-------------|
|
||||
| **Top-left** | Update slide | Opens prompt input — describe changes and AI regenerates |
|
||||
| **Top-right** | Delete slide | Removes the slide |
|
||||
| **Top-right** | Speaker notes | View/edit speaker notes for this slide |
|
||||
| **Bottom-center** | Add slide | Insert a new slide below this one |
|
||||
|
||||
### 7.4 AI-Powered Slide Updates
|
||||
|
||||
1. Hover over a slide
|
||||
2. Click the **magic wand** icon (top-left)
|
||||
3. Enter your update prompt (e.g., "Add a chart showing quarterly revenue")
|
||||
4. Click **"Update"**
|
||||
5. The AI regenerates the slide content based on your instructions
|
||||
|
||||
> **Note:** Updates may take 30–120 seconds depending on content complexity and image generation.
|
||||
|
||||
### 7.5 Auto-Save
|
||||
|
||||
The editor automatically saves your changes. A spinning icon in the header indicates a save is in progress.
|
||||
|
||||
---
|
||||
|
||||
## 8. Review Workflow
|
||||
|
||||
### 8.1 Status Flow
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
direction LR
|
||||
Draft --> InReview: Submit for Review
|
||||
InReview --> Approved: Approve
|
||||
InReview --> Draft: Return to Draft
|
||||
Approved --> Draft: Reopen
|
||||
```
|
||||
|
||||
Every presentation has a review status:
|
||||
|
||||
| Status | Badge Color | Meaning |
|
||||
|--------|-------------|---------|
|
||||
| **Draft** | Yellow | Work in progress — not reviewed |
|
||||
| **In Review** | Blue | Submitted for review — awaiting approval |
|
||||
| **Approved** | Green | Reviewed and approved — ready for use |
|
||||
|
||||
### 8.2 Changing Status
|
||||
|
||||
1. Click the **status badge** in the editor header
|
||||
2. A popover appears with:
|
||||
- Current status display
|
||||
- Last review comment (if any)
|
||||
- Available status transition buttons
|
||||
- Comment text area
|
||||
|
||||
### 8.3 Adding Review Comments
|
||||
|
||||
1. Open the status popover
|
||||
2. Type a comment in the text area
|
||||
3. Click **"Add Comment"**
|
||||
|
||||
Comments are saved and visible to all users who access the presentation.
|
||||
|
||||
### 8.4 Status Transitions
|
||||
|
||||
| Current Status | Available Actions |
|
||||
|----------------|-------------------|
|
||||
| **Draft** | Submit to **In Review** |
|
||||
| **In Review** | **Approve** or return to **Draft** |
|
||||
| **Approved** | Return to **Draft** |
|
||||
|
||||
---
|
||||
|
||||
## 9. Exporting Presentations
|
||||
|
||||
### 9.1 Export Options
|
||||
|
||||
Click **"Export"** in the editor header to see options:
|
||||
|
||||
| Format | Description |
|
||||
|--------|-------------|
|
||||
| **PDF** | High-quality PDF document, one slide per page |
|
||||
| **PPTX** | PowerPoint file, editable in Microsoft PowerPoint |
|
||||
|
||||
### 9.2 Export Process
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as User
|
||||
participant E as Editor
|
||||
participant S as Server
|
||||
participant P as Puppeteer
|
||||
|
||||
U->>E: Click Export
|
||||
E->>E: Auto-save presentation
|
||||
E->>S: Request export
|
||||
S->>P: Render slides in headless browser
|
||||
P->>S: Return rendered output
|
||||
S->>E: File ready
|
||||
E->>U: Download starts
|
||||
```
|
||||
|
||||
1. Click **"Export as PDF"** or **"Export as PPTX"**
|
||||
2. The system auto-saves your latest changes
|
||||
3. A loading overlay appears: **"Exporting presentation..."**
|
||||
4. The rendered file downloads automatically
|
||||
|
||||
> **Note:** Export may take 15–60 seconds depending on slide count and image complexity.
|
||||
|
||||
---
|
||||
|
||||
## 10. Keyboard Shortcuts & Tips
|
||||
|
||||
### 10.1 Tips for Better Presentations
|
||||
|
||||
<div class="tip">
|
||||
|
||||
**Be specific in your prompt.** Instead of "Make a sales presentation," try: "Create a 12-slide sales pitch for enterprise CRM software targeting Fortune 500 IT directors, emphasizing ROI and integration capabilities."
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tip">
|
||||
|
||||
**Use Custom Instructions wisely.** Add rules like: "Use bullet points, not paragraphs. Keep each slide to 3-4 key points. Include data visualizations where possible."
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tip">
|
||||
|
||||
**Upload reference documents.** The AI produces significantly better content when given source material like reports, briefs, or existing presentations to draw from.
|
||||
|
||||
</div>
|
||||
|
||||
<div class="warning">
|
||||
|
||||
**Image generation may fail silently.** If a slide shows a placeholder instead of a generated image, check the slide content for an image error indicator. Try updating the slide with a more specific image description.
|
||||
|
||||
</div>
|
||||
|
||||
### 10.2 Troubleshooting
|
||||
|
||||
| Problem | Solution |
|
||||
|---------|----------|
|
||||
| Export fails | Refresh the page and try again. Ensure the presentation has been saved. |
|
||||
| Slide update hangs | Wait up to 2 minutes. If still loading, refresh and retry. |
|
||||
| Outline won't generate | Check that you've entered content or uploaded at least one document. |
|
||||
| Template not showing | Ask your admin to verify the master deck has been fully parsed. |
|
||||
| Images missing | Image generation may be disabled or the provider API key may be invalid. Contact your admin. |
|
||||
| Cannot log in | Verify your credentials. In dev mode, check the `DEV_AUTH_PASSWORD` setting. |
|
||||
|
||||
### 10.3 Browser Requirements
|
||||
|
||||
Oliver DeckForge works best with:
|
||||
- **Google Chrome** 90+
|
||||
- **Microsoft Edge** 90+
|
||||
- **Firefox** 90+
|
||||
- **Safari** 15+
|
||||
|
||||
> JavaScript must be enabled. A stable internet connection is required for AI generation.
|
||||
|
||||
---
|
||||
|
||||
<div style="text-align: center; margin-top: 60px; color: #999;">
|
||||
|
||||
**Oliver DeckForge** | Enterprise AI Presentation Generator
|
||||
|
||||
Version 1.0 | © 2026 All Rights Reserved
|
||||
|
||||
</div>
|
||||
BIN
docs/01-User-Manual.pdf
Normal file
BIN
docs/01-User-Manual.pdf
Normal file
Binary file not shown.
1333
docs/02-System-Administration-Guide.md
Normal file
1333
docs/02-System-Administration-Guide.md
Normal file
File diff suppressed because it is too large
Load diff
BIN
docs/02-System-Administration-Guide.pdf
Normal file
BIN
docs/02-System-Administration-Guide.pdf
Normal file
Binary file not shown.
62
docs/build-pdfs.mjs
Normal file
62
docs/build-pdfs.mjs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* Build script for Oliver DeckForge documentation PDFs.
|
||||
*
|
||||
* 1. Renders Mermaid diagrams to PNG via @mermaid-js/mermaid-cli (mmdc)
|
||||
* 2. Converts the resulting Markdown (with images) to styled PDFs via md-to-pdf
|
||||
* 3. Cleans up intermediate files
|
||||
*
|
||||
* Usage: node docs/build-pdfs.mjs
|
||||
*/
|
||||
|
||||
import { execSync } from 'child_process';
|
||||
import { readdirSync, unlinkSync, existsSync } from 'fs';
|
||||
import { join, dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const sources = [
|
||||
'01-User-Manual.md',
|
||||
'02-System-Administration-Guide.md',
|
||||
];
|
||||
|
||||
for (const file of sources) {
|
||||
const input = join(__dirname, file);
|
||||
const rendered = join(__dirname, file.replace('.md', '-rendered.md'));
|
||||
const renderedPdf = rendered.replace('.md', '.pdf');
|
||||
const finalPdf = join(__dirname, file.replace('.md', '.pdf'));
|
||||
|
||||
console.log(`\n=== ${file} ===`);
|
||||
|
||||
// 1. Pre-render Mermaid diagrams → PNG, output modified markdown
|
||||
console.log(' [1/3] Rendering Mermaid diagrams...');
|
||||
execSync(
|
||||
`npx -y @mermaid-js/mermaid-cli -i "${input}" -o "${rendered}" -e png --scale 2`,
|
||||
{ cwd: __dirname, stdio: 'inherit' },
|
||||
);
|
||||
|
||||
// 2. Convert rendered markdown → PDF
|
||||
console.log(' [2/3] Converting to PDF...');
|
||||
execSync(`npx -y md-to-pdf "${rendered}"`, {
|
||||
cwd: __dirname,
|
||||
stdio: 'inherit',
|
||||
});
|
||||
|
||||
// 3. Move PDF to final name and clean up temp files
|
||||
console.log(' [3/3] Cleaning up...');
|
||||
execSync(`mv "${renderedPdf}" "${finalPdf}"`);
|
||||
|
||||
// Remove rendered markdown
|
||||
if (existsSync(rendered)) unlinkSync(rendered);
|
||||
|
||||
// Remove generated diagram PNGs
|
||||
const prefix = file.replace('.md', '-rendered-');
|
||||
readdirSync(__dirname)
|
||||
.filter((f) => f.startsWith(prefix) && f.endsWith('.png'))
|
||||
.forEach((f) => unlinkSync(join(__dirname, f)));
|
||||
|
||||
console.log(` -> ${file.replace('.md', '.pdf')} created`);
|
||||
}
|
||||
|
||||
console.log('\nDone.');
|
||||
Loading…
Add table
Reference in a new issue