first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:35:24 +03:00
commit bbbf76b184
592 changed files with 246870 additions and 0 deletions

46
.dockerignore Normal file
View File

@@ -0,0 +1,46 @@
# Git
.git
.gitignore
# IDEs
.vscode
.idea
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
# Build artifacts
main
*.exe
*.test
*.out
# Logs
*.log
server.log
app_routes.log
# Local dev
.env.local
.env.development
# Uploads (will be mounted as volume)
uploads/*
!uploads/.gitkeep
# Documentation
*.md
!README.md
belgeler/CHANGELOG.md
*.txt
# Test files
*_test.go
# Temporary files
tmp/
temp/

87
.env Normal file
View File

@@ -0,0 +1,87 @@
# Application Port Configuration
PORT=8080
#########################
# PostgreSQL Configuration
DB_URL=host=10.80.80.70 user=cloud password=gg7678290 dbname=atahan_go port=5432 sslmode=disable TimeZone=Europe/Istanbul
DB_USER=cloud
DB_PASSWORD=gg7678290
DB_NAME=atahan_go
DB_PORT=5432
DB_HOST=10.80.80.70
##########################
# Redis Configuration
REDIS_HOST=10.80.80.70
REDIS_PORT=6379
REDIS_USER=default
REDIS_PASSWORD=gg7678290
REDIS_URL=redis://default:gg7678290@10.80.80.70:6379/0
###########################
# JWT Secret
JWT_SECRET=eCT286MautyK9TWfz8SPSIWJTXV83mwLRwriLvSbpcMZuDLxywaHWP9Ju7xRoTS2
# Session Secret (for OAuth state management)
SESSION_SECRET=kL8mN2pQ5rS9tV1wX4yZ7aB0cD3eF6gH9jK2mN5pQ8rS1tV4wX7yZ0aB3cD6eF9g
###########################
# Application URL
APP_URL=http://localhost:8080
###########################
# OAuth - Google
GOOGLE_CLIENT_ID=915364976256-691m0s87as2r5vdbqr96f6humblseobt.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=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
################################
# OAuth - GitHub
GITHUB_CLIENT_ID=Ov23liUt9B61O46Mdfm4
GITHUB_CLIENT_SECRET=c7fc8dcb1b2c8f22120608425d07d5efd995baaf
################################
# OAuth Callback URL (Backend OAuth callback endpoint)
CLIENT_CALLBACK_URL=http://localhost:8080/v1/auth
# OAuth Redirect URL (Frontend callback page where user will be redirected with tokens)
OAUTH_REDIRECT_URL=http://localhost:3000/auth/callback
################################
# AVATANE IMAGES
AVATAR_H=150
AVATAR_W=150
AVATAR_Q=90
AVATAR_B=cover
AVATAR_F=webp
#######################
# Home IMAGES
HOME_IMAGE_H=400
HOME_IMAGE_W=400
HOME_IMAGE_Q=90
HOME_IMAGE_B=cover
HOME_IMAGE_F=webp
#######################
# Aboutme IMAGES
ABOUTME_IMAGE_H=400
ABOUTME_IMAGE_W=400
ABOUTME_IMAGE_Q=90
ABOUTME_IMAGE_B=cover
ABOUTME_IMAGE_F=webp
#######################
# MyService IMAGES
SERVICE_IMAGE_H=256
SERVICE_IMAGE_W=256
SERVICE_IMAGE_Q=90
SERVICE_IMAGE_B=cover
SERVICE_IMAGE_F=webp
#######################
# BANNER IMAGES
BANNER_IMAGE_H=700
BANNER_IMAGE_W=1920
BANNER_IMAGE_Q=85
BANNER_IMAGE_B=cover
BANNER_IMAGE_F=webp
################################
# Email Settings (Mailpit)
EMAIL_HOST=212.64.215.243
EMAIL_PORT=1025
EMAIL_HOST_USER=""
EMAIL_HOST_PASSWORD=""
EMAIL_USE_TLS=false
EMAIL_USE_SSL=false
EMAIL_FROM=noreply@gauth.local
################################
CORS_DEBUG=true
VITE_API_BASE_URL=http://localhost:8080
FRONTEND_URL=http://localhost:3000
# SESSION_SECRET=mTFY2jAOMWWxadVIWjRoPG9aOM3z9srCVoU35Gs1VZaRKgXet26cztUE8LLpwok9

34
.env.example Normal file
View File

@@ -0,0 +1,34 @@
# Server Configuration
PORT=8080
# PostgreSQL Configuration
DB_URL="host=localhost user=postgres password=yourpassword dbname=gauth port=5432 sslmode=disable TimeZone=Europe/Istanbul"
DB_USER=postgres
DB_PASSWORD=yourpassword
DB_NAME=gauth
DB_PORT=5432
DB_HOST=localhost
# Redis Configuration
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_USER=default
REDIS_PASSWORD=yourpassword
REDIS_URL=redis://default:yourpassword@localhost:6379/0
# JWT Secret
JWT_SECRET=your_super_secret_jwt_key_change_this_in_production
# Application URL
APP_URL=http://localhost:8080
# OAuth - Google
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
# OAuth - GitHub
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
# OAuth Callback URL
CLIENT_CALLBACK_URL=http://localhost:8080/v1/auth

61
.env.production.example Normal file
View File

@@ -0,0 +1,61 @@
# Application Port Configuration
PORT=8080
#########################
# PostgreSQL Configuration
DB_HOST=postgres
DB_USER=postgres
DB_PASSWORD=your_secure_password_here
DB_NAME=gauth
DB_PORT=5432
DB_URL=host=postgres user=postgres password=your_secure_password_here dbname=gauth port=5432 sslmode=disable TimeZone=Europe/Istanbul
##########################
# Redis Configuration
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_USER=default
REDIS_PASSWORD=your_redis_password_here
REDIS_URL=redis://redis:6379/0
###########################
# JWT Secret
JWT_SECRET=your_super_secret_jwt_key_change_this_in_production
###########################
# Application URL
APP_URL=https://yourdomain.com
###########################
# OAuth - Google
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
################################
# OAuth - GitHub
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
################################
# OAuth Callback URL
CLIENT_CALLBACK_URL=https://yourdomain.com/api/v1/auth
################################
# Avatar Settings - WebP optimized
AVATAR_H=150
AVATAR_W=150
AVATAR_Q=90
AVATAR_B=cover
AVATAR_F=webp
################################
# Email Settings
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_HOST_USER=your_email@gmail.com
EMAIL_HOST_PASSWORD=your_app_password
EMAIL_USE_TLS=true
EMAIL_USE_SSL=false
EMAIL_FROM=noreply@yourdomain.com
################################

30
.gitignore vendored Normal file
View File

@@ -0,0 +1,30 @@
### Go template
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
go_build_gauth_central
main
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# Go workspace file
go.work
go.work.sum
# Uploaded files
uploads/
# Build binary
main

10
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,10 @@
# Default ignored files
/shelf/
/workspace.xml
# Ignored default folder with query files
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

9
.idea/atahango.iml generated Normal file
View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/copilot.data.migration.agent.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AgentMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>

6
.idea/copilot.data.migration.ask.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AskMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Ask2AgentMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>

6
.idea/copilot.data.migration.edit.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EditMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>

11
.idea/go.imports.xml generated Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GoImports">
<option name="excludedPackages">
<array>
<option value="github.com/pkg/errors" />
<option value="golang.org/x/net/context" />
</array>
</option>
</component>
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/atahango.iml" filepath="$PROJECT_DIR$/.idea/atahango.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

43
Dockerfile Normal file
View File

@@ -0,0 +1,43 @@
# Build Stage
FROM golang:1.25.6-alpine AS builder
WORKDIR /app
# Install build dependencies including libwebp
RUN apk add --no-cache git gcc musl-dev libwebp-dev
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# Fix missing entries in go.sum (run after COPY to fix overwritten files)
RUN go mod tidy
RUN k=$(ls -la) && echo "$k"
# Install swag
RUN go install github.com/swaggo/swag/cmd/swag@latest
# Generate swagger docs
RUN swag init
# Build the binary with CGO enabled for WebP support
RUN CGO_ENABLED=1 GOOS=linux go build -a -ldflags '-linkmode external -extldflags "-static"' -o main .
# Run Stage
FROM alpine:latest
WORKDIR /app
# Install runtime dependencies: CA certificates and libwebp
RUN apk --no-cache add ca-certificates libwebp
COPY --from=builder /app/main .
COPY --from=builder /app/.env .
COPY --from=builder /app/web ./web
COPY --from=builder /app/docs ./docs
# Note: .env might be overridden by docker-compose environment
EXPOSE 8080
CMD ["./main"]

76
GEMINI.md Normal file
View File

@@ -0,0 +1,76 @@
# Proje: GAuth-Central (Go-Gin Merkezi Kimlik Doğrulama Servisi)
## 1. Proje Özeti
Bu proje, birden fazla istemci uygulama (backend) için merkezi bir kimlik doğrulama ve yetkilendirme (Identity Provider) hizmeti sunar. Go (Gin Framework) ile geliştirilecek olan bu servis; klasik e-posta kaydı, Google ve GitHub OAuth2 girişlerini yönetir ve başarılı giriş sonrası JWT (JSON Web Token) üretir.
## 2. Teknoloji Yığını
- **Dil:** Go 1.25.7 (Golang)
- **Web Framework:** Gin Gonic
- **Veritabanı:** PostgreSQL (GORM üzerinden)
- **Kimlik Doğrulama:**
- JWT (github.com/golang-jwt/jwt/v5)
- OAuth2 (golang.org/x/oauth2 ve github.com/markbates/goth)
- **Güvenlik:** Bcrypt (şifre hashleme), CORS, Rate Limiting.
## 3. Klasör Yapısı
```text
/atahango
├── /api
│ ├── /handlers # HTTP istek işleyicileri
│ ├── /middlewares # JWT ve Auth kontrolleri
│ └── /routes # Route tanımları
├── /config # Env ve Konfigürasyon yönetimi
├── /internal
│ ├── /models # DB Modelleri (User, SocialAccount)
│ ├── /services # Auth ve JWT iş mantığı
│ └── /database # DB Bağlantısı ve Migration
├── /pkg # Yardımcı araçlar (utils)
├── .env # Gizli anahtarlar
├── go.mod
└── main.go
```
## 4. Veritabanı Modeli (GORM)
- **User:** `ID`, `Email`, `Password` (hash), `CreatedAt`, `UpdatedAt`.
- **SocialAccount:** `ID`, `UserID` (FK), `Provider` (google/github), `ProviderID`, `Email`.
## 5. API Uç Noktaları (Endpoints)
### Klasik Auth
- `POST /v1/auth/register`: E-posta ve şifre ile kayıt.
- `POST /v1/auth/login`: E-posta ve şifre ile giriş -> JWT döner.
### OAuth2 (Social Login)
- `GET /v1/auth/:provider`: (google/github) Kullanıcıyı ilgili platforma yönlendirir.
- `GET /v1/auth/:provider/callback`: Platformdan dönen veriyi işler, kullanıcıyı DB'de eşleştirir/oluşturur -> JWT döner.
### Doğrulama ve Yönetim
- `GET /v1/auth/validate`: İstemci uygulama (Django) bu endpoint'e JWT gönderir, servis kullanıcı bilgilerini doğrular.
- `POST /v1/auth/refresh`: Refresh token ile yeni Access Token üretimi.
## 6. JWT Tasarımı
- **Payload:**
```json
{
"sub": "user_uuid",
"email": "user@example.com",
"exp": 1738500000,
"iss": "gauth-central"
}
```
- **İmzalama:** HS256 veya RS256 algoritması kullanılmalıdır.
## 7. İstemci Entegrasyon Mantığı (Örn: Django)
1. Django, kullanıcıyı `GAuth/v1/auth/google` adresine yönlendirir.
2. GAuth işlemi tamamlar ve kullanıcıyı Django'nun callback URL'ine bir `?token=...` query parametresi ile geri gönderir.
3. Django, bu token'ı alır ve kendi session'ını oluşturmak için GAuth'un `/v1/auth/validate` servisini kullanır.
## 8. Gemini İçin Talimatlar (Implementation Rules)
- Kodları modüler yaz (Handlers, Services, Models ayrımı).
- `.env` dosyasından `CLIENT_ID`, `CLIENT_SECRET` ve `JWT_SECRET` okumayı unutma.
- Hata yönetimini (Error Handling) profesyonelce yap ve JSON formatında hata mesajları dön.
- CORS ayarlarını tüm istemciler (Django vb.) için yapılandırılabilir kıl.
- `github.com/markbates/goth` kütüphanesini kullanarak multi-provider desteğini uygula.
---
**Not:** Bu dosya projenin teknik rehberidir. Kod üretim aşamasında bu mimariye sadık kalınmalıdır.

26
Public.txt Normal file
View File

@@ -0,0 +1,26 @@
Public
/v1/post-categories
/v1/post-categories/:slug
/v1/post-categories/:id/views
/v1/post-tags
/v1/posts (opsiyonel front=true)
/v1/posts/:slug
/v1/posts/:id/comments
Hepsi routes.go:131-145 icinde.
Auth (korumali yorum ekleme)
/v1/posts/:id/comments (POST)
routes.go:176-181
Admin (JWT + AdminMiddleware)
/v1/admin/post-categories (GET/POST)
/v1/admin/post-categories/:id (GET/PUT/DELETE)
/v1/admin/post-tags (GET/POST)
/v1/admin/post-tags/:id (GET/PUT/DELETE)
/v1/admin/posts (GET/POST)
/v1/admin/posts/:id (GET/PUT/DELETE)
/v1/admin/post-comments (GET)
/v1/admin/post-comments/:id (GET/PUT/DELETE)
/v1/admin/post-category-views (GET, category_id query)
Hepsi routes.go:279-322 icinde.

229
README.md Normal file
View File

@@ -0,0 +1,229 @@
# GAuth-Central - Centralized Authentication Service
Modern, ölçeklenebilir ve güvenli bir kimlik doğrulama servisi. PostgreSQL ve Redis ile desteklenir.
## 🚀 Özellikler
- ✅ JWT tabanlı kimlik doğrulama
- ✅ OAuth2 entegrasyonu (Google, GitHub)
- ✅ Email doğrulama
- ✅ Redis ile session yönetimi ve caching
- ✅ PostgreSQL ile veri saklama
- ✅ Rate limiting
- ✅ Token blacklist (logout)
- ✅ CORS desteği
- ✅ Swagger/OpenAPI dokümantasyonu
- ✅ Docker & Docker Compose desteği
## 📋 Gereksinimler
- Go 1.25+
- PostgreSQL 17+
- Redis 7+
- Docker & Docker Compose (opsiyonel)
## 🛠️ Kurulum
### 1. Repository'yi klonlayın
```bash
git clone <repository-url>
cd atahango
```
### 2. Environment dosyasını ayarlayın
```bash
cp .env.example .env
# .env dosyasını kendi ayarlarınıza göre düzenleyin
```
### 3. Bağımlılıkları yükleyin
```bash
go mod download
```
### 4a. Standalone Mode (Mevcut PostgreSQL & Redis kullanarak)
Eğer zaten çalışan PostgreSQL ve Redis sunucularınız varsa:
```bash
# .env dosyasında DB_URL ve REDIS_URL'i ayarlayın
# Örnek:
# DB_URL="host=10.80.80.70 user=cloud password=xxx dbname=go_gauth port=5432 sslmode=disable"
# REDIS_URL=redis://default:xxx@10.80.80.70:6379/0
# Uygulamayı başlat
./start.sh
# veya manuel
go run main.go
```
### 4b. Docker ile çalıştırma
```bash
# Tüm servisleri başlat (PostgreSQL, Redis, App)
docker-compose up -d
# Logları takip et
docker-compose logs -f app
```
### 4b. Docker ile çalıştırma
Docker ile tüm servisleri (PostgreSQL, Redis, App) birlikte başlatmak için:
```bash
# Tüm servisleri başlat (PostgreSQL, Redis, App)
docker-compose up -d
# Logları takip et
docker-compose logs -f app
```
### 5. Bağlantı Testi
```bash
# API sağlık kontrolü
curl http://localhost:8080/
# Swagger dokümantasyonu
open http://localhost:8080/docs/index.html
```
## 🔧 Yapılandırma
### Environment Variables
| Değişken | Açıklama | Örnek |
|----------------------|------------------------------|-----------------------------------------------------------------------------------|
| `PORT` | Uygulama portu | `8080` |
| `DB_URL` | PostgreSQL bağlantı string'i | `host=localhost user=postgres password=pass dbname=gauth port=5432 sslmode=disable` |
| `REDIS_URL` | Redis bağlantı URL'i | `redis://default:password@localhost:6379/0` |
| `JWT_SECRET` | JWT için gizli anahtar | `your_secret_key` |
| `GOOGLE_CLIENT_ID` | Google OAuth Client ID | \- |
| `GOOGLE_CLIENT_SECRET` | Google OAuth Client Secret | \- |
| `GITHUB_CLIENT_ID` | GitHub OAuth Client ID | \- |
| `GITHUB_CLIENT_SECRET` | GitHub OAuth Client Secret | \- |
| `CLIENT_CALLBACK_URL` | OAuth callback URL | `http://localhost:8080/v1/auth` |
## 📚 API Dokümantasyonu
Swagger UI: `http://localhost:8080/docs/index.html`
### Temel Endpoint'ler
#### Authentication
- `POST /v1/auth/register` - Yeni kullanıcı kaydı
- `POST /v1/auth/login` - Kullanıcı girişi
- `GET /v1/auth/verify-email` - Email doğrulama
- `POST /v1/auth/refresh` - Token yenileme
- `GET /v1/auth/:provider` - OAuth ile giriş (google, github)
- `GET /v1/auth/:provider/callback` - OAuth callback
#### Protected Routes (Authorization gerekli)
- `GET /v1/auth/me` - Kullanıcı bilgilerini getir
- `GET /v1/auth/validate` - Token doğrulama
## 🗄️ Veritabanı Yapısı
### PostgreSQL Tables
- `users` - Kullanıcı bilgileri
- `social_accounts` - OAuth hesap bağlantıları
- `roles` - Kullanıcı rolleri
- `permissions` - İzinler
### Redis Cache Keys
- `user:{id}` - Kullanıcı cache
- `session:{token}` - Session yönetimi
- `blacklist:{token}` - Token blacklist
- `ratelimit:{key}` - Rate limiting
- `email_verify:{email}` - Email doğrulama token'ları
- `password_reset:{email}` - Şifre sıfırlama token'ları
## 🔒 Güvenlik
- Şifreler bcrypt ile hashlenmiş olarak saklanır
- JWT token'lar Authorization header'da Bearer token olarak gönderilir
- CORS politikaları yapılandırılmıştır
- Rate limiting Redis ile yönetilir
- Logout sonrası token'lar blacklist'e eklenir
## 🐳 Docker Compose
Uygulama 3 servis ile çalışır:
1. **PostgreSQL** - Ana veritabanı (Port: 5432)
2. **Redis** - Cache ve session store (Port: 6379)
3. **App** - Go backend (Port: 8080)
```bash
# Servisleri başlat
docker-compose up -d
# Servisleri durdur
docker-compose down
# Volume'ları da sil
docker-compose down -v
```
## 🧪 Development
### Swagger Docs Güncelleme
```bash
# Swagger dokümantasyonunu güncelle
swag init -g main.go
```
### Database Migration
Uygulama ilk çalıştırıldığında otomatik olarak migration yapar ve seed data'yı ekler.
## 📝 Cache Service Kullanımı
```go
cacheService := services.NewCacheService()
// Kullanıcı cache
cacheService.SetUser(userID, user, 1*time.Hour)
user, err := cacheService.GetUser(userID)
// Session
cacheService.SetSession(token, userID, 24*time.Hour)
userID, err := cacheService.GetSession(token)
// Rate limiting
count, err := cacheService.IncrementRateLimit("login:"+ip, 1*time.Minute)
// Token blacklist
cacheService.BlacklistToken(token, 24*time.Hour)
isBlacklisted, err := cacheService.IsTokenBlacklisted(token)
```
## 🤝 Contributing
1. Fork the project
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
## 📄 License
This project is licensed under the MIT License.
## 👨‍💻 Author
GAuth-Central Team
---
⭐ Bu projeyi beğendiyseniz yıldız vermeyi unutmayın!

1
admin-panel/.env Normal file
View File

@@ -0,0 +1 @@
VITE_API_BASE_URL=http://localhost:8080

24
admin-panel/.gitignore vendored Normal file
View File

@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

25
admin-panel/Dockerfile Normal file
View File

@@ -0,0 +1,25 @@
# Build Stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
ARG VITE_API_BASE_URL
ENV VITE_API_BASE_URL=$VITE_API_BASE_URL
RUN npm run build
# Production Stage
FROM node:20-alpine
WORKDIR /app
RUN npm install -g serve
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["serve", "-s", "dist", "-l", "3000"]

73
admin-panel/README.md Normal file
View File

@@ -0,0 +1,73 @@
# React + TypeScript + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
## React Compiler
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
## Expanding the ESLint configuration
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
```js
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Remove tseslint.configs.recommended and replace with this
tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
tseslint.configs.stylisticTypeChecked,
// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```
You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
```js
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```

View File

@@ -0,0 +1,20 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/index.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
}
}

View File

@@ -0,0 +1,23 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { defineConfig, globalIgnores } from 'eslint/config'
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
},
])

13
admin-panel/index.html Normal file
View File

@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>admin-panel</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

6533
admin-panel/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

66
admin-panel/package.json Normal file
View File

@@ -0,0 +1,66 @@
{
"name": "admin-panel",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@hookform/resolvers": "^5.2.2",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.8",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-separator": "^1.1.8",
"@radix-ui/react-slider": "^1.3.6",
"@radix-ui/react-slot": "^1.2.4",
"@radix-ui/react-switch": "^1.2.6",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-toast": "^1.2.15",
"@tanstack/react-query": "^5.90.20",
"@tinymce/tinymce-react": "^6.3.0",
"autoprefixer": "^10.4.24",
"axios": "^1.13.4",
"class-variance-authority": "^0.7.1",
"classnames": "^2.5.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"date-fns": "^4.1.0",
"form-data": "^4.0.5",
"i18next": "^25.8.4",
"lucide-react": "^0.563.0",
"postcss": "^8.5.6",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-hook-form": "^7.71.1",
"react-i18next": "^16.5.4",
"react-router-dom": "^7.13.0",
"sweetalert2": "^11.26.18",
"sweetalert2-react-content": "^5.1.1",
"tailwind-merge": "^3.4.0",
"tailwindcss": "^3.4.17",
"tinymce": "^8.3.2",
"zod": "^4.3.6"
},
"devDependencies": {
"@eslint/js": "^9.39.1",
"@types/node": "^24.10.11",
"@types/react": "^19.2.5",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.1",
"eslint": "^9.39.1",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.24",
"globals": "^16.5.0",
"tailwindcss-animate": "^1.0.7",
"typescript": "~5.9.3",
"typescript-eslint": "^8.46.4",
"vite": "^7.2.4"
}
}

View File

@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,77 @@
# TinyMCE
The world's #1 open source rich text editor.
**Using an old version of TinyMCE?** We recommend you to upgrade to TinyMCE 8 to continue receiving security updates.
Used and trusted by millions of developers, TinyMCE is the worlds most customizable, scalable, and flexible rich text editor. Weve helped launch the likes of Atlassian, Medium, Evernote (and lots more that we cant tell you), by empowering them to create exceptional content and experiences for their users.
With more than 350M+ downloads every year, were also one of the most trusted enterprise-grade open source HTML editors on the internet. Theres currently more than 100M+ products worldwide, powered by Tiny. As a high powered WYSIWYG editor, TinyMCE is built to scale, designed to innovate, and thrives on delivering results to difficult edge-cases.
You can access a [full featured demo of TinyMCE](https://www.tiny.cloud/docs/tinymce/8/premium-full-featured/) in the docs on the TinyMCE website.
<p align="center">
<img alt="Screenshot of the TinyMCE Editor" src="https://www.tiny.cloud/storage/github-readme-images/tinymce-editor-6x.png"\>
</p>
## Get started with TinyMCE
Getting started with the TinyMCE rich text editor is easy, and for simple configurations can be done in less than 5 minutes.
[TinyMCE Cloud Deployment Quick Start Guide](https://www.tiny.cloud/docs/tinymce/8/cloud-quick-start/)
[TinyMCE Self-hosted Deployment Guide](https://www.tiny.cloud/docs/tinymce/8/npm-projects/)
TinyMCE provides a range of configuration options that allow you to integrate it into your application. Start customizing with a [basic setup](https://www.tiny.cloud/docs/tinymce/8/basic-setup/).
Configure it for one of three modes of editing:
- [TinyMCE classic editing mode](https://www.tiny.cloud/docs/tinymce/8/use-tinymce-classic/).
- [TinyMCE inline editing mode](https://www.tiny.cloud/docs/tinymce/8/use-tinymce-inline/).
- [TinyMCE distraction-free editing mode](https://www.tiny.cloud/docs/tinymce/8/use-tinymce-distraction-free/).
## Features
### Integration
TinyMCE is easily integrated into your projects with the help of components such as:
- [tinymce-react](https://github.com/tinymce/tinymce-react)
- [tinymce-vue](https://github.com/tinymce/tinymce-vue)
- [tinymce-angular](https://github.com/tinymce/tinymce-angular)
With over 29 integrations, and 400+ APIs, see the TinyMCE docs for a full list of editor [integrations](https://www.tiny.cloud/docs/tinymce/8/integrations/).
### Customization
It is easy to [configure the UI](https://www.tiny.cloud/docs/tinymce/8/customize-ui/) of your rich text editor to match the design of your site, product or application. Due to its flexibility, you can [configure the editor](https://www.tiny.cloud/docs/tinymce/8/basic-setup/) with as much or as little functionality as you like, depending on your requirements.
With [50+ powerful plugins available](https://www.tiny.cloud/tinymce/features/), and content editable as the basis of TinyMCE, adding additional functionality is as simple as including a single line of code.
Realizing the full power of most plugins requires only a few lines more.
### Extensibility
Sometimes your editor requirements can be quite unique, and you need the freedom and flexibility to innovate. Thanks to TinyMCE being open source, you can view the source code and develop your own extensions for custom functionality to meet your own requirements.
The TinyMCE [API](https://www.tiny.cloud/docs/tinymce/8/apis/tinymce.root/) is exposed to make it easier for you to write custom functionality that fits within the existing framework of TinyMCE [UI components](https://www.tiny.cloud/docs/tinymce/8/custom-ui-components/).
### Extended Features and Support
For the professional software teams that require more in-depth efficiency, compliance or collaborative features built to enterprise-grade standards, please [get in touch with our team](https://www.tiny.cloud/contact/).
Tiny also offers dedicated SLAs and support for professional development teams.
## Compiling and contributing
In 2019 the decision was made to transition our codebase to a monorepo. For information on compiling and contributing, see: [contribution guidelines](https://github.com/tinymce/tinymce/blob/master/CONTRIBUTING.md).
As an open source product, we encourage and support the active development of our software.
## Want more information?
Visit the [TinyMCE website](https://tiny.cloud/) and check out the [TinyMCE documentation](https://www.tiny.cloud/docs/).
## License
License terms can be found in the license.md file.

View File

@@ -0,0 +1,27 @@
{
"name": "tinymce",
"description": "Web based JavaScript HTML WYSIWYG editor control.",
"license": "SEE LICENSE IN license.md",
"keywords": [
"wysiwyg",
"tinymce",
"richtext",
"javascript",
"html",
"text",
"rich editor",
"rich text editor",
"rte",
"rich text",
"contenteditable",
"editing"
],
"homepage": "https://www.tiny.cloud/",
"ignore": [
"README.md",
"composer.json",
"package.json",
".npmignore",
"CHANGELOG.md"
]
}

View File

@@ -0,0 +1,52 @@
{
"name": "tinymce/tinymce",
"version": "8.3.2",
"description": "Web based JavaScript HTML WYSIWYG editor control.",
"license": [
"SEE LICENSE IN license.md"
],
"keywords": [
"wysiwyg",
"tinymce",
"richtext",
"javascript",
"html",
"text",
"rich editor",
"rich text editor",
"rte",
"rich text",
"contenteditable",
"editing"
],
"homepage": "https://www.tiny.cloud/",
"type": "component",
"extra": {
"component": {
"scripts": [
"tinymce.js",
"plugins/*/plugin.js",
"themes/*/theme.js",
"models/*/model.js",
"icons/*/icons.js"
],
"files": [
"tinymce.min.js",
"plugins/*/plugin.min.js",
"themes/*/theme.min.js",
"models/*/model.min.js",
"skins/**",
"icons/*/icons.min.js"
]
}
},
"archive": {
"exclude": [
"README.md",
"bower.js",
"package.json",
".npmignore",
"CHANGELOG.md"
]
}
}

View File

@@ -0,0 +1,239 @@
tinymce.IconManager.add('default', {
icons: {
'accessibility-check': '<svg width="24" height="24"><path d="M12 2a2 2 0 0 1 2 2 2 2 0 0 1-2 2 2 2 0 0 1-2-2c0-1.1.9-2 2-2Zm8 7h-5v12c0 .6-.4 1-1 1a1 1 0 0 1-1-1v-5c0-.6-.4-1-1-1a1 1 0 0 0-1 1v5c0 .6-.4 1-1 1a1 1 0 0 1-1-1V9H4a1 1 0 1 1 0-2h16c.6 0 1 .4 1 1s-.4 1-1 1Z" fill-rule="nonzero"/></svg>',
'accordion-toggle': '<svg width="24" height="24"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 15c0-.6.4-1 1-1h6c.6 0 1 .4 1 1s-.4 1-1 1h-6a1 1 0 0 1-1-1Z"/><path opacity=".2" fill-rule="evenodd" clip-rule="evenodd" d="M4 15c0-.6.4-1 1-1h6c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1-1-1Z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M12 19c0-.6.4-1 1-1h6c.6 0 1 .4 1 1s-.4 1-1 1h-6a1 1 0 0 1-1-1Z"/><path opacity=".2" fill-rule="evenodd" clip-rule="evenodd" d="M4 19c0-.6.4-1 1-1h6c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1-1-1Z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M12.3 7.3a1 1 0 0 1 1.4 0L16 9.6l2.3-2.3a1 1 0 1 1 1.4 1.4L16 12.4l-3.7-3.7a1 1 0 0 1 0-1.4ZM4.3 11.7a1 1 0 0 1 0-1.4L6.6 8 4.3 5.7a1 1 0 0 1 1.4-1.4L9.4 8l-3.7 3.7a1 1 0 0 1-1.4 0Z"/></svg>',
'accordion': '<svg width="24" height="24"><rect x="12" y="7" width="10" height="2" rx="1"/><rect x="12" y="11" width="10" height="2" rx="1"/><rect x="12" y="15" width="6" height="2" rx="1"/><path fill-rule="evenodd" clip-rule="evenodd" d="M2.3 7.3a1 1 0 0 1 1.4 0L6 9.6l2.3-2.3a1 1 0 0 1 1.4 1.4L6 12.4 2.3 8.7a1 1 0 0 1 0-1.4Z"/></svg>',
'action-next': '<svg width="24" height="24"><path fill-rule="nonzero" d="M5.7 7.3a1 1 0 0 0-1.4 1.4l7.7 7.7 7.7-7.7a1 1 0 1 0-1.4-1.4L12 13.6 5.7 7.3Z"/></svg>',
'action-prev': '<svg width="24" height="24"><path fill-rule="nonzero" d="M18.3 15.7a1 1 0 0 0 1.4-1.4L12 6.6l-7.7 7.7a1 1 0 0 0 1.4 1.4L12 9.4l6.3 6.3Z"/></svg>',
'add-file': '<svg height="24" width="24"><path d="M2 7h2V4h3V2H4a2 2 0 0 0-2 2zm20 0h-2V4h-3V2h3a2 2 0 0 1 2 2zm0 2h-2v6h2zm0 8h-2v3h-3v2h3a2 2 0 0 0 2-2zM2 9h2v6H2zm0 8h2v3h3v2H4a2 2 0 0 1-2-2zm7 5v-2h6v2zm6-20v2H9V2zM6 17h12l-4-5-3 3.8-2-2.6z"/><path d="M2 7h2V4h3V2H4a2 2 0 0 0-2 2zm20 0h-2V4h-3V2h3a2 2 0 0 1 2 2zm0 2h-2v6h2zm0 8h-2v3h-3v2h3a2 2 0 0 0 2-2zM2 9h2v6H2zm0 8h2v3h3v2H4a2 2 0 0 1-2-2zm7 5v-2h6v2zm6-20v2H9V2zM6 17h12l-4-5-3 3.8-2-2.6z"/><path d="M6 17h12l-4-5-3 3.8-2-2.6z"/><path d="M6 17h12l-4-5-3 3.8-2-2.6z"/><path d="M6 17h12l-4-5-3 3.8-2-2.6z"/><path d="M6 17h12l-4-5-3 3.8-2-2.6z"/></svg>',
'addtag': '<svg width="24" height="24"><path fill-rule="evenodd" clip-rule="evenodd" d="M15 5a2 2 0 0 1 1.6.8L21 12l-4.4 6.2a2 2 0 0 1-1.6.8h-3v-2h3l3.5-5L15 7H5v3H3V7c0-1.1.9-2 2-2h10Z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M6 12a1 1 0 0 0-1 1v2H3a1 1 0 1 0 0 2h2v2a1 1 0 1 0 2 0v-2h2a1 1 0 1 0 0-2H7v-2c0-.6-.4-1-1-1Z"/></svg>',
'adjustments': '<svg width="24" height="24"><path d="M16 11a3 3 0 1 1 2.8-4H21v2h-2.2a3 3 0 0 1-2.8 2Zm0-2a1 1 0 1 1 0-2 1 1 0 0 1 0 2ZM3 9h8V7H3v2Zm5 10a3 3 0 1 0-2.8-4H3v2h2.2A3 3 0 0 0 8 19Zm0-2a1 1 0 1 0 0-2 1 1 0 0 0 0 2Zm13 0h-8v-2h8v2Z"/></svg>',
'ai-prompt': '<svg width="24" height="24"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M15 6.7a1 1 0 0 0-1.4 0l-9.9 10a1 1 0 0 0 0 1.3l2.1 2.1c.4.4 1 .4 1.4 0l10-9.9c.3-.3.3-1 0-1.4l-2.2-2Zm1.4 2.8-2-2-3 2.7 2.2 2.2 2.8-2.9Z"/><path d="m18.5 7.3-.7-1.5-1.5-.8 1.5-.7.7-1.5.7 1.5 1.5.7-1.5.8-.7 1.5ZM18.5 16.5l-.7-1.6-1.5-.7 1.5-.7.7-1.6.7 1.6 1.5.7-1.5.7-.7 1.6ZM9.7 7.3 9 5.8 7.5 5 9 4.3l.7-1.5.7 1.5L12 5l-1.5.8-.7 1.5Z"/></g><defs><clipPath id="a"><path d="M0 0h24v24H0z"/></clipPath></defs></svg>',
'ai': '<svg width="24" height="24"><path fill-rule="evenodd" clip-rule="evenodd" d="M5 3a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3V6a3 3 0 0 0-3-3H5Zm6.8 11.5.5 1.2a68.3 68.3 0 0 0 .7 1.1l.4.1c.3 0 .5 0 .7-.3.2-.1.3-.3.3-.6l-.3-1-2.6-6.2a20.4 20.4 0 0 0-.5-1.3l-.5-.4-.7-.2c-.2 0-.5 0-.6.2-.2 0-.4.2-.5.4l-.3.6-.3.7L5.7 15l-.2.6-.1.4c0 .3 0 .5.3.7l.6.2c.3 0 .5 0 .7-.2l.4-1 .5-1.2h3.9ZM9.8 9l1.5 4h-3l1.5-4Zm5.6-.9v7.6c0 .4 0 .7.2 1l.7.2c.3 0 .6 0 .8-.3l.2-.9V8.1c0-.4 0-.7-.2-.9a1 1 0 0 0-.8-.3c-.2 0-.5.1-.7.3l-.2 1Z"/></svg>',
'align-center': '<svg width="24" height="24"><path d="M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2Zm3 4h8c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 1 1 0-2Zm0 8h8c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 0 1 0-2Zm-3-4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2Z" fill-rule="evenodd"/></svg>',
'align-justify': '<svg width="24" height="24"><path d="M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2Zm0 4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2Zm0 4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2Zm0 4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2Z" fill-rule="evenodd"/></svg>',
'align-left': '<svg width="24" height="24"><path d="M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2Zm0 4h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2Zm0 8h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2Zm0-4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2Z" fill-rule="evenodd"/></svg>',
'align-none': '<svg width="24" height="24"><path d="M14.2 5 13 7H5a1 1 0 1 1 0-2h9.2Zm4 0h.8a1 1 0 0 1 0 2h-2l1.2-2Zm-6.4 4-1.2 2H5a1 1 0 0 1 0-2h6.8Zm4 0H19a1 1 0 0 1 0 2h-4.4l1.2-2Zm-6.4 4-1.2 2H5a1 1 0 0 1 0-2h4.4Zm4 0H19a1 1 0 0 1 0 2h-6.8l1.2-2ZM7 17l-1.2 2H5a1 1 0 0 1 0-2h2Zm4 0h8a1 1 0 0 1 0 2H9.8l1.2-2Zm5.2-13.5 1.3.7-9.7 16.3-1.3-.7 9.7-16.3Z" fill-rule="evenodd"/></svg>',
'align-right': '<svg width="24" height="24"><path d="M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2Zm6 4h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2Zm0 8h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2Zm-6-4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2Z" fill-rule="evenodd"/></svg>',
'alt-text': '<svg width="24" height="24"><path d="M3 20a2 2 0 0 1-1.4-.6A2 2 0 0 1 1 18V6c0-.6.2-1 .6-1.4A2 2 0 0 1 3 4h18c.6 0 1 .2 1.4.6.4.4.6.9.6 1.4v12c0 .6-.2 1-.6 1.4a2 2 0 0 1-1.4.6H3Zm0-2h18V6H3v12Zm1.5-3H6v-1.5h1.5V15H9v-5a1 1 0 0 0-.3-.7A1 1 0 0 0 8 9H5.5a1 1 0 0 0-.7.3 1 1 0 0 0-.3.7v5ZM6 12v-1.5h1.5V12H6Z"/><path d="M11 15V9h1.3v4.5h2V15H11Zm5.8-4.5V15h1.4v-4.5h1.3V9h-4v1.5h1.3Z"/></svg>',
'arrow-left': '<svg width="24" height="24"><path d="m5.6 13 12 6a1 1 0 0 0 1.4-1V6a1 1 0 0 0-1.4-.9l-12 6a1 1 0 0 0 0 1.8Z" fill-rule="evenodd"/></svg>',
'arrow-right': '<svg width="24" height="24"><path d="m18.5 13-12 6A1 1 0 0 1 5 18V6a1 1 0 0 1 1.4-.9l12 6a1 1 0 0 1 0 1.8Z" fill-rule="evenodd"/></svg>',
'auto-image-enhancement': '<svg width="24" height="24"><path d="M7.7 10.6a5.8 5.8 0 0 0 5.7 5.7A5.8 5.8 0 0 0 7.7 22 5.8 5.8 0 0 0 2 16.3a5.8 5.8 0 0 0 5.7-5.7ZM15.5 2c.3 3 3.3 6 6.5 6.4-3.2.5-6.2 3.4-6.5 6.5-.3-3.4-3-6-6.4-6.5 3.3-.5 6.1-3 6.4-6.4Z"/></svg>',
'blur': '<svg width="24" height="24"><path d="M19.3 9.3a1 1 0 0 0-.3.7c0 .3.1.5.3.7.2.2.4.3.7.3s.5-.1.7-.3a1 1 0 0 0 .3-.7 1 1 0 0 0-.3-.7A1 1 0 0 0 20 9a1 1 0 0 0-.7.3Zm-16 0a1 1 0 0 0-.3.7c0 .3.1.5.3.7.2.2.4.3.7.3s.5-.1.7-.3A1 1 0 0 0 5 10a1 1 0 0 0-.3-.7A1 1 0 0 0 4 9a1 1 0 0 0-.7.3Zm16 6a1 1 0 0 0-.3.7c0 .3.1.5.3.7.2.2.4.3.7.3s.5-.1.7-.3a1 1 0 0 0 .3-.7 1 1 0 0 0-.3-.7 1 1 0 0 0-.7-.3 1 1 0 0 0-.7.3Zm-16 0a1 1 0 0 0-.3.7c0 .3.1.5.3.7.2.2.4.3.7.3s.5-.1.7-.3A1 1 0 0 0 5 16a1 1 0 0 0-.3-.7A1 1 0 0 0 4 15a1 1 0 0 0-.7.3Zm5-11A1 1 0 0 0 8 5a1 1 0 0 0 1 1c.3 0 .5-.1.7-.3A1 1 0 0 0 10 5a1 1 0 0 0-.3-.7A1 1 0 0 0 9 4a1 1 0 0 0-.7.3Zm6 0a1 1 0 0 0-.3.7 1 1 0 0 0 1 1c.3 0 .5-.1.7-.3A1 1 0 0 0 16 5a1 1 0 0 0-.3-.7A1 1 0 0 0 15 4a1 1 0 0 0-.7.3Zm-6 16a1 1 0 0 0-.3.7c0 .3.1.5.3.7.2.2.4.3.7.3s.5-.1.7-.3a1 1 0 0 0 .3-.7 1 1 0 0 0-.3-.7A1 1 0 0 0 9 20a1 1 0 0 0-.7.3Zm6 0a1 1 0 0 0-.3.7c0 .3.1.5.3.7.2.2.4.3.7.3s.5-.1.7-.3a1 1 0 0 0 .3-.7 1 1 0 0 0-.3-.7 1 1 0 0 0-.7-.3 1 1 0 0 0-.7.3ZM7.6 8.6A2 2 0 0 0 7 10c0 .6.2 1 .6 1.4.4.4.8.6 1.4.6s1-.2 1.4-.6c.4-.4.6-.8.6-1.4s-.2-1-.6-1.4A2 2 0 0 0 9 8a2 2 0 0 0-1.4.6Zm0 6A2 2 0 0 0 7 16c0 .6.2 1 .6 1.4.4.4.8.6 1.4.6s1-.2 1.4-.6c.4-.4.6-.8.6-1.4s-.2-1-.6-1.4A2 2 0 0 0 9 14a2 2 0 0 0-1.4.6Zm6-6A2 2 0 0 0 13 10c0 .6.2 1 .6 1.4.4.4.8.6 1.4.6s1-.2 1.4-.6c.4-.4.6-.8.6-1.4s-.2-1-.6-1.4A2 2 0 0 0 15 8a2 2 0 0 0-1.4.6Zm0 6A2 2 0 0 0 13 16c0 .6.2 1 .6 1.4.4.4.8.6 1.4.6s1-.2 1.4-.6c.4-.4.6-.8.6-1.4s-.2-1-.6-1.4A2 2 0 0 0 15 14a2 2 0 0 0-1.4.6Z"/></svg>',
'bold': '<svg width="24" height="24"><path d="M7.8 19c-.3 0-.5 0-.6-.2l-.2-.5V5.7c0-.2 0-.4.2-.5l.6-.2h5c1.5 0 2.7.3 3.5 1 .7.6 1.1 1.4 1.1 2.5a3 3 0 0 1-.6 1.9c-.4.6-1 1-1.6 1.2.4.1.9.3 1.3.6s.8.7 1 1.2c.4.4.5 1 .5 1.6 0 1.3-.4 2.3-1.3 3-.8.7-2.1 1-3.8 1H7.8Zm5-8.3c.6 0 1.2-.1 1.6-.5.4-.3.6-.7.6-1.3 0-1.1-.8-1.7-2.3-1.7H9.3v3.5h3.4Zm.5 6c.7 0 1.3-.1 1.7-.4.4-.4.6-.9.6-1.5s-.2-1-.7-1.4c-.4-.3-1-.4-2-.4H9.4v3.8h4Z" fill-rule="evenodd"/></svg>',
'bookmark': '<svg width="24" height="24"><path d="M6 4v17l6-4 6 4V4c0-.6-.4-1-1-1H7a1 1 0 0 0-1 1Z" fill-rule="nonzero"/></svg>',
'border-style': '<svg width="24" height="24"><g fill-rule="evenodd"><rect width="18" height="2" x="3" y="6" rx="1"/><rect width="2.8" height="2" x="3" y="16" rx="1"/><rect width="2.8" height="2" x="6.8" y="16" rx="1"/><rect width="2.8" height="2" x="10.6" y="16" rx="1"/><rect width="2.8" height="2" x="14.4" y="16" rx="1"/><rect width="2.8" height="2" x="18.2" y="16" rx="1"/><rect width="8" height="2" x="3" y="11" rx="1"/><rect width="8" height="2" x="13" y="11" rx="1"/></g></svg>',
'border-width': '<svg width="24" height="24"><g fill-rule="evenodd"><rect width="18" height="5" x="3" y="5" rx="1"/><rect width="18" height="3.5" x="3" y="11.5" rx="1"/><rect width="18" height="2" x="3" y="17" rx="1"/></g></svg>',
'box': '<svg width="24" height="24"><path d="M3.8 7a1 1 0 0 0-.7.6l-.1 3V13.8a3.5 3.5 0 0 0 4 2.7c.8-.2 1.4-.5 2-1l.3-.3.3.2c.7.7 1.4 1 2.4 1.1 1.2 0 2.4-.6 3-1.6.9-1.2.8-2.8 0-4a3.7 3.7 0 0 0-2-1.2c-.4-.1-1.2-.1-1.6 0a3.4 3.4 0 0 0-1.7 1l-.3.2-.2-.1c-.4-.5-1.2-1-2-1.1-.6-.2-1.5 0-2 .2H5V9c0-1.3 0-1.3-.3-1.6a1 1 0 0 0-1-.3Zm12 2.6c-.3.2-.5.4-.6.8v.6l.9 1 .7 1v.1l-.8 1-.7 1a1 1 0 0 0 0 .7 1 1 0 0 0 1.3.6c.2 0 .3-.2 1-1l.5-.7.6.8.7.8c.4.3 1 .3 1.3 0l.2-.3a1 1 0 0 0 0-.8l-.8-1.2-.7-1a26 26 0 0 0 1.5-2 .8.8 0 0 0 .1-.4c0-.4-.1-.7-.5-.9H20c-.4 0-.5 0-1.2.8l-.7.8-.6-.7-.7-.9a1 1 0 0 0-1 0Zm-9 2 .4.1c.3.1.6.5.7.8l.1.6v.6c-.6 1-2 1.2-2.7.3-.3-.3-.3-.5-.3-1v-.5c.3-.5.7-.8 1.1-1a1.5 1.5 0 0 1 .7 0Zm5.7 0c.4 0 .8.4 1 .8l.2.6-.1.7c-.5.9-1.6 1.1-2.4.6a1.4 1.4 0 0 1-.6-1.1 1.4 1.4 0 0 1 .5-1.2 1.5 1.5 0 0 1 1.4-.4Z"/></svg>',
'brightness': '<svg width="24" height="24"><path d="M12.7 18.3a1 1 0 0 0-.7-.3 1 1 0 0 0-.7.3 1 1 0 0 0-.3.7v1a1 1 0 0 0 .3.7 1 1 0 0 0 .7.3 1 1 0 0 0 .7-.3 1 1 0 0 0 .3-.7v-1a1 1 0 0 0-.3-.7ZM11.3 5.7a1 1 0 0 0 .7.3 1 1 0 0 0 .7-.3A1 1 0 0 0 13 5V4a1 1 0 0 0-.3-.7A1 1 0 0 0 12 3a1 1 0 0 0-.7.3 1 1 0 0 0-.3.7v1a1 1 0 0 0 .3.7Zm9.4 5.6a1 1 0 0 0-.7-.3h-1a1 1 0 0 0-.7.3 1 1 0 0 0-.3.7 1 1 0 0 0 .3.7 1 1 0 0 0 .7.3h1a1 1 0 0 0 .7-.3 1 1 0 0 0 .3-.7 1 1 0 0 0-.3-.7Zm-15 1.4A1 1 0 0 0 6 12a1 1 0 0 0-.3-.7A1 1 0 0 0 5 11H4a1 1 0 0 0-.7.3 1 1 0 0 0-.3.7 1 1 0 0 0 .3.7 1 1 0 0 0 .7.3h1a1 1 0 0 0 .7-.3Zm13 4.6-.7-.8a1 1 0 0 0-.8-.3 1 1 0 0 0-.7.3 1 1 0 0 0-.3.7 1 1 0 0 0 .3.8l.7.7a1 1 0 0 0 .7.3 1 1 0 0 0 .8-.3 1 1 0 0 0 .3-.8 1 1 0 0 0-.3-.7ZM5.3 6.7l.7.8a1 1 0 0 0 .8.3 1 1 0 0 0 .7-.3 1 1 0 0 0 .3-.7 1 1 0 0 0-.3-.8l-.7-.7A1 1 0 0 0 6 5a1 1 0 0 0-.8.3 1 1 0 0 0-.3.8 1 1 0 0 0 .3.6Zm12 1a1 1 0 0 0 .7-.2l.7-.7A1 1 0 0 0 19 6a1 1 0 0 0-.3-.8 1 1 0 0 0-.8-.3 1 1 0 0 0-.7.3l-.7.7a1 1 0 0 0-.3.8 1 1 0 0 0 .3.7 1 1 0 0 0 .7.2ZM6.7 16.4a1 1 0 0 0-.8.2l-.7.7a1 1 0 0 0-.3.7 1 1 0 0 0 .3.8 1 1 0 0 0 .8.3 1 1 0 0 0 .7-.3l.7-.7a1 1 0 0 0 .3-.8 1 1 0 0 0-.3-.7 1 1 0 0 0-.7-.3Z"/><path fill-rule="evenodd" d="M13.6 8.3A4 4 0 0 0 12 8a4 4 0 0 0-1.6.3A4 4 0 0 0 9 9.5a4 4 0 0 0-.6 1A4 4 0 0 0 8 12c0 .6.1 1 .3 1.6a4 4 0 0 0 2.1 2 4 4 0 0 0 1.6.4 4 4 0 0 0 1.6-.3 4 4 0 0 0 2-2.1A4 4 0 0 0 16 12a4 4 0 0 0-.3-1.6 4 4 0 0 0-2.1-2ZM14 12a2 2 0 1 1-4 0 2 2 0 0 1 4 0Z"/></svg>',
'browse': '<svg width="24" height="24"><path d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-4v-2h4V8H5v10h4v2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14Zm-8 9.4-2.3 2.3a1 1 0 1 1-1.4-1.4l4-4a1 1 0 0 1 1.4 0l4 4a1 1 0 0 1-1.4 1.4L13 13.4V20a1 1 0 0 1-2 0v-6.6Z" fill-rule="nonzero"/></svg>',
'camera': '<svg height="24" width="24"><g clip-rule="evenodd" fill-rule="evenodd"><path d="M10 5.4a1 1 0 0 1 .8-.4h4.4a1 1 0 0 1 .8.4l1.2 1.8h2.3A2.5 2.5 0 0 1 22 9.6v8a2.5 2.5 0 0 1-2.5 2.5h-13A2.5 2.5 0 0 1 4 17.6v-8a2.5 2.5 0 0 1 2.5-2.4h2.3zM11.4 7l-1.2 1.7a1 1 0 0 1-.8.5h-3a.5.5 0 0 0-.4.4v8a.5.5 0 0 0 .5.5h13a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.4h-2.9a1 1 0 0 1-.8-.5L14.6 7z"/><path d="M13 11.4a2 2 0 1 0 0 3.8 2 2 0 0 0 0-3.8zm-4 1.9a4 4 0 1 1 8 0 4 4 0 0 1-8 0z"/></g></svg>',
'cancel': '<svg width="24" height="24"><path d="M12 4.6a7.4 7.4 0 1 1 0 14.8 7.4 7.4 0 0 1 0-14.8ZM12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18Zm0 8L14.8 8l1 1.1-2.7 2.8 2.7 2.7-1.1 1.1-2.7-2.7-2.7 2.7-1-1.1 2.6-2.7-2.7-2.7 1-1.1 2.8 2.7Z" fill-rule="nonzero"/></svg>',
'caption': '<svg height="24" width="24"><path d="M6 16h8v-2H6zm10 0h2v-2h-2zM4 20a2 2 0 0 1-1.5-.6A2 2 0 0 1 2 18V6c0-.6.2-1 .6-1.4A2 2 0 0 1 4 4h16c.6 0 1 .2 1.4.6.4.4.6.9.6 1.4v12c0 .6-.2 1-.6 1.4a2 2 0 0 1-1.4.6zm0-2h16V6H4z"/></svg>',
'cell-background-color': '<svg width="24" height="24"><path d="m15.7 2 1.6 1.6-2.7 2.6 5.9 5.8c.7.7.7 1.7 0 2.4l-6.3 6.1a1.7 1.7 0 0 1-2.4 0l-6.3-6.1c-.7-.7-.7-1.7 0-2.4L15.7 2ZM18 12l-4.5-4L9 12h9ZM4 16s2 2.4 2 3.8C6 21 5.1 22 4 22s-2-1-2-2.2C2 18.4 4 16 4 16Z"/></svg>',
'cell-border-color': '<svg width="24" height="24"><g fill-rule="evenodd"><path fill-rule="nonzero" d="M5 13v5h2v2H5a2 2 0 0 1-2-2v-5h2zm8-7V4h6a2 2 0 0 1 2 2h-8z" opacity=".2"/><path fill-rule="nonzero" d="M13 4v2H5v7H3V6c0-1.1.9-2 2-2h8zm-2.6 14.1.1-.1.1.1.2.3.2.2.2.2c.4.6.8 1.2.8 1.7 0 .8-.7 1.5-1.5 1.5S9 21.3 9 20.5c0-.5.4-1.1.8-1.7l.2-.2.2-.2.2-.3z"/><path d="m13 11-2 2H5v-2h6V6h2z"/><path fill-rule="nonzero" d="m18.4 8 1 1-1.8 1.9 4 4c.5.4.5 1.1 0 1.6l-4.3 4.2a1.2 1.2 0 0 1-1.6 0l-4.4-4.2c-.4-.5-.4-1.2 0-1.7l7-6.8Zm1.6 7-3-3-3 3h6Z"/></g></svg>',
'change-case': '<svg width="24" height="24"><path d="M18.4 18.2v-.6c-.5.8-1.3 1.2-2.4 1.2-2.2 0-3.3-1.6-3.3-4.8 0-3.1 1-4.7 3.3-4.7 1.1 0 1.8.3 2.4 1.1v-.6c0-.5.4-.8.8-.8s.8.3.8.8v8.4c0 .5-.4.8-.8.8a.8.8 0 0 1-.8-.8zm-2-7.4c-1.3 0-1.8.9-1.8 3.2 0 2.4.5 3.3 1.7 3.3 1.3 0 1.8-.9 1.8-3.2 0-2.4-.5-3.3-1.7-3.3zM10 15.7H5.5l-.8 2.6a1 1 0 0 1-1 .7h-.2a.7.7 0 0 1-.7-1l4-12a1 1 0 0 1 2 0l4 12a.7.7 0 0 1-.8 1h-.2a1 1 0 0 1-1-.7l-.8-2.6zm-.3-1.5-2-6.5-1.9 6.5h3.9z" fill-rule="evenodd"/></svg>',
'character-count': '<svg width="24" height="24"><path d="M4 11.5h16v1H4v-1Zm4.8-6.8V10H7.7V5.8h-1v-1h2ZM11 8.3V9h2v1h-3V7.7l2-1v-.9h-2v-1h3v2.4l-2 1Zm6.3-3.4V10h-3.1V9h2.1V8h-2.1V6.8h2.1v-1h-2.1v-1h3.1ZM5.8 16.4c0-.5.2-.8.5-1 .2-.2.6-.3 1.2-.3l.8.1c.2 0 .4.2.5.3l.4.4v2.8l.2.3H8.2V18.7l-.6.3H7c-.4 0-.7 0-1-.2a1 1 0 0 1-.3-.9c0-.3 0-.6.3-.8.3-.2.7-.4 1.2-.4l.6-.2h.3v-.2l-.1-.2a.8.8 0 0 0-.5-.1 1 1 0 0 0-.4 0l-.3.4h-1Zm2.3.8h-.2l-.2.1-.4.1a1 1 0 0 0-.4.2l-.2.2.1.3.5.1h.4l.4-.4v-.6Zm2-3.4h1.2v1.7l.5-.3h.5c.5 0 .9.1 1.2.5.3.4.5.8.5 1.4 0 .6-.2 1.1-.5 1.5-.3.4-.7.6-1.3.6l-.6-.1-.4-.4v.4h-1.1v-5.4Zm1.1 3.3c0 .3 0 .6.2.8a.7.7 0 0 0 1.2 0l.2-.8c0-.4 0-.6-.2-.8a.7.7 0 0 0-.6-.3l-.6.3-.2.8Zm6.1-.5c0-.2 0-.3-.2-.4a.8.8 0 0 0-.5-.2c-.3 0-.5.1-.6.3l-.2.9c0 .3 0 .6.2.8.1.2.3.3.6.3.2 0 .4 0 .5-.2l.2-.4h1.1c0 .5-.3.8-.6 1.1a2 2 0 0 1-1.3.4c-.5 0-1-.2-1.3-.6a2 2 0 0 1-.5-1.4c0-.6.1-1.1.5-1.5.3-.4.8-.5 1.4-.5.5 0 1 0 1.2.3.4.3.5.7.5 1.2h-1v-.1Z" fill-rule="evenodd"/></svg>',
'checklist-rtl': '<svg width="24" height="24"><path d="M5 17h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm14.2 11c.2-.4.6-.5.9-.3.3.2.4.6.2 1L18 20c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8zm0-6c.2-.4.6-.5.9-.3.3.2.4.6.2 1L18 14c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8zm0-6c.2-.4.6-.5.9-.3.3.2.4.6.2 1L18 8c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8z" fill-rule="evenodd"/></svg>',
'checklist': '<svg width="24" height="24"><path d="M11 17h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2Zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2Zm0-6h8a1 1 0 0 1 0 2h-8a1 1 0 0 1 0-2ZM7.2 16c.2-.4.6-.5.9-.3.3.2.4.6.2 1L6 20c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8Zm0-6c.2-.4.6-.5.9-.3.3.2.4.6.2 1L6 14c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8Zm0-6c.2-.4.6-.5.9-.3.3.2.4.6.2 1L6 8c-.2.3-.7.4-1 0L3.8 6.9a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8Z" fill-rule="evenodd"/></svg>',
'checkmark-filled': '<svg width="24" height="24"><path fill-rule="evenodd" d="M12 2a10 10 0 1 1 0 20 10 10 0 0 1 0-20Zm4.8 5a1 1 0 0 0-1.4.3l-5.4 8-2-2.1a1 1 0 1 0-1.5 1.4l3 3a1 1 0 0 0 1.5-.2l6-9a1 1 0 0 0-.2-1.4Z"/></svg>',
'checkmark': '<svg width="24" height="24"><path d="M18.2 5.4a1 1 0 0 1 1.6 1.2l-8 12a1 1 0 0 1-1.5.1l-5-5a1 1 0 1 1 1.4-1.4l4.1 4.1 7.4-11Z" fill-rule="nonzero"/></svg>',
'chevron-down': '<svg width="10" height="10"><path d="M8.7 2.2c.3-.3.8-.3 1 0 .4.4.4.9 0 1.2L5.7 7.8c-.3.3-.9.3-1.2 0L.2 3.4a.8.8 0 0 1 0-1.2c.3-.3.8-.3 1.1 0L5 6l3.7-3.8Z" fill-rule="nonzero"/></svg>',
'chevron-left': '<svg width="10" height="10"><path d="M7.8 1.3 4 5l3.8 3.7c.3.3.3.8 0 1-.4.4-.9.4-1.2 0L2.2 5.7a.8.8 0 0 1 0-1.2L6.6.2C7 0 7.4 0 7.8.2c.3.3.3.8 0 1.1Z" fill-rule="nonzero"/></svg>',
'chevron-right': '<svg width="10" height="10"><path d="M2.2 1.3a.8.8 0 0 1 0-1c.4-.4.9-.4 1.2 0l4.4 4.1c.3.4.3.9 0 1.2L3.4 9.8c-.3.3-.8.3-1.2 0a.8.8 0 0 1 0-1.1L6 5 2.2 1.3Z" fill-rule="nonzero"/></svg>',
'chevron-up': '<svg width="10" height="10"><path d="M8.7 7.8 5 4 1.3 7.8c-.3.3-.8.3-1 0a.8.8 0 0 1 0-1.2l4.1-4.4c.3-.3.9-.3 1.2 0l4.2 4.4c.3.3.3.9 0 1.2-.3.3-.8.3-1.1 0Z" fill-rule="nonzero"/></svg>',
'close-filled': '<svg width="24" height="24"><path fill-rule="evenodd" d="M12 2a10 10 0 1 1 0 20 10 10 0 0 1 0-20Zm4.7 5.3a1 1 0 0 0-1.3 0L12 10.6 8.6 7.3a1 1 0 0 0-1.3 1.3l3.3 3.4-3.3 3.4a1 1 0 0 0 1.3 1.3l3.4-3.3 3.4 3.3a1 1 0 0 0 1.3-1.3L13.4 12l3.3-3.4a1 1 0 0 0 0-1.3Z"/></svg>',
'close': '<svg width="24" height="24"><path d="M17.3 8.2 13.4 12l3.9 3.8a1 1 0 0 1-1.5 1.5L12 13.4l-3.8 3.9a1 1 0 0 1-1.5-1.5l3.9-3.8-3.9-3.8a1 1 0 0 1 1.5-1.5l3.8 3.9 3.8-3.9a1 1 0 0 1 1.5 1.5Z" fill-rule="evenodd"/></svg>',
'code-sample': '<svg width="24" height="26"><path d="M7.1 11a2.8 2.8 0 0 1-.8 2 2.8 2.8 0 0 1 .8 2v1.7c0 .3.1.6.4.8.2.3.5.4.8.4.3 0 .4.2.4.4v.8c0 .2-.1.4-.4.4-.7 0-1.4-.3-2-.8-.5-.6-.8-1.3-.8-2V15c0-.3-.1-.6-.4-.8-.2-.3-.5-.4-.8-.4a.4.4 0 0 1-.4-.4v-.8c0-.2.2-.4.4-.4.3 0 .6-.1.8-.4.3-.2.4-.5.4-.8V9.3c0-.7.3-1.4.8-2 .6-.5 1.3-.8 2-.8.3 0 .4.2.4.4v.8c0 .2-.1.4-.4.4-.3 0-.6.1-.8.4-.3.2-.4.5-.4.8V11Zm9.8 0V9.3c0-.3-.1-.6-.4-.8-.2-.3-.5-.4-.8-.4a.4.4 0 0 1-.4-.4V7c0-.2.1-.4.4-.4.7 0 1.4.3 2 .8.5.6.8 1.3.8 2V11c0 .3.1.6.4.8.2.3.5.4.8.4.2 0 .4.2.4.4v.8c0 .2-.2.4-.4.4-.3 0-.6.1-.8.4-.3.2-.4.5-.4.8v1.7c0 .7-.3 1.4-.8 2-.6.5-1.3.8-2 .8a.4.4 0 0 1-.4-.4v-.8c0-.2.1-.4.4-.4.3 0 .6-.1.8-.4.3-.2.4-.5.4-.8V15a2.8 2.8 0 0 1 .8-2 2.8 2.8 0 0 1-.8-2Zm-3.3-.4c0 .4-.1.8-.5 1.1-.3.3-.7.5-1.1.5-.4 0-.8-.2-1.1-.5-.4-.3-.5-.7-.5-1.1 0-.5.1-.9.5-1.2.3-.3.7-.4 1.1-.4.4 0 .8.1 1.1.4.4.3.5.7.5 1.2ZM12 13c.4 0 .8.1 1.1.5.4.3.5.7.5 1.1 0 1-.1 1.6-.5 2a3 3 0 0 1-1.1 1c-.4.3-.8.4-1.1.4a.5.5 0 0 1-.5-.5V17a3 3 0 0 0 1-.2l.6-.6c-.6 0-1-.2-1.3-.5-.2-.3-.3-.7-.3-1 0-.5.1-1 .5-1.2.3-.4.7-.5 1.1-.5Z" fill-rule="evenodd"/></svg>',
'color-levels': '<svg width="24" height="24"><path d="M17.5 11.4A9 9 0 0 1 18 14c0 .5 0 1-.2 1.4 0 .4-.3.9-.5 1.3a6.2 6.2 0 0 1-3.7 3 5.7 5.7 0 0 1-3.2 0A5.9 5.9 0 0 1 7.6 18a6.2 6.2 0 0 1-1.4-2.6 6.7 6.7 0 0 1 0-2.8c0-.4.1-.9.3-1.3a13.6 13.6 0 0 1 2.3-4A20 20 0 0 1 12 4a26.4 26.4 0 0 1 3.2 3.4 18.2 18.2 0 0 1 2.3 4Zm-2 4.5c.4-.7.5-1.4.5-2a7.3 7.3 0 0 0-1-3.2c.2.6.2 1.2.2 1.9a4.5 4.5 0 0 1-1.3 3 5.3 5.3 0 0 1-2.3 1.5 4.9 4.9 0 0 1-2 .1 4.3 4.3 0 0 0 2.4.8 4 4 0 0 0 2-.6 4 4 0 0 0 1.5-1.5Z" fill-rule="evenodd"/></svg>',
'color-picker': '<svg width="24" height="24"><path d="M12 3a9 9 0 0 0 0 18 1.5 1.5 0 0 0 1.1-2.5c-.2-.3-.4-.6-.4-1 0-.8.7-1.5 1.5-1.5H16a5 5 0 0 0 5-5c0-4.4-4-8-9-8Zm-5.5 9a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3Zm3-4a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3Zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3Zm3 4a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3Z" fill-rule="nonzero"/></svg>',
'color-swatch-remove-color': '<svg width="24" height="24" class="color-swatch-remove-color"><path stroke="#000" stroke-width="2" d="M21 3 3 21" fill-rule="evenodd"/></svg>',
'color-swatch': '<svg width="24" height="24"><rect x="3" y="3" width="18" height="18" rx="1" fill-rule="evenodd"/></svg>',
'comment-add': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="m9 19 3-2h7c.6 0 1-.4 1-1V6c0-.6-.4-1-1-1H5a1 1 0 0 0-1 1v10c0 .6.4 1 1 1h4v2Zm-2 4v-4H5a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3h14a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3h-6.4L7 23Z"/><path d="M13 10h2a1 1 0 0 1 0 2h-2v2a1 1 0 0 1-2 0v-2H9a1 1 0 0 1 0-2h2V8a1 1 0 0 1 2 0v2Z"/></g></svg>',
'comment': '<svg width="24" height="24"><path fill-rule="nonzero" d="m9 19 3-2h7c.6 0 1-.4 1-1V6c0-.6-.4-1-1-1H5a1 1 0 0 0-1 1v10c0 .6.4 1 1 1h4v2Zm-2 4v-4H5a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3h14a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3h-6.4L7 23Z"/></svg>',
'contrast': '<svg width="24" height="24"><path fill-rule="evenodd" d="M12 4a7.8 7.8 0 0 1 5.7 2.3A8 8 0 0 1 19.4 9c.4 1 .6 2 .6 3.1s-.2 2.1-.6 3.1a8 8 0 0 1-1.7 2.6 8 8 0 0 1-2.6 1.7 7.8 7.8 0 0 1-3.1.6 7.8 7.8 0 0 1-3.1-.6 8 8 0 0 1-2.6-1.7A8 8 0 0 1 4.6 15 7.8 7.8 0 0 1 4 12c0-1.1.2-2.1.6-3.1a8 8 0 0 1 1.7-2.6A8 8 0 0 1 9 4.6 7.8 7.8 0 0 1 12 4Zm-6 8a6 6 0 0 0 1.8 4.2 6 6 0 0 0 1.9 1.3 5.8 5.8 0 0 0 2.3.5V6c-.8 0-1.6.2-2.3.5a6 6 0 0 0-2 1.3 6 6 0 0 0-1.2 1.9A5.8 5.8 0 0 0 6 12Z"/></svg>',
'copy': '<svg width="24" height="24"><path d="M16 3H6a2 2 0 0 0-2 2v11h2V5h10V3Zm1 4a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-7a2 2 0 0 1-2-2V9c0-1.2.9-2 2-2h7Zm0 12V9h-7v10h7Z" fill-rule="nonzero"/></svg>',
'crop': '<svg width="24" height="24"><path d="M17 8v7h2c.6 0 1 .4 1 1s-.4 1-1 1h-2v2c0 .6-.4 1-1 1a1 1 0 0 1-1-1v-2H7V9H5a1 1 0 1 1 0-2h2V5c0-.6.4-1 1-1s1 .4 1 1v2h7l3-3 1 1-3 3ZM9 9v5l5-5H9Zm1 6h5v-5l-5 5Z" fill-rule="evenodd"/></svg>',
'cut-column': '<svg width="24" height="24"><path fill-rule="evenodd" d="M7.2 4.5c.9 0 1.6.4 2.2 1A3.7 3.7 0 0 1 10.5 8v.5l1 1 4-4 1-.5a3.3 3.3 0 0 1 2 0c.4 0 .7.3 1 .5L17 8h4v13h-6V10l-1.5 1.5.5.5v4l-2.5-2.5-1 1v.5c0 .4 0 .8-.3 1.2-.2.5-.4.9-.8 1.2-.6.7-1.3 1-2.2 1-.8.2-1.5 0-2-.6l-.5-.8-.2-1c0-.4 0-.8.3-1.2A3.9 3.9 0 0 1 7 12.7c.5-.2 1-.3 1.5-.2l1-1-1-1c-.5 0-1 0-1.5-.2-.5-.1-1-.4-1.4-.9-.4-.3-.6-.7-.8-1.2L4.5 7c0-.4 0-.7.2-1 0-.3.3-.6.5-.8.5-.5 1.2-.8 2-.7Zm12.3 5h-3v10h3v-10ZM8 13.8h-.3l-.4.2a2.8 2.8 0 0 0-.7.4v.1a2.8 2.8 0 0 0-.6.8l-.1.4v.7l.2.5.5.2h.7a2.6 2.6 0 0 0 .8-.3 2.4 2.4 0 0 0 .7-.7 2.5 2.5 0 0 0 .3-.8 1.5 1.5 0 0 0 0-.8 1 1 0 0 0-.2-.4 1 1 0 0 0-.5-.2H8Zm3.5-3.7c-.4 0-.7.1-1 .4-.3.3-.4.6-.4 1s.1.7.4 1c.3.3.6.4 1 .4s.7-.1 1-.4c.3-.3.4-.6.4-1s-.1-.7-.4-1c-.3-.3-.6-.4-1-.4ZM7 5.8h-.4a1 1 0 0 0-.5.3 1 1 0 0 0-.2.5v.7a2.5 2.5 0 0 0 .3.8l.2.3h.1l.4.4.4.2.4.1h.7L9 9l.2-.4a1.6 1.6 0 0 0 0-.8 2.6 2.6 0 0 0-.3-.8A2.5 2.5 0 0 0 7.7 6l-.4-.1H7Z"/></svg>',
'cut-row': '<svg width="24" height="24"><path fill-rule="evenodd" d="M22 3v5H9l3 3 2-2h4l-4 4 1 1h.5c.4 0 .8 0 1.2.3.5.2.9.4 1.2.8.7.6 1 1.3 1 2.2.2.8 0 1.5-.6 2l-.8.5-1 .2c-.4 0-.8 0-1.2-.3a3.9 3.9 0 0 1-2.1-2.2c-.2-.5-.3-1-.2-1.5l-1-1-1 1c0 .5 0 1-.2 1.5-.1.5-.4 1-.9 1.4-.3.4-.7.6-1.2.8l-1.2.3c-.4 0-.7 0-1-.2-.3 0-.6-.3-.8-.5-.5-.5-.8-1.2-.7-2 0-.9.4-1.6 1-2.2A3.7 3.7 0 0 1 8.6 14H9l1-1-4-4-.5-1a3.3 3.3 0 0 1 0-2c0-.4.3-.7.5-1l2 2V3h14ZM8.5 15.3h-.3a2.6 2.6 0 0 0-.8.4 2.5 2.5 0 0 0-.9 1.1l-.1.4v.7l.2.5.5.2h.7a2.5 2.5 0 0 0 .8-.3L9 18V18l.4-.4.2-.4.1-.4v-.7a1 1 0 0 0-.2-.5 1 1 0 0 0-.4-.2h-.5Zm7 0H15a1 1 0 0 0-.4.3 1 1 0 0 0-.2.5 1.5 1.5 0 0 0 0 .7v.4a2.8 2.8 0 0 0 .5.7h.1a2.8 2.8 0 0 0 .8.6l.4.1h.7l.5-.2.2-.5v-.7a2.6 2.6 0 0 0-.3-.8 2.4 2.4 0 0 0-.7-.7 2.5 2.5 0 0 0-.8-.3h-.3ZM12 11.6c-.4 0-.7.1-1 .4-.3.3-.4.6-.4 1s.1.7.4 1c.3.3.6.4 1 .4s.7-.1 1-.4c.3-.3.4-.6.4-1s-.1-.7-.4-1c-.3-.3-.6-.4-1-.4Zm8.5-7.1h-11v2h11v-2Z"/></svg>',
'cut': '<svg width="24" height="24"><path d="M18 15c.6.7 1 1.4 1 2.3 0 .8-.2 1.5-.7 2l-.8.5-1 .2c-.4 0-.8 0-1.2-.3a3.9 3.9 0 0 1-2.1-2.2c-.2-.5-.3-1-.2-1.5l-1-1-1 1c0 .5 0 1-.2 1.5-.1.5-.4 1-.9 1.4-.3.4-.7.6-1.2.8l-1.2.3c-.4 0-.7 0-1-.2-.3 0-.6-.3-.8-.5-.5-.5-.8-1.2-.7-2 0-.9.4-1.6 1-2.2A3.7 3.7 0 0 1 8.6 14H9l1-1-4-4-.5-1a3.3 3.3 0 0 1 0-2c0-.4.3-.7.5-1l6 6 6-6 .5 1a3.3 3.3 0 0 1 0 2c0 .4-.3.7-.5 1l-4 4 1 1h.5c.4 0 .8 0 1.2.3.5.2.9.4 1.2.8Zm-8.5 2.2.1-.4v-.7a1 1 0 0 0-.2-.5 1 1 0 0 0-.4-.2 1.6 1.6 0 0 0-.8 0 2.6 2.6 0 0 0-.8.3 2.5 2.5 0 0 0-.9 1.1l-.1.4v.7l.2.5.5.2h.7a2.5 2.5 0 0 0 .8-.3 2.8 2.8 0 0 0 1-1Zm2.5-2.8c.4 0 .7-.1 1-.4.3-.3.4-.6.4-1s-.1-.7-.4-1c-.3-.3-.6-.4-1-.4s-.7.1-1 .4c-.3.3-.4.6-.4 1s.1.7.4 1c.3.3.6.4 1 .4Zm5.4 4 .2-.5v-.7a2.6 2.6 0 0 0-.3-.8 2.4 2.4 0 0 0-.7-.7 2.5 2.5 0 0 0-.8-.3 1.5 1.5 0 0 0-.8 0 1 1 0 0 0-.4.2 1 1 0 0 0-.2.5 1.5 1.5 0 0 0 0 .7v.4l.3.4.3.4a2.8 2.8 0 0 0 .8.5l.4.1h.7l.5-.2Z" fill-rule="evenodd"/></svg>',
'document-gear-properties': '<svg height="24" width="24"><path d="M17.3 14.5a7.1 7.1 0 0 1 1.2.6l1.5-.5 1 1.8-1.2 1V18.7l1.2 1-1 1.6-1.5-.4a4.5 4.5 0 0 1-.6.3 7.1 7.1 0 0 1-.6.3L17 23h-2l-.3-1.5a7.4 7.4 0 0 1-.6-.3 4.5 4.5 0 0 1-.6-.3l-1.5.5-1-1.8 1.2-1a3.9 3.9 0 0 1 0-.6v-.7l-1.2-1 1-1.6 1.5.4a4.5 4.5 0 0 1 1.2-.6L15 13h2zM16 16a2 2 0 0 0-1.5.6A1.9 1.9 0 0 0 14 18c0 .6.2 1 .6 1.4s1 .6 1.5.6 1-.2 1.5-.6.6-.8.6-1.4-.2-1-.6-1.4A2 2 0 0 0 16 16z" fill-rule="evenodd"/><path d="M19 7.6V12h-2V9h-4V5H7v14h3v2H7a2 2 0 0 1-2-2V5c0-1.1.9-2 2-2h7.4z"/></svg>',
'document-properties': '<svg width="24" height="24"><path d="M14.4 3H7a2 2 0 0 0-2 2v14c0 1.1.9 2 2 2h10a2 2 0 0 0 2-2V7.6L14.4 3ZM17 19H7V5h6v4h4v10Z" fill-rule="nonzero"/></svg>',
'drag': '<svg width="24" height="24"><path d="M13 5h2v2h-2V5Zm0 4h2v2h-2V9ZM9 9h2v2H9V9Zm4 4h2v2h-2v-2Zm-4 0h2v2H9v-2Zm0 4h2v2H9v-2Zm4 0h2v2h-2v-2ZM9 5h2v2H9V5Z" fill-rule="evenodd"/></svg>',
'dropbox': '<svg height="24" width="24"><path clip-rule="evenodd" d="m6.4 9.3-3-2a1 1 0 0 1 0-1.6l4-2.5a1 1 0 0 1 1 0L12 5.5l3.6-2.3a1 1 0 0 1 1 0l4 2.5a1 1 0 0 1 0 1.7l-3 1.9 3 1.9a1 1 0 0 1 0 1.6l-2.9 1.9V16c0 .3-.1.6-.4.8l-4.5 3a1 1 0 0 1-1.2 0l-4.4-3a1 1 0 0 1-.5-.9v-1l-3.2-2.2a1 1 0 0 1 0-1.6zm3 0L12 7.5l2.6 1.8L12 11zM8.9 15v.4l3.3 2.3 3.4-2.3v-.2L12 13l-3.1 2zm-1-10-2 1.4 2 1.3 2-1.3zm8.2 0-2 1.4 2 1.3 2-1.3zm-2 6.9 2-1.3 2 1.3-2 1.3-2-1.3zm-8.3 0 2-1.3L10 12l-2 1.3-2-1.3z" fill-rule="evenodd"/></svg>',
'duplicate-column': '<svg width="24" height="24"><path d="M17 6v16h-7V6h7Zm-2 2h-3v12h3V8Zm-2-6v2H8v15H6V2h7Z"/></svg>',
'duplicate-row': '<svg width="24" height="24"><path d="M22 11v7H6v-7h16Zm-2 2H8v3h12v-3Zm-1-6v2H4v5H2V7h17Z"/></svg>',
'duplicate': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="M16 3v2H6v11H4V5c0-1.1.9-2 2-2h10Zm3 8h-2V9h-7v10h9a2 2 0 0 1-2 2h-7a2 2 0 0 1-2-2V9c0-1.2.9-2 2-2h7a2 2 0 0 1 2 2v2Z"/><path d="M17 14h1a1 1 0 0 1 0 2h-1v1a1 1 0 0 1-2 0v-1h-1a1 1 0 0 1 0-2h1v-1a1 1 0 0 1 2 0v1Z"/></g></svg>',
'edit-block': '<svg width="24" height="24"><path fill-rule="nonzero" d="m19.8 8.8-9.4 9.4c-.2.2-.5.4-.9.4l-5.4 1.2 1.2-5.4.5-.8 9.4-9.4c.7-.7 1.8-.7 2.5 0l2.1 2.1c.7.7.7 1.8 0 2.5Zm-2-.2 1-.9v-.3l-2.2-2.2a.3.3 0 0 0-.3 0l-1 1L18 8.5Zm-1 1-2.5-2.4-6 6 2.5 2.5 6-6Zm-7 7.1-2.6-2.4-.3.3-.1.2-.7 3 3.1-.6h.1l.4-.5Z"/></svg>',
'edit-image': '<svg width="24" height="24"><path d="M18 16h2V7a2 2 0 0 0-2-2H7v2h11v9ZM6 17h15a1 1 0 0 1 0 2h-1v1a1 1 0 0 1-2 0v-1H6a2 2 0 0 1-2-2V7H3a1 1 0 1 1 0-2h1V4a1 1 0 1 1 2 0v13Zm3-5.3 1.3 2 3-4.7 3.7 6H7l2-3.3Z" fill-rule="nonzero"/></svg>',
'embed-page': '<svg width="24" height="24"><path d="M19 6V5H5v14h2A13 13 0 0 1 19 6Zm0 1.4c-.8.8-1.6 2.4-2.2 4.6H19V7.4Zm0 5.6h-2.4c-.4 1.8-.6 3.8-.6 6h3v-6Zm-4 6c0-2.2.2-4.2.6-6H13c-.7 1.8-1.1 3.8-1.1 6h3Zm-4 0c0-2.2.4-4.2 1-6H9.6A12 12 0 0 0 8 19h3ZM4 3h16c.6 0 1 .4 1 1v16c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V4c0-.6.4-1 1-1Zm11.8 9c.4-1.9 1-3.4 1.8-4.5a9.2 9.2 0 0 0-4 4.5h2.2Zm-3.4 0a12 12 0 0 1 2.8-4 12 12 0 0 0-5 4h2.2Z" fill-rule="nonzero"/></svg>',
'embed': '<svg width="24" height="24"><path d="M4 3h16c.6 0 1 .4 1 1v16c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V4c0-.6.4-1 1-1Zm1 2v14h14V5H5Zm4.8 2.6 5.6 4a.5.5 0 0 1 0 .8l-5.6 4A.5.5 0 0 1 9 16V8a.5.5 0 0 1 .8-.4Z" fill-rule="nonzero"/></svg>',
'emoji': '<svg width="24" height="24"><path d="M9 11c.6 0 1-.4 1-1s-.4-1-1-1a1 1 0 0 0-1 1c0 .6.4 1 1 1Zm6 0c.6 0 1-.4 1-1s-.4-1-1-1a1 1 0 0 0-1 1c0 .6.4 1 1 1Zm-3 5.5c2.1 0 4-1.5 4.4-3.5H7.6c.5 2 2.3 3.5 4.4 3.5ZM12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm0 14.5a6.5 6.5 0 1 1 0-13 6.5 6.5 0 0 1 0 13Z" fill-rule="nonzero"/></svg>',
'evernote': '<svg width="24" height="24"><path fill-rule="evenodd" d="m9.5 3-.3.1-2.6 2.6C3.8 8.5 4 8.2 4 8.7c0 1.3.3 3 .6 4.3.5 2 1.1 3.2 2 3.7l1.2.3c1 .2 1.5.2 2.2.2 1.3 0 1.7 0 2.2-.4.3-.2.3-.4.4-1a38.4 38.4 0 0 1 .3-.4l.3.1 1.8.1h1.6v-1.8H14l-.1-.2a6.8 6.8 0 0 1-.5-1c-.2-.4-.3-.6-.5-.7a.8.8 0 0 0-.5-.1.9.9 0 0 0-.8.5l-.4 1.6-.3 1.5H9.4l-2-.3a1 1 0 0 1-.1-.2A10.1 10.1 0 0 1 6 9.7v-.2h4l.5-.5V5H12c.4.2.7.7.8 1.1a1 1 0 0 0 .2.6c.2.2.3.2 1 .3 1.2 0 2 .2 2.5.6.4.2.8.7 1 1.2.3 1.2.5 4 .3 6.4 0 1.8-.4 3.4-.8 4h-.7a8 8 0 0 1-.8 0c-.2 0-.3-.3-.2-.5a.5.5 0 0 1 .4-.3h.9v-1.8H16c-.7 0-.9 0-1.2.2-.9.4-1.4 1.2-1.4 2.1l.1.4.1.2a1 1 0 0 1 .1.2c.3.7.8 1.2 1.4 1.3l1.2.1h1.2a2 2 0 0 0 1-.8 9 9 0 0 0 1.1-4.3c.2-3 0-6.3-.4-7.7A4.3 4.3 0 0 0 16 5.3a7 7 0 0 0-1.3-.2 7.2 7.2 0 0 1-.4 0 5.5 5.5 0 0 1 0-.3c-.2-.5-.6-1-1.2-1.4a3 3 0 0 0-.5-.2c-.4-.2-.5-.2-1.8-.2a26.5 26.5 0 0 0-1.3 0Zm-.8 4v.7H7.2l.7-.8.8-.7v.7Zm7 3.5c-.4 0-.7.5-.9 1v.7h.3c.7 0 1.1.2 1.5.6l.3.2.3-.6V11a1 1 0 0 0-.6-.4 2 2 0 0 0-.8 0Z" clip-rule="evenodd"/></svg>',
'export-pdf': '<svg width="24" height="24"><path fill-rule="evenodd" clip-rule="evenodd" d="M7 3h7.4L19 7.6V17h-2V9h-4V5H7v3H5V5c0-1.1.9-2 2-2Z"/><path d="M2.6 15.2v-1.9h1c.6 0 1-.2 1.4-.5.3-.3.5-.7.5-1.2s-.2-.9-.5-1.2a2 2 0 0 0-1.3-.4H1v5.2h1.6Zm.4-3h-.4v-1.1h.5l.6.1.2.5c0 .1 0 .3-.2.4l-.7.1Zm5.7 3 1-.1c.3 0 .5-.2.7-.4l.5-.8c.2-.3.2-.7.2-1.3v-1l-.5-.8c-.2-.3-.4-.5-.7-.6L8.7 10H6.3v5.2h2.4Zm-.4-1.1H8v-3h.4c.5 0 .8.2 1 .4l.2 1.1-.1 1-.3.3-.8.2Zm5.3 1.2V13h2v-1h-2v-1H16V10h-4v5.2h1.6Z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M15 17a1 1 0 1 0-2 0v3.1l-1.4-1a1 1 0 1 0-1.2 1.7l3.6 2.4 3.6-2.4a1 1 0 0 0-1.2-1.6l-1.4 1V17Z"/></svg>',
'export-word': '<svg width="24" height="24"><path d="M9.5 7A1.5 1.5 0 0 1 11 8.4v7.1A1.5 1.5 0 0 1 9.6 17H2.5A1.5 1.5 0 0 1 1 15.6V8.5A1.5 1.5 0 0 1 2.4 7h7.1Zm-1 2.8-1 2.6-1-2.5v-.1a.6.6 0 0 0-1 0l-.1.1-.9 2.5-1-2.5v-.1a.6.6 0 0 0-1 .4v.1l1.5 4v.1a.6.6 0 0 0 1 0v-.1l1-2.5.9 2.5v.1a.6.6 0 0 0 1 0H8l1.6-4v-.2a.6.6 0 0 0-1.1-.4Z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M7 3h7.4L19 7.6V17h-2V9h-4V5H5c0-1.1.9-2 2-2ZM15 17a1 1 0 1 0-2 0v3.1l-1.4-1a1 1 0 1 0-1.2 1.7l3.6 2.4 3.6-2.4a1 1 0 0 0-1.2-1.6l-1.4 1V17Z"/></svg>',
'export': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="M14.4 3 18 7v1h-5V5H7v14h9a1 1 0 0 1 2 0c0 1-.8 2-1.9 2H7c-1 0-2-.8-2-1.9V5c0-1 .8-2 1.9-2h7.5Z"/><path d="M18.1 12c.5 0 .9.4.9 1 0 .5-.3 1-.8 1h-7.3c-.5 0-.9-.4-.9-1 0-.5.3-1 .8-1h7.3Z"/><path d="M16.4 9.2a1 1 0 0 1 1.4.2l2.4 3.6-2.4 3.6a1 1 0 0 1-1.7-1v-.2l1.7-2.4-1.6-2.4a1 1 0 0 1 .2-1.4Z"/></g></svg>',
'exposure': '<svg width="24" height="24"><path d="M5 21a2 2 0 0 1-1.4-.6A2 2 0 0 1 3 19V5c0-.6.2-1 .6-1.4A2 2 0 0 1 5 3h14c.6 0 1 .2 1.4.6.4.4.6.8.6 1.4v14c0 .6-.2 1-.6 1.4a2 2 0 0 1-1.4.6H5Zm0-2h14V5L5 19Zm9.5-1v-2h-2v-1.5h2v-2H16v2h2V16h-2v2h-1.5ZM6 8.5h5V7H6v1.5Z"/></svg>',
'fb': '<svg width="24" height="24"><path fill-rule="evenodd" d="M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-11 6.7V14H8.1v-2.5h2v-1C10 8.2 11.5 7 12.8 7H16v2.5h-2.4c-.8 0-1 .7-1 1.3v.7h3.2l-1 2.5h-2v5a7 7 0 1 0-2.8-.2Z" clip-rule="evenodd"/></svg>',
'feedback': '<svg width="24" height="24"><path fill-rule="evenodd" d="M16 6c1 0 2 1 2 2v5c0 1-1 2-2 2h-3l-4 3v-3H8c-1 0-2-1-2-2V8c0-1 1-2 2-2h8Zm-7 5v1h4v-1H9Zm0-2v1h6V9H9Z"/></svg>',
'fill': '<svg width="24" height="26"><path d="m16.6 12-9-9-1.4 1.4 2.4 2.4-5.2 5.1c-.5.6-.5 1.6 0 2.2L9 19.6a1.5 1.5 0 0 0 2.2 0l5.5-5.5c.5-.6.5-1.6 0-2.2ZM5.2 13 10 8.2l4.8 4.8H5.2ZM19 14.5s-2 2.2-2 3.5c0 1.1.9 2 2 2a2 2 0 0 0 2-2c0-1.3-2-3.5-2-3.5Z" fill-rule="nonzero"/></svg>',
'flickr': '<svg width="24" height="24"><path d="M8.2 15.3c1.7 0 3.1-1.4 3.1-3.1A3.2 3.2 0 0 0 8.1 9 3.2 3.2 0 0 0 5 12.2c0 1.7 1.4 3 3.2 3Zm7.6 0c1.7 0 3.2-1.4 3.2-3.1a3.2 3.2 0 0 0-6.3 0c0 1.7 1.4 3 3.1 3Z"/></svg>',
'flip-horizontally': '<svg width="24" height="24"><path d="M14 19h2v-2h-2v2Zm4-8h2V9h-2v2ZM4 7v10c0 1.1.9 2 2 2h3v-2H6V7h3V5H6a2 2 0 0 0-2 2Zm14-2v2h2a2 2 0 0 0-2-2Zm-7 16h2V3h-2v18Zm7-6h2v-2h-2v2Zm-4-8h2V5h-2v2Zm4 12a2 2 0 0 0 2-2h-2v2Z" fill-rule="nonzero"/></svg>',
'flip-vertically': '<svg width="24" height="24"><path d="M5 14v2h2v-2H5Zm8 4v2h2v-2h-2Zm4-14H7a2 2 0 0 0-2 2v3h2V6h10v3h2V6a2 2 0 0 0-2-2Zm2 14h-2v2a2 2 0 0 0 2-2ZM3 11v2h18v-2H3Zm6 7v2h2v-2H9Zm8-4v2h2v-2h-2ZM5 18c0 1.1.9 2 2 2v-2H5Z" fill-rule="nonzero"/></svg>',
'folder': '<svg width="24" height="24"><path fill-rule="evenodd" d="M5.6 6a.6.6 0 0 0-.6.6v11.2a.6.6 0 0 0 .6.6h12.8a.6.6 0 0 0 .6-.6V9a.6.6 0 0 0-.6-.6h-7.2a1 1 0 0 1-.8-.4L9 6H5.6ZM3.8 4.8A2.6 2.6 0 0 1 5.6 4h4a1 1 0 0 1 .8.4l1.3 2h6.7A2.6 2.6 0 0 1 21 9v8.8a2.6 2.6 0 0 1-2.6 2.6H5.6A2.6 2.6 0 0 1 3 17.8V6.6c0-.7.3-1.4.8-1.8Z" clip-rule="evenodd"/></svg>',
'footnote': '<svg width="24" height="24"><path d="M19 13c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2h14Z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M19 4v6h-1V5h-1.5V4h2.6Z"/><path d="M12 18c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2h7ZM14 8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2h9Z"/></svg>',
'format-code': '<svg width="24" height="24"><path d="m10 22 2-7H6l9-13h2l-2 8h7L12 22h-2ZM6 2h7l-1.4 2H6V2Zm4.2 4H4v2h4.8l1.4-2Zm-2.7 4H2v2h4l1.5-2Z"/></svg>',
'format-painter': '<svg width="24" height="24"><path d="M18 5V4c0-.5-.4-1-1-1H5a1 1 0 0 0-1 1v4c0 .6.5 1 1 1h12c.6 0 1-.4 1-1V7h1v4H9v9c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-7h8V5h-3Z" fill-rule="nonzero"/></svg>',
'format': '<svg width="24" height="24"><path fill-rule="evenodd" d="M17 5a1 1 0 0 1 0 2h-4v11a1 1 0 0 1-2 0V7H7a1 1 0 1 1 0-2h10Z"/></svg>',
'fullscreen': '<svg width="24" height="24"><path d="m15.3 10-1.2-1.3 2.9-3h-2.3a.9.9 0 1 1 0-1.7H19c.5 0 .9.4.9.9v4.4a.9.9 0 1 1-1.8 0V7l-2.9 3Zm0 4 3 3v-2.3a.9.9 0 1 1 1.7 0V19c0 .5-.4.9-.9.9h-4.4a.9.9 0 1 1 0-1.8H17l-3-2.9 1.3-1.2ZM10 15.4l-2.9 3h2.3a.9.9 0 1 1 0 1.7H5a.9.9 0 0 1-.9-.9v-4.4a.9.9 0 1 1 1.8 0V17l2.9-3 1.2 1.3ZM8.7 10 5.7 7v2.3a.9.9 0 0 1-1.7 0V5c0-.5.4-.9.9-.9h4.4a.9.9 0 0 1 0 1.8H7l3 2.9-1.3 1.2Z" fill-rule="nonzero"/></svg>',
'gallery': '<svg width="24" height="24"><path fill-rule="nonzero" d="m5 15.7 2.3-2.2c.3-.3.7-.3 1 0L11 16l5.1-5c.3-.4.8-.4 1 0l2 1.9V8H5v7.7ZM5 18V19h3l1.8-1.9-2-2L5 17.9Zm14-3-2.5-2.4-6.4 6.5H19v-4ZM4 6h16c.6 0 1 .4 1 1v13c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V7c0-.6.4-1 1-1Zm6 7a2 2 0 1 1 0-4 2 2 0 0 1 0 4ZM4.5 4h15a.5.5 0 1 1 0 1h-15a.5.5 0 0 1 0-1Zm2-2h11a.5.5 0 1 1 0 1h-11a.5.5 0 0 1 0-1Z"/></svg>',
'gamma': '<svg height="24" width="24"><path d="M11.5 16.3a.7.7 0 1 0 1.4 0V14l2.7-6a.7.7 0 1 0-1.2-.6l-2.2 5-2.3-4.9C9.6 7 8.7 7 8 7.2v1.1c.8-.2.9 0 1.2 1l2.3 4.7z"/><path d="M4 3h16a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm1 2h14v14H5z" fill-rule="evenodd"/></svg>',
'google-drive': '<svg height="24" width="24"><path clip-rule="evenodd" d="M8.7 4.5a1 1 0 0 1 .9-.5h4.8a1 1 0 0 1 .9.5l5.6 9.7a1 1 0 0 1 0 1l-2.4 4.2a1 1 0 0 1-.9.5H6.4a1 1 0 0 1-.9-.5l-2.4-4.2a1 1 0 0 1 0-1zM10.2 6l-4.5 7.7h2.5L12.7 6h-2.5zm4.2 1 4.4 7.7-1.2 2.2-4.4-7.7zM12 11.2l-1.5 2.5h3zm2.6 4.5H5.7L7 17.9h8.9l-1.3-2.2z" fill-rule="evenodd"/></svg>',
'google-photos': '<svg width="24" height="24"><path fill-rule="evenodd" d="M12.4 3c-.8 0-1.4.7-1.4 1.4v3.2a5 5 0 0 0-8 4c0 .8.6 1.4 1.4 1.4h3.2a5 5 0 0 0-1 3 5 5 0 0 0 5 5c.8 0 1.4-.6 1.4-1.4v-3.2a5 5 0 0 0 8-4c0-.8-.7-1.4-1.4-1.4h-3.2a5 5 0 0 0-4-8Zm.6 8V5a3 3 0 0 1 2.4 3 3 3 0 0 1-2.4 3Zm-2 0H5a3 3 0 0 1 3-2.4 3 3 0 0 1 3 2.4Zm2 2a3 3 0 0 0 3 2.4 3 3 0 0 0 3-2.4h-6Zm-4.4 3a3 3 0 0 1 2.4-3v6a3 3 0 0 1-2.4-3Z" clip-rule="evenodd"/></svg>',
'grayscale': '<svg height="24" width="24"><path d="M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2zm12.4 0H19v3.6zm-2.8 0h-2.2l8.6 8.6v-2.2zm-5 0H5l14 14v-2.6z" fill-rule="evenodd"/></svg>',
'help': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M12 5.5a6.5 6.5 0 0 0-6 9 6.3 6.3 0 0 0 1.4 2l1 1a6.3 6.3 0 0 0 3.6 1 6.5 6.5 0 0 0 6-9 6.3 6.3 0 0 0-1.4-2l-1-1a6.3 6.3 0 0 0-3.6-1ZM12 4a7.8 7.8 0 0 1 5.7 2.3A8 8 0 1 1 12 4Z"/><path d="M9.6 9.7a.7.7 0 0 1-.7-.8c0-1.1 1.5-1.8 3.2-1.8 1.8 0 3.2.8 3.2 2.4 0 1.4-.4 2.1-1.5 2.8-.2 0-.3.1-.3.2a2 2 0 0 0-.8.8.8.8 0 0 1-1.4-.6c.3-.7.8-1 1.3-1.5l.4-.2c.7-.4.8-.6.8-1.5 0-.5-.6-.9-1.7-.9-.5 0-1 .1-1.4.3-.2 0-.3.1-.3.2v-.2c0 .4-.4.8-.8.8Z" fill-rule="nonzero"/><circle cx="12" cy="16" r="1"/></g></svg>',
'highlight-bg-color': '<svg width="24" height="24"><g fill-rule="evenodd"><path class="tox-icon-highlight-bg-color__color" d="M3 18h18v3H3z"/><path fill-rule="nonzero" d="M7.7 16.7H3l3.3-3.3-.7-.8L10.2 8l4 4.1-4 4.2c-.2.2-.6.2-.8 0l-.6-.7-1.1 1.1zm5-7.5L11 7.4l3-2.9a2 2 0 0 1 2.6 0L18 6c.7.7.7 2 0 2.7l-2.9 2.9-1.8-1.8-.5-.6"/></g></svg>',
'home': '<svg width="24" height="24"><path fill-rule="nonzero" d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>',
'horizontal-rule': '<svg width="24" height="24"><path d="M4 11h16v2H4z" fill-rule="evenodd"/></svg>',
'huddle': '<svg height="24" width="24"><path d="M10.3 5.6V8h.8v-2l3.5 2 4.3-2.5L14.6 3l-4.3 2.6zM14.6 8v5.2l4.3-2.6V5.6L14.6 8zM6 13.3v2.5h.9v-2l3.4 2 4.3-2.5-4.3-2.6zm4.3 2.6V21l4.3-2.6v-5.1l-4.3 2.6z"/></svg>',
'image-decorative': '<svg width="24" height="24"><path d="M12 10c.3 0 .5-.1.7-.3A1 1 0 0 0 13 9a1 1 0 0 0-.3-.7A1 1 0 0 0 12 8a1 1 0 0 0-.7.3 1 1 0 0 0-.3.7 1 1 0 0 0 1 1Zm0 6a3 3 0 0 1-1.8-.5A3 3 0 0 1 9.1 14a2 2 0 0 0-.2 0 3 3 0 0 1-2.5-1 3 3 0 0 1-.9-2.2A3 3 0 0 1 6.2 9a3.4 3.4 0 0 1-.5-1 3 3 0 0 1-.2-1 3 3 0 0 1 1-2.2A3 3 0 0 1 8.8 4H9a3 3 0 0 1 1.1-1.4A3 3 0 0 1 12 2a3 3 0 0 1 1.8.5c.5.4.9.9 1.1 1.5h.2a3 3 0 0 1 2.5.8 3 3 0 0 1 .9 2.3c0 .3 0 .7-.2 1a2.8 2.8 0 0 1-.5.9l.5 1 .2 1a3 3 0 0 1-1 2.2 3 3 0 0 1-2.4.9 1.8 1.8 0 0 0-.2 0 3 3 0 0 1-1.1 1.4 3 3 0 0 1-1.8.5Zm0 7a8.7 8.7 0 0 1 .7-3.5 9.2 9.2 0 0 1 2-2.8 9.2 9.2 0 0 1 2.8-2A8.6 8.6 0 0 1 21 14a8.6 8.6 0 0 1-.7 3.5 9.2 9.2 0 0 1-2 2.8 9.2 9.2 0 0 1-2.8 2 8.6 8.6 0 0 1-3.5.7Zm2.5-2.5a6.8 6.8 0 0 0 2.4-1.5 6.8 6.8 0 0 0 1.7-2.6c-1 .4-1.8 1-2.6 1.7a6.8 6.8 0 0 0-1.5 2.4ZM12 23a8.6 8.6 0 0 0-.7-3.5 9.2 9.2 0 0 0-2-2.9 9.2 9.2 0 0 0-2.8-1.9A8.6 8.6 0 0 0 3 14a8.7 8.7 0 0 0 .7 3.5 9.2 9.2 0 0 0 2 2.9 9.2 9.2 0 0 0 2.8 1.9 8.6 8.6 0 0 0 3.5.7Zm-2.5-2.5A6.8 6.8 0 0 1 7.2 19a6.8 6.8 0 0 1-1.6-2.6c.9.4 1.7 1 2.5 1.7a6.8 6.8 0 0 1 1.6 2.4Zm5.9-8.4c.3 0 .5-.1.8-.4.2-.2.3-.5.3-.8 0-.2 0-.4-.2-.6a1.3 1.3 0 0 0-.5-.4l-.8-.4a3 3 0 0 1-.2.5 3.8 3.8 0 0 1-.2.5 2.5 2.5 0 0 1-.3.4 4 4 0 0 1-.4.4l.8.6a.8.8 0 0 0 .3.1h.4ZM15 8.5l.8-.4.5-.4.2-.6a1.1 1.1 0 0 0-.3-.8 1 1 0 0 0-.8-.4 1.1 1.1 0 0 0-.7.2l-.8.6.4.4.3.4a3.9 3.9 0 0 1 .4 1Zm-4-2.3a2.7 2.7 0 0 1 1-.2 2.7 2.7 0 0 1 1 .2l.2-1.1c0-.3-.1-.6-.4-.8A1.2 1.2 0 0 0 12 4c-.3 0-.6.1-.8.3-.3.2-.4.5-.3.8v1.1Zm1 7.8c.3 0 .6-.1.8-.3.3-.2.4-.5.3-.8v-1.1a2.7 2.7 0 0 1-1.1.2 2.7 2.7 0 0 1-1-.2l-.2 1.1c0 .3.1.6.4.8.2.2.5.3.8.3ZM9 8.5a3 3 0 0 1 .4-1l.3-.4.4-.4-.8-.6A.9.9 0 0 0 9 6a1.2 1.2 0 0 0-.3 0c-.4 0-.6 0-.9.3a1.1 1.1 0 0 0-.3.8c0 .2 0 .4.2.6l.5.4.9.4Zm-.3 3.6H9l.3-.2.8-.6a5.5 5.5 0 0 1-.4-.4 2.1 2.1 0 0 1-.3-.4 3.8 3.8 0 0 1-.2-.5 3 3 0 0 1-.1-.5l-1 .4-.4.4a1.1 1.1 0 0 0-.2.6c0 .3.2.6.4.8.2.2.4.4.7.4Z"/></svg>',
'image-enhancements': '<svg height="24" width="24"><path d="M5.3 21a2 2 0 0 1-1.5-.6 2 2 0 0 1-.6-1.4V5c0-.6.2-1 .6-1.4A2 2 0 0 1 5.2 3H13v2H5.2v14h14v-8h2v8c0 .6-.1 1-.5 1.4a2 2 0 0 1-1.4.6z"/><path d="M11 9a4 4 0 0 0 4 4 4 4 0 0 0-4 4 4 4 0 0 0-4-4 4 4 0 0 0 4-4zm5.5-6c.2 2.1 2.2 4.1 4.5 4.5-2.3.4-4.3 2.4-4.5 4.5A5.2 5.2 0 0 0 12 7.5 5.2 5.2 0 0 0 16.5 3z"/></svg>',
'image-options': '<svg width="24" height="24"><path d="M6 10a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2Zm12 0a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2Zm-6 0a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2Z" fill-rule="nonzero"/></svg>',
'image': '<svg width="24" height="24"><path d="m5 15.7 3.3-3.2c.3-.3.7-.3 1 0L12 15l4.1-4c.3-.4.8-.4 1 0l2 1.9V5H5v10.7ZM5 18V19h3l2.8-2.9-2-2L5 17.9Zm14-3-2.5-2.4-6.4 6.5H19v-4ZM4 3h16c.6 0 1 .4 1 1v16c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V4c0-.6.4-1 1-1Zm6 8a2 2 0 1 0 0-4 2 2 0 0 0 0 4Z" fill-rule="nonzero"/></svg>',
'import-word': '<svg width="24" height="24"><path fill-rule="evenodd" clip-rule="evenodd" d="M7 3h7.4L19 7.6V15h-2V9h-4V5H5c0-1.1.9-2 2-2Z"/><path d="M9.5 7A1.5 1.5 0 0 1 11 8.4v7.1A1.5 1.5 0 0 1 9.6 17H2.5A1.5 1.5 0 0 1 1 15.6V8.5A1.5 1.5 0 0 1 2.4 7h7.1Zm-1 2.8-1 2.6-1-2.5v-.1a.6.6 0 0 0-1 0l-.1.1-.9 2.5-1-2.5v-.1a.6.6 0 0 0-1 .4v.1l1.5 4v.1a.6.6 0 0 0 1 0v-.1l1-2.5.9 2.5v.1a.6.6 0 0 0 1 0H8l1.6-4v-.2a.6.6 0 0 0-1.1-.4Z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M11.4 18.2a1 1 0 0 0 1.2 1.6l1.4-1V22a1 1 0 1 0 2 0v-3.1l1.4 1a1 1 0 0 0 1.2-1.7L15 15.8l-3.6 2.4Z"/></svg>',
'indent': '<svg width="24" height="24"><path d="M7 5h12c.6 0 1 .4 1 1s-.4 1-1 1H7a1 1 0 1 1 0-2Zm5 4h7c.6 0 1 .4 1 1s-.4 1-1 1h-7a1 1 0 0 1 0-2Zm0 4h7c.6 0 1 .4 1 1s-.4 1-1 1h-7a1 1 0 0 1 0-2Zm-5 4h12a1 1 0 0 1 0 2H7a1 1 0 0 1 0-2Zm-2.6-3.8L6.2 12l-1.8-1.2a1 1 0 0 1 1.2-1.6l3 2a1 1 0 0 1 0 1.6l-3 2a1 1 0 1 1-1.2-1.6Z" fill-rule="evenodd"/></svg>',
'info': '<svg width="24" height="24"><path d="M12 4a7.8 7.8 0 0 1 5.7 2.3A8 8 0 1 1 12 4Zm-1 3v2h2V7h-2Zm3 10v-1h-1v-5h-3v1h1v4h-1v1h4Z" fill-rule="evenodd"/></svg>',
'insert-character': '<svg width="24" height="24"><path d="M15 18h4l1-2v4h-6v-3.3l1.4-1a6 6 0 0 0 1.8-2.9 6.3 6.3 0 0 0-.1-4.1 5.8 5.8 0 0 0-3-3.2c-.6-.3-1.3-.5-2.1-.5a5.1 5.1 0 0 0-3.9 1.8 6.3 6.3 0 0 0-1.3 6 6.2 6.2 0 0 0 1.8 3l1.4.9V20H4v-4l1 2h4v-.5l-2-1L5.4 15A6.5 6.5 0 0 1 4 11c0-1 .2-1.9.6-2.7A7 7 0 0 1 6.3 6C7.1 5.4 8 5 9 4.5c1-.3 2-.5 3.1-.5a8.8 8.8 0 0 1 5.7 2 7 7 0 0 1 1.7 2.3 6 6 0 0 1 .2 4.8c-.2.7-.6 1.3-1 1.9a7.6 7.6 0 0 1-3.6 2.5v.5Z" fill-rule="evenodd"/></svg>',
'insert-time': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="M12 19a7 7 0 1 0 0-14 7 7 0 0 0 0 14Zm0 2a9 9 0 1 1 0-18 9 9 0 0 1 0 18Z"/><path d="M16 12h-3V7c0-.6-.4-1-1-1a1 1 0 0 0-1 1v7h5c.6 0 1-.4 1-1s-.4-1-1-1Z"/></g></svg>',
'instagram': '<svg height="24" width="24"><path clip-rule="evenodd" d="M10.1 9a4 4 0 1 1 4.4 6.6A4 4 0 0 1 10.1 9zm2.2 1.3a2 2 0 1 0 0 4 2 2 0 0 0 0-4z" fill-rule="evenodd"/><path d="M16 9.3a1.3 1.3 0 1 0 0-2.6 1.3 1.3 0 0 0 0 2.6z"/><path clip-rule="evenodd" d="M3 6a3 3 0 0 1 3-3h12a3 3 0 0 1 3 3v12a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3zm3-1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1z" fill-rule="evenodd"/></svg>',
'invert': '<svg height="24" width="24"><path d="M5 4 3.6 5.4l3.9 4C6.6 10.7 6 12.3 6 14a6 6 0 0 0 10.3 4.2l1.9 1.8 1.4-1.4z" fill-rule="evenodd"/><path d="M13.4 8.4c.9 1 1.6 2.1 2 3.2l2.6 2.6V14c0-5-6-10-6-10s-1 .8-2.1 2l1.4 1.5.7-.7 1.4 1.6z"/></svg>',
'italic': '<svg width="24" height="24"><path d="m16.7 4.7-.1.9h-.3c-.6 0-1 0-1.4.3-.3.3-.4.6-.5 1.1l-2.1 9.8v.6c0 .5.4.8 1.4.8h.2l-.2.8H8l.2-.8h.2c1.1 0 1.8-.5 2-1.5l2-9.8.1-.5c0-.6-.4-.8-1.4-.8h-.3l.2-.9h5.8Z" fill-rule="evenodd"/></svg>',
'language': '<svg width="24" height="24"><path d="M12 3a9 9 0 1 1 0 18 9 9 0 0 1 0-18Zm4.3 13.3c-.5 1-1.2 2-2 2.9a7.5 7.5 0 0 0 3.2-2.1l-.2-.2a6 6 0 0 0-1-.6Zm-8.6 0c-.5.2-.9.5-1.2.8.9 1 2 1.7 3.2 2a10 10 0 0 1-2-2.8Zm3.6-.8c-.8 0-1.6.1-2.2.3.5 1 1.2 1.9 2.1 2.7Zm1.5 0v3c.9-.8 1.6-1.7 2.1-2.7-.6-.2-1.4-.3-2.1-.3Zm-6-2.7H4.5c.2 1 .5 2.1 1 3h.3l1.3-1a10 10 0 0 1-.3-2Zm12.7 0h-2.3c0 .7-.1 1.4-.3 2l1.6 1.1c.5-1 .9-2 1-3.1Zm-3.8 0h-3V14c1 0 2 .1 2.7.4.2-.5.3-1 .3-1.6Zm-4.4 0h-3l.3 1.6c.8-.3 1.7-.4 2.7-.4v-1.3Zm-5.5-5c-.7 1-1.1 2.2-1.3 3.5h2.3c0-1 .2-1.8.5-2.6l-1.5-1Zm2.9 1.4v.1c-.2.6-.4 1.3-.4 2h3V9.4c-1 0-1.8-.1-2.6-.3Zm6.6 0h-.1l-2.4.3v1.8h3l-.5-2.1Zm3-1.4-.3.1-1.3.8c.3.8.5 1.6.5 2.6h2.3a7.5 7.5 0 0 0-1.3-3.5Zm-9 0 2 .2V5.5a9 9 0 0 0-2 2.2Zm3.5-2.3V8c.6 0 1.3 0 1.9-.2a9 9 0 0 0-2-2.3Zm-3-.7h-.1c-1.1.4-2.1 1-3 1.8l1.2.7a10 10 0 0 1 1.9-2.5Zm4.4 0 .1.1a10 10 0 0 1 1.8 2.4l1.1-.7a7.5 7.5 0 0 0-3-1.8Z"/></svg>',
'line-height': '<svg width="24" height="24"><path d="M21 5a1 1 0 0 1 .1 2H13a1 1 0 0 1-.1-2H21zm0 4a1 1 0 0 1 .1 2H13a1 1 0 0 1-.1-2H21zm0 4a1 1 0 0 1 .1 2H13a1 1 0 0 1-.1-2H21zm0 4a1 1 0 0 1 .1 2H13a1 1 0 0 1-.1-2H21zM7 3.6l3.7 3.7a1 1 0 0 1-1.3 1.5h-.1L8 7.3v9.2l1.3-1.3a1 1 0 0 1 1.3 0h.1c.4.4.4 1 0 1.3v.1L7 20.4l-3.7-3.7a1 1 0 0 1 1.3-1.5h.1L6 16.7V7.4L4.7 8.7a1 1 0 0 1-1.3 0h-.1a1 1 0 0 1 0-1.3v-.1L7 3.6z"/></svg>',
'line': '<svg width="24" height="24"><path d="m15 9-8 8H4v-3l8-8 3 3Zm1-1-3-3 1-1h1c-.2 0 0 0 0 0l2 2s0 .2 0 0v1l-1 1ZM4 18h16v2H4v-2Z" fill-rule="evenodd"/></svg>',
'link': '<svg width="24" height="24"><path d="M6.2 12.3a1 1 0 0 1 1.4 1.4l-2 2a2 2 0 1 0 2.6 2.8l4.8-4.8a1 1 0 0 0 0-1.4 1 1 0 1 1 1.4-1.3 2.9 2.9 0 0 1 0 4L9.6 20a3.9 3.9 0 0 1-5.5-5.5l2-2Zm11.6-.6a1 1 0 0 1-1.4-1.4l2-2a2 2 0 1 0-2.6-2.8L11 10.3a1 1 0 0 0 0 1.4A1 1 0 1 1 9.6 13a2.9 2.9 0 0 1 0-4L14.4 4a3.9 3.9 0 0 1 5.5 5.5l-2 2Z" fill-rule="nonzero"/></svg>',
'list-bull-circle': '<svg height="48" width="48"><path d="M8 14a3 3 0 1 0 6 0 3 3 0 0 0-6 0zm5 0a2 2 0 1 1-4 0 2 2 0 0 1 4 0zM8 24a3 3 0 1 0 6 0 3 3 0 0 0-6 0zm5 0a2 2 0 1 1-4 0 2 2 0 0 1 4 0zM8 34a3 3 0 1 0 6 0 3 3 0 0 0-6 0zm5 0a2 2 0 1 1-4 0 2 2 0 0 1 4 0z" fill-rule="evenodd"/><path d="M18 12h22v4H18zm0 10h22v4H18zm0 10h22v4H18z" opacity=".2"/></svg>',
'list-bull-default': '<svg height="48" width="48"><path d="M14 14a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/><path d="M12 24a3 3 0 1 0 6 0 3 3 0 0 0-6 0zm5 0a2 2 0 1 1-4 0 2 2 0 0 1 4 0z" fill-rule="evenodd"/><path d="M16 31h6v6h-6z"/><path d="M16 31h6v6h-6z"/><path d="M18 12h22v4H18zm4 10h18v4H22zm4 10h14v4H26z" opacity=".2"/></svg>',
'list-bull-disc': '<svg height="48" width="48"><path d="M14 14a3 3 0 1 1-6 0 3 3 0 0 1 6 0zm0 10a3 3 0 1 1-6 0 3 3 0 0 1 6 0zm0 10a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/><path d="M18 12h22v4H18zm0 10h22v4H18zm0 10h22v4H18z" opacity=".2"/></svg>',
'list-bull-square': '<svg height="48" width="48"><path d="M8 21h6v6H8zm0 10h6v6H8zm0-20h6v6H8z"/><path d="M18 12h22v4H18zm0 10h22v4H18zm0 10h22v4H18z" opacity=".2"/></svg>',
'list-num-default-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="M37.4 17v-4.8h-.1l-1.5 1v-1.1l1.6-1.1h1.2v6zM33.3 17.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm1.7 5.7c0-1.2 1-2 2.2-2 1.3 0 2.1.8 2.1 1.8 0 .7-.3 1.2-1.3 2.2l-1.2 1v.2h2.6v1h-4.3v-.9l2-1.9c.8-.8 1-1.1 1-1.5 0-.5-.4-.8-1-.8-.5 0-.9.3-.9.9H35zm-1.7 4.3c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm3.2 7.3v-1h.7c.6 0 1-.3 1-.8 0-.4-.4-.7-1-.7s-1 .3-1 .8H35c0-1.1 1-1.8 2.2-1.8 1.2 0 2.1.6 2.1 1.6 0 .7-.4 1.2-1 1.3v.1c.7.1 1.3.7 1.3 1.4 0 1-1 1.9-2.4 1.9-1.3 0-2.2-.8-2.3-2h1.2c0 .6.5 1 1.1 1 .6 0 1-.4 1-1 0-.5-.3-.8-1-.8h-.7zm-3.3 2.7c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7z"/></g></svg>',
'list-num-default': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="M10 17v-4.8l-1.5 1v-1.1l1.6-1h1.2V17h-1.2Zm3.6.1c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .7.3.7.7 0 .4-.2.7-.7.7Zm-5 5.7c0-1.2.8-2 2.1-2s2.1.8 2.1 1.8c0 .7-.3 1.2-1.4 2.2l-1.1 1v.2h2.6v1H8.6v-.9l2-1.9c.8-.8 1-1.1 1-1.5 0-.5-.4-.8-1-.8-.5 0-.9.3-.9.9H8.5Zm6.3 4.3c-.5 0-.7-.3-.7-.7 0-.4.2-.7.7-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7ZM10 34.4v-1h.7c.6 0 1-.3 1-.8 0-.4-.4-.7-1-.7s-1 .3-1 .8H8.6c0-1.1 1-1.8 2.2-1.8 1.3 0 2.1.6 2.1 1.6 0 .7-.4 1.2-1 1.3v.1c.8.1 1.3.7 1.3 1.4 0 1-1 1.9-2.4 1.9-1.3 0-2.2-.8-2.3-2h1.2c0 .6.5 1 1.1 1 .7 0 1-.4 1-1 0-.5-.3-.8-1-.8h-.7Zm4.7 2.7c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7Z"/></g></svg>',
'list-num-lower-alpha-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="M36.5 16c-.9 0-1.5-.5-1.5-1.3s.6-1.3 1.8-1.4h1v-.4c0-.4-.2-.6-.7-.6-.4 0-.7.1-.8.4h-1.1c0-.8.8-1.4 2-1.4S39 12 39 13V16h-1.2v-.6c-.3.4-.8.7-1.4.7Zm.4-.8c.6 0 1-.4 1-.9V14h-1c-.5.1-.7.3-.7.6 0 .4.3.6.7.6ZM33.1 16.1c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7ZM37.7 26c-.7 0-1.2-.2-1.5-.7v.7H35v-6.3h1.2v2.5c.3-.5.8-.9 1.5-.9 1.1 0 1.8 1 1.8 2.4 0 1.5-.7 2.4-1.8 2.4Zm-.5-3.6c-.6 0-1 .5-1 1.3s.4 1.4 1 1.4c.7 0 1-.6 1-1.4 0-.8-.3-1.3-1-1.3ZM33.2 26.1c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7zm6 7h-1c-.1-.5-.4-.8-1-.8s-1 .5-1 1.4c0 1 .4 1.4 1 1.4.5 0 .9-.2 1-.7h1c0 1-.8 1.7-2 1.7-1.4 0-2.2-.9-2.2-2.4s.8-2.4 2.2-2.4c1.2 0 2 .7 2 1.7zm-6.1 3c-.5 0-.7-.3-.7-.7 0-.4.2-.7.7-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z"/></g></svg>',
'list-num-lower-alpha': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="M10.3 15.2c.5 0 1-.4 1-.9V14h-1c-.5.1-.8.3-.8.6 0 .4.3.6.8.6Zm-.4.9c-1 0-1.5-.6-1.5-1.4 0-.8.6-1.3 1.7-1.4h1.1v-.4c0-.4-.2-.6-.7-.6-.5 0-.8.1-.9.4h-1c0-.8.8-1.4 2-1.4 1.1 0 1.8.6 1.8 1.6V16h-1.1v-.6h-.1c-.2.4-.7.7-1.3.7Zm4.6 0c-.5 0-.7-.3-.7-.7 0-.4.2-.7.7-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7Zm-3.2 10c-.6 0-1.2-.3-1.4-.8v.7H8.5v-6.3H10v2.5c.3-.5.8-.9 1.4-.9 1.2 0 1.9 1 1.9 2.4 0 1.5-.7 2.4-1.9 2.4Zm-.4-3.7c-.7 0-1 .5-1 1.3s.3 1.4 1 1.4c.6 0 1-.6 1-1.4 0-.8-.4-1.3-1-1.3Zm4 3.7c-.5 0-.7-.3-.7-.7 0-.4.2-.7.7-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7Zm-2.2 7h-1.2c0-.5-.4-.8-.9-.8-.6 0-1 .5-1 1.4 0 1 .4 1.4 1 1.4.5 0 .8-.2 1-.7h1c0 1-.8 1.7-2 1.7-1.4 0-2.2-.9-2.2-2.4s.8-2.4 2.2-2.4c1.2 0 2 .7 2 1.7Zm1.8 3c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7Z"/></g></svg>',
'list-num-lower-greek-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="M37.4 16c-1.2 0-2-.8-2-2.3 0-1.5.8-2.4 2-2.4.6 0 1 .4 1.3 1v-.9H40v3.2c0 .4.1.5.4.5h.2v.9h-.6c-.6 0-1-.2-1-.7h-.2c-.2.4-.7.8-1.3.8Zm.3-1c.6 0 1-.5 1-1.3s-.4-1.3-1-1.3-1 .5-1 1.3.4 1.4 1 1.4ZM33.3 16.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7ZM36 21.9c0-1.5.8-2.3 2.1-2.3 1.2 0 2 .6 2 1.6 0 .6-.3 1-.9 1.3.9.3 1.3.8 1.3 1.7 0 1.2-.7 1.9-1.8 1.9-.6 0-1.1-.3-1.4-.8v2.2H36V22Zm1.8 1.2v-1h.3c.5 0 .9-.2.9-.7 0-.5-.3-.8-.9-.8-.5 0-.8.3-.8 1v2.2c0 .8.4 1.3 1 1.3s1-.4 1-1-.4-1-1.2-1h-.3ZM33.3 26.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7ZM37.1 34.6 34.8 30h1.4l1.7 3.5 1.7-3.5h1.1l-2.2 4.6v.1c.5.8.7 1.4.7 1.8 0 .4-.2.8-.4 1-.2.2-.6.3-1 .3-.9 0-1.3-.4-1.3-1.2 0-.5.2-1 .5-1.7l.1-.2Zm.7 1a2 2 0 0 0-.4.9c0 .3.1.4.4.4.3 0 .4-.1.4-.4 0-.2-.1-.6-.4-1ZM33.3 36.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7Z"/></g></svg>',
'list-num-lower-greek': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="M10.5 15c.7 0 1-.5 1-1.3s-.3-1.3-1-1.3c-.5 0-.9.5-.9 1.3s.4 1.4 1 1.4Zm-.3 1c-1.1 0-1.8-.8-1.8-2.3 0-1.5.7-2.4 1.8-2.4.7 0 1.1.4 1.3 1h.1v-.9h1.2v3.2c0 .4.1.5.4.5h.2v.9h-.6c-.6 0-1-.2-1.1-.7h-.1c-.2.4-.7.8-1.4.8Zm5 .1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7Zm-4.9 7v-1h.3c.6 0 1-.2 1-.7 0-.5-.4-.8-1-.8-.5 0-.8.3-.8 1v2.2c0 .8.4 1.3 1.1 1.3.6 0 1-.4 1-1s-.5-1-1.3-1h-.3ZM8.6 22c0-1.5.7-2.3 2-2.3 1.2 0 2 .6 2 1.6 0 .6-.3 1-.8 1.3.8.3 1.3.8 1.3 1.7 0 1.2-.8 1.9-1.9 1.9-.6 0-1.1-.3-1.3-.8v2.2H8.5V22Zm6.2 4.2c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .7.3.7.7 0 .4-.2.7-.7.7Zm-4.5 8.5L8 30h1.4l1.7 3.5 1.7-3.5h1.1l-2.2 4.6v.1c.5.8.7 1.4.7 1.8 0 .4-.1.8-.4 1-.2.2-.6.3-1 .3-.9 0-1.3-.4-1.3-1.2 0-.5.2-1 .5-1.7l.1-.2Zm.7 1a2 2 0 0 0-.4.9c0 .3.1.4.4.4.3 0 .4-.1.4-.4 0-.2-.1-.6-.4-1Zm4.5.5c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7Z"/></g></svg>',
'list-num-lower-roman-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="M32.9 16v-1.2h-1.3V16H33Zm0 10v-1.2h-1.3V26H33Zm0 10v-1.2h-1.3V36H33Z"/><path fill-rule="nonzero" d="M36 21h-1.5v5H36zM36 31h-1.5v5H36zM39 21h-1.5v5H39zM39 31h-1.5v5H39zM42 31h-1.5v5H42zM36 11h-1.5v5H36zM36 19h-1.5v1H36zM36 29h-1.5v1H36zM39 19h-1.5v1H39zM39 29h-1.5v1H39zM42 29h-1.5v1H42zM36 9h-1.5v1H36z"/></g></svg>',
'list-num-lower-roman': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="M15.1 16v-1.2h1.3V16H15Zm0 10v-1.2h1.3V26H15Zm0 10v-1.2h1.3V36H15Z"/><path fill-rule="nonzero" d="M12 21h1.5v5H12zM12 31h1.5v5H12zM9 21h1.5v5H9zM9 31h1.5v5H9zM6 31h1.5v5H6zM12 11h1.5v5H12zM12 19h1.5v1H12zM12 29h1.5v1H12zM9 19h1.5v1H9zM9 29h1.5v1H9zM6 29h1.5v1H6zM12 9h1.5v1H12z"/></g></svg>',
'list-num-upper-alpha-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="m39.3 17-.5-1.4h-2l-.5 1.4H35l2-6h1.6l2 6h-1.3Zm-1.6-4.7-.7 2.3h1.6l-.8-2.3ZM33.4 17c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .7.3.7.7 0 .4-.2.7-.7.7Zm4.7 9.9h-2.7v-6H38c1.2 0 1.9.6 1.9 1.5 0 .6-.5 1.2-1 1.3.7.1 1.3.7 1.3 1.5 0 1-.8 1.7-2 1.7Zm-1.4-5v1.5h1c.6 0 1-.3 1-.8 0-.4-.4-.7-1-.7h-1Zm0 4h1.1c.7 0 1.1-.3 1.1-.8 0-.6-.4-.9-1.1-.9h-1.1V26ZM33 27.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7Zm4.9 10c-1.8 0-2.8-1.1-2.8-3.1s1-3.1 2.8-3.1c1.4 0 2.5.9 2.6 2.2h-1.3c0-.7-.6-1.1-1.3-1.1-1 0-1.6.7-1.6 2s.6 2 1.6 2c.7 0 1.2-.4 1.4-1h1.2c-.1 1.3-1.2 2.2-2.6 2.2Zm-4.5 0c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7Z"/></g></svg>',
'list-num-upper-alpha': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="m12.6 17-.5-1.4h-2L9.5 17H8.3l2-6H12l2 6h-1.3ZM11 12.3l-.7 2.3h1.6l-.8-2.3Zm4.7 4.8c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .7.3.7.7 0 .4-.2.7-.7.7ZM11.4 27H8.7v-6h2.6c1.2 0 1.9.6 1.9 1.5 0 .6-.5 1.2-1 1.3.7.1 1.3.7 1.3 1.5 0 1-.8 1.7-2 1.7ZM10 22v1.5h1c.6 0 1-.3 1-.8 0-.4-.4-.7-1-.7h-1Zm0 4H11c.7 0 1.1-.3 1.1-.8 0-.6-.4-.9-1.1-.9H10V26Zm5.4 1.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7Zm-4.1 10c-1.8 0-2.8-1.1-2.8-3.1s1-3.1 2.8-3.1c1.4 0 2.5.9 2.6 2.2h-1.3c0-.7-.6-1.1-1.3-1.1-1 0-1.6.7-1.6 2s.6 2 1.6 2c.7 0 1.2-.4 1.4-1h1.2c-.1 1.3-1.2 2.2-2.6 2.2Zm4.5 0c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7Z"/></g></svg>',
'list-num-upper-roman-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="M31.6 17v-1.2H33V17h-1.3Zm0 10v-1.2H33V27h-1.3Zm0 10v-1.2H33V37h-1.3Z"/><path fill-rule="nonzero" d="M34.5 20H36v7h-1.5zM34.5 30H36v7h-1.5zM37.5 20H39v7h-1.5zM37.5 30H39v7h-1.5zM40.5 30H42v7h-1.5zM34.5 10H36v7h-1.5z"/></g></svg>',
'list-num-upper-roman': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="M15.1 17v-1.2h1.3V17H15Zm0 10v-1.2h1.3V27H15Zm0 10v-1.2h1.3V37H15Z"/><path fill-rule="nonzero" d="M12 20h1.5v7H12zM12 30h1.5v7H12zM9 20h1.5v7H9zM9 30h1.5v7H9zM6 30h1.5v7H6zM12 10h1.5v7H12z"/></g></svg>',
'lock': '<svg width="24" height="24"><path d="M16.3 11c.2 0 .3 0 .5.2l.2.6v7.4c0 .3 0 .4-.2.6l-.6.2H7.8c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6v-7.4c0-.3 0-.4.2-.6l.5-.2H8V8c0-.8.3-1.5.9-2.1.6-.6 1.3-.9 2.1-.9h2c.8 0 1.5.3 2.1.9.6.6.9 1.3.9 2.1v3h.3ZM10 8v3h4V8a1 1 0 0 0-.3-.7A1 1 0 0 0 13 7h-2a1 1 0 0 0-.7.3 1 1 0 0 0-.3.7Z" fill-rule="evenodd"/></svg>',
'ltr': '<svg width="24" height="24"><path d="M11 5h7a1 1 0 0 1 0 2h-1v11a1 1 0 0 1-2 0V7h-2v11a1 1 0 0 1-2 0v-6c-.5 0-1 0-1.4-.3A3.4 3.4 0 0 1 7.8 10a3.3 3.3 0 0 1 0-2.8 3.4 3.4 0 0 1 1.8-1.8L11 5ZM4.4 16.2 6.2 15l-1.8-1.2a1 1 0 0 1 1.2-1.6l3 2a1 1 0 0 1 0 1.6l-3 2a1 1 0 1 1-1.2-1.6Z" fill-rule="evenodd"/></svg>',
'math-equation': '<svg width="24" height="24"><path fill-rule="evenodd" clip-rule="evenodd" d="M9 4.8c.1-.5.5-.8 1-.8h10a1 1 0 1 1 0 2h-9.2L8.3 19.2a1 1 0 0 1-1.7.4l-3.4-4.2a1 1 0 0 1 1.6-1.2l2 2.5L9 4.8Zm9.7 5.5c.4.4.4 1 0 1.4L17 13.5l1.8 1.8a1 1 0 1 1-1.4 1.4L15.5 15l-1.8 1.8a1 1 0 0 1-1.4-1.4l1.8-1.8-1.8-1.8a1 1 0 0 1 1.4-1.4l1.8 1.8 1.8-1.8a1 1 0 0 1 1.4 0Z"/></svg>',
'mentions': '<svg height="24" width="24"><path d="M12 21a8.8 8.8 0 0 1-3.5-.7 9 9 0 0 1-2.9-2 9 9 0 0 1-1.9-2.8A8.8 8.8 0 0 1 3 12c0-1.3.2-2.4.7-3.5a9 9 0 0 1 4.8-4.8A8.8 8.8 0 0 1 12 3c1.3 0 2.4.2 3.5.7a9.1 9.1 0 0 1 4.8 4.8A8.7 8.7 0 0 1 21 12v1.4a3 3 0 0 1-.9 2.2 3 3 0 0 1-2.2.9c-.5 0-1-.1-1.5-.4a3.8 3.8 0 0 1-1.1-1 4.8 4.8 0 0 1-1.5 1 4.3 4.3 0 0 1-1.8.4c-1.2 0-2.3-.4-3.2-1.3-.9-.9-1.3-2-1.3-3.2s.4-2.3 1.3-3.2c.9-.9 2-1.3 3.2-1.3s2.3.4 3.2 1.3c.9.9 1.3 2 1.3 3.2v1.4c0 .4.1.7.4 1 .3.3.6.4 1 .4s.7-.1 1-.4c.3-.3.4-.6.4-1V12c0-2-.7-3.8-2.1-5.2S14 4.7 12 4.7s-3.8.7-5.2 2.1S4.7 10 4.7 12s.7 3.8 2.1 5.2 3.2 2.1 5.2 2.1h4.5V21zm0-6.2c.8 0 1.4-.3 2-.8a2.7 2.7 0 0 0 .8-2c0-.8-.3-1.4-.8-2a2.7 2.7 0 0 0-2-.8c-.8 0-1.4.3-2 .8a2.7 2.7 0 0 0-.8 2c0 .8.3 1.4.8 2a2.7 2.7 0 0 0 2 .8z"/></svg>',
'minus': '<svg width="24" height="24"><path d="M19 11a1 1 0 0 1 .1 2H5a1 1 0 0 1-.1-2H19Z"/></svg>',
'more-drawer': '<svg width="24" height="24"><path d="M6 10a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2Zm12 0a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2Zm-6 0a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2Z" fill-rule="nonzero"/></svg>',
'new-document': '<svg width="24" height="24"><path d="M14.4 3H7a2 2 0 0 0-2 2v14c0 1.1.9 2 2 2h10a2 2 0 0 0 2-2V7.6L14.4 3ZM17 19H7V5h6v4h4v10Z" fill-rule="nonzero"/></svg>',
'new-tab': '<svg width="24" height="24"><path d="m15 13 2-2v8H5V7h8l-2 2H7v8h8v-4Zm4-8v5.5l-2-2-5.6 5.5H10v-1.4L15.5 7l-2-2H19Z" fill-rule="evenodd"/></svg>',
'non-breaking': '<svg width="24" height="24"><path d="M11 11H8a1 1 0 1 1 0-2h3V6c0-.6.4-1 1-1s1 .4 1 1v3h3c.6 0 1 .4 1 1s-.4 1-1 1h-3v3c0 .6-.4 1-1 1a1 1 0 0 1-1-1v-3Zm10 4v5H3v-5c0-.6.4-1 1-1s1 .4 1 1v3h14v-3c0-.6.4-1 1-1s1 .4 1 1Z" fill-rule="evenodd"/></svg>',
'notice': '<svg width="24" height="24"><path d="M15.5 4 20 8.5v7L15.5 20h-7L4 15.5v-7L8.5 4h7ZM13 17v-2h-2v2h2Zm0-4V7h-2v6h2Z" fill-rule="evenodd" clip-rule="evenodd"/></svg>',
'onedrive': '<svg height="24" width="24"><path d="M4 13.7h1zm16 .7h-1zm-11.7-4A4.4 4.4 0 0 1 12.1 8V6a6.4 6.4 0 0 0-5.6 3.4l1.8 1zM12.1 8c2 0 3.6 1.4 4 2.8l2-.5A6.3 6.3 0 0 0 12 6v2zm8.1 6.8-9.8-5.5-1 1.8 9.8 5.5 1-1.8zm-9.8-5.5A5 5 0 0 0 3 13.7h2A3 3 0 0 1 9.5 11l1-1.8zM3 13.7a5 5 0 0 0 1 2.8l1.5-1.1a3 3 0 0 1-.5-1.7zm15.8 1.6a2.3 2.3 0 0 1-2 1.4v2a4.3 4.3 0 0 0 3.9-2.6zm-2 1.4H8v2h8.7zm-8.8 0a3 3 0 0 1-2.5-1.3L4 16.5a5 5 0 0 0 4 2.2v-2zm12.7-.6c.2-.6.3-1.1.3-1.7h-2c0 .3 0 .6-.2.9zm.3-1.7c0-3-3.1-5.1-6-4l.8 1.9a2.3 2.3 0 0 1 3.2 2h2zm-6-4L4.4 15l.8 1.9 10.7-4.6-.7-1.8z"/></svg>',
'ordered-list-rtl': '<svg width="24" height="24"><path d="M6 17h8a1 1 0 0 1 0 2H6a1 1 0 0 1 0-2Zm0-6h8a1 1 0 0 1 0 2H6a1 1 0 0 1 0-2Zm0-6h8a1 1 0 0 1 0 2H6a1 1 0 1 1 0-2Zm13-1v3.5a.5.5 0 1 1-1 0V5h-.5a.5.5 0 1 1 0-1H19Zm-1 8.8.2.2h1.3a.5.5 0 1 1 0 1h-1.6a1 1 0 0 1-.9-1V13c0-.4.3-.8.6-1l1.2-.4.2-.3a.2.2 0 0 0-.2-.2h-1.3a.5.5 0 0 1-.5-.5c0-.3.2-.5.5-.5h1.6c.5 0 .9.4.9 1v.1c0 .4-.3.8-.6 1l-1.2.4-.2.3Zm2 4.2v2c0 .6-.4 1-1 1h-1.5a.5.5 0 0 1 0-1h1.2a.3.3 0 1 0 0-.6h-1.3a.4.4 0 1 1 0-.8h1.3a.3.3 0 0 0 0-.6h-1.2a.5.5 0 1 1 0-1H19c.6 0 1 .4 1 1Z" fill-rule="evenodd"/></svg>',
'ordered-list': '<svg width="24" height="24"><path d="M10 17h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2Zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2Zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 1 1 0-2ZM6 4v3.5c0 .3-.2.5-.5.5a.5.5 0 0 1-.5-.5V5h-.5a.5.5 0 0 1 0-1H6Zm-1 8.8.2.2h1.3c.3 0 .5.2.5.5s-.2.5-.5.5H4.9a1 1 0 0 1-.9-1V13c0-.4.3-.8.6-1l1.2-.4.2-.3a.2.2 0 0 0-.2-.2H4.5a.5.5 0 0 1-.5-.5c0-.3.2-.5.5-.5h1.6c.5 0 .9.4.9 1v.1c0 .4-.3.8-.6 1l-1.2.4-.2.3ZM7 17v2c0 .6-.4 1-1 1H4.5a.5.5 0 0 1 0-1h1.2c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3H4.4a.4.4 0 1 1 0-.8h1.3c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3H4.5a.5.5 0 1 1 0-1H6c.6 0 1 .4 1 1Z" fill-rule="evenodd"/></svg>',
'orientation': '<svg width="24" height="24"><path d="M7.3 6.4 1 13l6.4 6.5 6.5-6.5-6.5-6.5ZM3.7 13l3.6-3.7L11 13l-3.7 3.7-3.6-3.7ZM12 6l2.8 2.7c.3.3.3.8 0 1-.3.4-.9.4-1.2 0L9.2 5.7a.8.8 0 0 1 0-1.2L13.6.2c.3-.3.9-.3 1.2 0 .3.3.3.8 0 1.1L12 4h1a9 9 0 1 1-4.3 16.9l1.5-1.5A7 7 0 1 0 13 6h-1Z" fill-rule="nonzero"/></svg>',
'outdent': '<svg width="24" height="24"><path d="M7 5h12c.6 0 1 .4 1 1s-.4 1-1 1H7a1 1 0 1 1 0-2Zm5 4h7c.6 0 1 .4 1 1s-.4 1-1 1h-7a1 1 0 0 1 0-2Zm0 4h7c.6 0 1 .4 1 1s-.4 1-1 1h-7a1 1 0 0 1 0-2Zm-5 4h12a1 1 0 0 1 0 2H7a1 1 0 0 1 0-2Zm1.6-3.8a1 1 0 0 1-1.2 1.6l-3-2a1 1 0 0 1 0-1.6l3-2a1 1 0 0 1 1.2 1.6L6.8 12l1.8 1.2Z" fill-rule="evenodd"/></svg>',
'page-break': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M5 11c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2Zm3 0h1c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 0 1 0-2Zm4 0c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2Zm3 0h1c.6 0 1 .4 1 1s-.4 1-1 1h-1a1 1 0 0 1 0-2Zm4 0c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2ZM7 3v5h10V3c0-.6.4-1 1-1s1 .4 1 1v7H5V3c0-.6.4-1 1-1s1 .4 1 1ZM6 22a1 1 0 0 1-1-1v-7h14v7c0 .6-.4 1-1 1a1 1 0 0 1-1-1v-5H7v5c0 .6-.4 1-1 1Z"/></g></svg>',
'paragraph': '<svg width="24" height="24"><path fill-rule="evenodd" d="M10 5h7a1 1 0 0 1 0 2h-1v11a1 1 0 0 1-2 0V7h-2v11a1 1 0 0 1-2 0v-6c-.5 0-1 0-1.4-.3A3.4 3.4 0 0 1 6.8 10a3.3 3.3 0 0 1 0-2.8 3.4 3.4 0 0 1 1.8-1.8L10 5Z"/></svg>',
'paste-column-after': '<svg width="24" height="24"><path fill-rule="evenodd" d="M12 1a3 3 0 0 1 2.8 2H18c1 0 2 .8 2 1.9V7h-2V5h-2v1c0 .6-.4 1-1 1H9a1 1 0 0 1-1-1V5H6v13h7v2H6c-1 0-2-.8-2-1.9V5c0-1 .8-2 1.9-2H9.2A3 3 0 0 1 12 1Zm8 7v12h-6V8h6Zm-1.5 1.5h-3v9h3v-9ZM12 3a1 1 0 1 0 0 2 1 1 0 0 0 0-2Z"/></svg>',
'paste-column-before': '<svg width="24" height="24"><path fill-rule="evenodd" d="M12 1a3 3 0 0 1 2.8 2H18c1 0 2 .8 2 1.9V18c0 1-.8 2-1.9 2H11v-2h7V5h-2v1c0 .6-.4 1-1 1H9a1 1 0 0 1-1-1V5H6v2H4V5c0-1 .8-2 1.9-2H9.2A3 3 0 0 1 12 1Zm-2 7v12H4V8h6ZM8.5 9.5h-3v9h3v-9ZM12 3a1 1 0 1 0 0 2 1 1 0 0 0 0-2Z"/></svg>',
'paste-row-after': '<svg width="24" height="24"><path fill-rule="evenodd" d="M12 1a3 3 0 0 1 2.8 2H18c1 0 2 .8 2 1.9V11h-2V5h-2v1c0 .6-.4 1-1 1H9a1 1 0 0 1-1-1V5H6v13h14c0 1-.8 2-1.9 2H6c-1 0-2-.8-2-1.9V5c0-1 .8-2 1.9-2H9.2A3 3 0 0 1 12 1Zm10 11v5H8v-5h14Zm-1.5 1.5h-11v2h11v-2ZM12 3a1 1 0 1 0 0 2 1 1 0 0 0 0-2Z"/></svg>',
'paste-row-before': '<svg width="24" height="24"><path fill-rule="evenodd" d="M12 1a3 3 0 0 1 2.8 2H18c1 0 2 .8 2 1.9V7h-2V5h-2v1c0 .6-.4 1-1 1H9a1 1 0 0 1-1-1V5H6v13h12v-4h2v4c0 1-.8 2-1.9 2H6c-1 0-2-.8-2-1.9V5c0-1 .8-2 1.9-2H9.2A3 3 0 0 1 12 1Zm10 7v5H8V8h14Zm-1.5 1.5h-11v2h11v-2ZM12 3a1 1 0 1 0 0 2 1 1 0 0 0 0-2Z"/></svg>',
'paste-text': '<svg width="24" height="24"><path d="M18 9V5h-2v1c0 .6-.4 1-1 1H9a1 1 0 0 1-1-1V5H6v13h3V9h9ZM9 20H6a2 2 0 0 1-2-2V5c0-1.1.9-2 2-2h3.2A3 3 0 0 1 12 1a3 3 0 0 1 2.8 2H18a2 2 0 0 1 2 2v4h1v12H9v-1Zm1.5-9.5v9h9v-9h-9ZM12 3a1 1 0 0 0-1 1c0 .5.4 1 1 1s1-.5 1-1-.4-1-1-1Zm0 9h6v2h-.5l-.5-1h-1v4h.8v1h-3.6v-1h.8v-4h-1l-.5 1H12v-2Z" fill-rule="nonzero"/></svg>',
'paste': '<svg width="24" height="24"><path d="M18 9V5h-2v1c0 .6-.4 1-1 1H9a1 1 0 0 1-1-1V5H6v13h3V9h9ZM9 20H6a2 2 0 0 1-2-2V5c0-1.1.9-2 2-2h3.2A3 3 0 0 1 12 1a3 3 0 0 1 2.8 2H18a2 2 0 0 1 2 2v4h1v12H9v-1Zm1.5-9.5v9h9v-9h-9ZM12 3a1 1 0 0 0-1 1c0 .5.4 1 1 1s1-.5 1-1-.4-1-1-1Z" fill-rule="nonzero"/></svg>',
'permanent-pen': '<svg width="24" height="24"><path d="M10.5 17.5 8 20H3v-3l3.5-3.5a2 2 0 0 1 0-3L14 3l1 1-7.3 7.3a1 1 0 0 0 0 1.4l3.6 3.6c.4.4 1 .4 1.4 0L20 9l1 1-7.6 7.6a2 2 0 0 1-2.8 0l-.1-.1Z" fill-rule="nonzero"/></svg>',
'photo-filter': '<svg height="24" width="24"><path d="M4.4 21c-.3 0-.6-.2-.9-.5-.3-.3-.4-.6-.5-.9L19.6 3c.3 0 .6.3.9.5l.5.9zM3 14.7v-2.8L11.9 3h2.8zM3 7V5c0-.6.2-1 .6-1.4A2 2 0 0 1 5 3h2zm14 14 4-4v2c0 .6-.2 1-.6 1.4a2 2 0 0 1-1.4.6zm-7.7 0L21 9.3v2.8L12 21z"/></svg>',
'plus': '<svg width="24" height="24"><path d="M12 4c.5 0 1 .4 1 .9V11h6a1 1 0 0 1 .1 2H13v6a1 1 0 0 1-2 .1V13H5a1 1 0 0 1-.1-2H11V5c0-.6.4-1 1-1Z"/></svg>',
'preferences': '<svg width="24" height="24"><path d="m20.1 13.5-1.9.2a5.8 5.8 0 0 1-.6 1.5l1.2 1.5c.4.4.3 1 0 1.4l-.7.7a1 1 0 0 1-1.4 0l-1.5-1.2a6.2 6.2 0 0 1-1.5.6l-.2 1.9c0 .5-.5.9-1 .9h-1a1 1 0 0 1-1-.9l-.2-1.9a5.8 5.8 0 0 1-1.5-.6l-1.5 1.2a1 1 0 0 1-1.4 0l-.7-.7a1 1 0 0 1 0-1.4l1.2-1.5a6.2 6.2 0 0 1-.6-1.5l-1.9-.2a1 1 0 0 1-.9-1v-1c0-.5.4-1 .9-1l1.9-.2a5.8 5.8 0 0 1 .6-1.5L5.2 7.3a1 1 0 0 1 0-1.4l.7-.7a1 1 0 0 1 1.4 0l1.5 1.2a6.2 6.2 0 0 1 1.5-.6l.2-1.9c0-.5.5-.9 1-.9h1c.5 0 1 .4 1 .9l.2 1.9a5.8 5.8 0 0 1 1.5.6l1.5-1.2a1 1 0 0 1 1.4 0l.7.7c.3.4.4 1 0 1.4l-1.2 1.5a6.2 6.2 0 0 1 .6 1.5l1.9.2c.5 0 .9.5.9 1v1c0 .5-.4 1-.9 1ZM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" fill-rule="evenodd"/></svg>',
'preview': '<svg width="24" height="24"><path d="M3.5 12.5c.5.8 1.1 1.6 1.8 2.3 2 2 4.2 3.2 6.7 3.2s4.7-1.2 6.7-3.2a16.2 16.2 0 0 0 2.1-2.8 15.7 15.7 0 0 0-2.1-2.8c-2-2-4.2-3.2-6.7-3.2a9.3 9.3 0 0 0-6.7 3.2A16.2 16.2 0 0 0 3.2 12c0 .2.2.3.3.5Zm-2.4-1 .7-1.2L4 7.8C6.2 5.4 8.9 4 12 4c3 0 5.8 1.4 8.1 3.8a18.2 18.2 0 0 1 2.8 3.7v1l-.7 1.2-2.1 2.5c-2.3 2.4-5 3.8-8.1 3.8-3 0-5.8-1.4-8.1-3.8a18.2 18.2 0 0 1-2.8-3.7 1 1 0 0 1 0-1Zm12-3.3a2 2 0 1 0 2.7 2.6 4 4 0 1 1-2.6-2.6Z" fill-rule="nonzero"/></svg>',
'print': '<svg width="24" height="24"><path d="M18 8H6a3 3 0 0 0-3 3v6h2v3h14v-3h2v-6a3 3 0 0 0-3-3Zm-1 10H7v-4h10v4Zm.5-5c-.8 0-1.5-.7-1.5-1.5s.7-1.5 1.5-1.5 1.5.7 1.5 1.5-.7 1.5-1.5 1.5Zm.5-8H6v2h12V5Z" fill-rule="nonzero"/></svg>',
'quote': '<svg width="24" height="24"><path d="M7.5 17h.9c.4 0 .7-.2.9-.6L11 13V8c0-.6-.4-1-1-1H6a1 1 0 0 0-1 1v4c0 .6.4 1 1 1h2l-1.3 2.7a1 1 0 0 0 .8 1.3Zm8 0h.9c.4 0 .7-.2.9-.6L19 13V8c0-.6-.4-1-1-1h-4a1 1 0 0 0-1 1v4c0 .6.4 1 1 1h2l-1.3 2.7a1 1 0 0 0 .8 1.3Z" fill-rule="nonzero"/></svg>',
'redo': '<svg width="24" height="24"><path d="M17.6 10H12c-2.8 0-4.4 1.4-4.9 3.5-.4 2 .3 4 1.4 4.6a1 1 0 1 1-1 1.8c-2-1.2-2.9-4.1-2.3-6.8.6-3 3-5.1 6.8-5.1h5.6l-3.3-3.3a1 1 0 1 1 1.4-1.4l5 5a1 1 0 0 1 0 1.4l-5 5a1 1 0 0 1-1.4-1.4l3.3-3.3Z" fill-rule="nonzero"/></svg>',
'reload': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="m5 22.1-1.2-4.7v-.2a1 1 0 0 1 1-1l5 .4a1 1 0 1 1-.2 2l-2.2-.2a7.8 7.8 0 0 0 8.4.2 7.5 7.5 0 0 0 3.5-6.4 1 1 0 1 1 2 0 9.5 9.5 0 0 1-4.5 8 9.9 9.9 0 0 1-10.2 0l.4 1.4a1 1 0 1 1-2 .5ZM13.6 7.4c0-.5.5-1 1-.9l2.8.2a8 8 0 0 0-9.5-1 7.5 7.5 0 0 0-3.6 7 1 1 0 0 1-2 0 9.5 9.5 0 0 1 4.5-8.6 10 10 0 0 1 10.9.3l-.3-1a1 1 0 0 1 2-.5l1.1 4.8a1 1 0 0 1-1 1.2l-5-.4a1 1 0 0 1-.9-1Z"/></g></svg>',
'remove-formatting': '<svg width="24" height="24"><path d="M13.2 6a1 1 0 0 1 0 .2l-2.6 10a1 1 0 0 1-1 .8h-.2a.8.8 0 0 1-.8-1l2.6-10H8a1 1 0 1 1 0-2h9a1 1 0 0 1 0 2h-3.8ZM5 18h7a1 1 0 0 1 0 2H5a1 1 0 0 1 0-2Zm13 1.5L16.5 18 15 19.5a.7.7 0 0 1-1-1l1.5-1.5-1.5-1.5a.7.7 0 0 1 1-1l1.5 1.5 1.5-1.5a.7.7 0 0 1 1 1L17.5 17l1.5 1.5a.7.7 0 0 1-1 1Z" fill-rule="evenodd"/></svg>',
'remove': '<svg width="24" height="24"><path d="M16 7h3a1 1 0 0 1 0 2h-1v9a3 3 0 0 1-3 3H9a3 3 0 0 1-3-3V9H5a1 1 0 1 1 0-2h3V6a3 3 0 0 1 3-3h2a3 3 0 0 1 3 3v1Zm-2 0V6c0-.6-.4-1-1-1h-2a1 1 0 0 0-1 1v1h4Zm2 2H8v9c0 .6.4 1 1 1h6c.6 0 1-.4 1-1V9Zm-7 3a1 1 0 0 1 2 0v4a1 1 0 0 1-2 0v-4Zm4 0a1 1 0 0 1 2 0v4a1 1 0 0 1-2 0v-4Z" fill-rule="nonzero"/></svg>',
'resize-handle': '<svg width="10" height="10"><g fill-rule="nonzero"><path d="M8.1 1.1A.5.5 0 1 1 9 2l-7 7A.5.5 0 1 1 1 8l7-7ZM8.1 5.1A.5.5 0 1 1 9 6l-3 3A.5.5 0 1 1 5 8l3-3Z"/></g></svg>',
'resize': '<svg width="24" height="24"><path d="M4 5c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h6c.3 0 .5.1.7.3.2.2.3.4.3.7 0 .3-.1.5-.3.7a1 1 0 0 1-.7.3H7.4L18 16.6V13c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3.3 0 .5.1.7.3.2.2.3.4.3.7v6c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3h-6a1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h3.6L6 7.4V11c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3 1 1 0 0 1-.7-.3A1 1 0 0 1 4 11V5Z" fill-rule="evenodd"/></svg>',
'restore-draft': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M17 13c0 .6-.4 1-1 1h-4V8c0-.6.4-1 1-1s1 .4 1 1v4h2c.6 0 1 .4 1 1Z"/><path d="M4.7 10H9a1 1 0 0 1 0 2H3a1 1 0 0 1-1-1V5a1 1 0 1 1 2 0v3l2.5-2.4a9.2 9.2 0 0 1 10.8-1.5A9 9 0 0 1 13.4 21c-2.4.1-4.7-.7-6.5-2.2a1 1 0 1 1 1.3-1.5 7.2 7.2 0 0 0 11.6-3.7 7 7 0 0 0-3.5-7.7A7.2 7.2 0 0 0 8 7L4.7 10Z" fill-rule="nonzero"/></g></svg>',
'revert-changes': '<svg height="24" width="24"><path d="m8.9 18.8.4 3.2H13v-2h-2v-2.6a4.6 4.6 0 0 1-1.6-.6 5.9 5.9 0 0 1-1.3-1l-2.5 1-1-1.7 2.2-1.6a4 4 0 0 1-.2-.7 5.9 5.9 0 0 1 0-.8v-.8l.2-.8-2.2-1.6 1-1.7 2.5 1a6 6 0 0 1 1.2-.9l1.4-.6.4-2.6h2l.3 2.6A5.6 5.6 0 0 1 16 8.2l2.5-1 1 1.6-2.2 1.7.2.7v.8a5 5 0 0 1 0 1h2a2.6 2.6 0 0 0 0-.5V11.3l2.6-2-2.8-4.7-3 1.3a8.2 8.2 0 0 0-.5-.4 3.8 3.8 0 0 0-.6-.3L14.8 2H9.3l-.4 3.2a5 5 0 0 0-1.2.7l-3-1.3L2 9.4l2.6 2V12.6l-2.6 2 2.7 4.7 3-1.3a8 8 0 0 0 1.2.7z"/><path d="m14.5 20.3 2.1-2-2.1-2.2 1.4-1.4 2.1 2.1 2.1-2 1.4 1.3-2 2.1 2 2.1-1.4 1.4-2.1-2-2.1 2zM12 14a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></svg>',
'revision-history': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M17 13c0 .6-.4 1-1 1h-4V8c0-.6.4-1 1-1s1 .4 1 1v4h2c.6 0 1 .4 1 1Z"/><path d="M4.7 10H9a1 1 0 0 1 0 2H3a1 1 0 0 1-1-1V5a1 1 0 1 1 2 0v3l2.5-2.4a9.2 9.2 0 0 1 10.8-1.5A9 9 0 0 1 13.4 21c-2.4.1-4.7-.7-6.5-2.2a1 1 0 1 1 1.3-1.5 7.2 7.2 0 0 0 11.6-3.7 7 7 0 0 0-3.5-7.7A7.2 7.2 0 0 0 8 7L4.7 10Z" fill-rule="nonzero"/></g></svg>',
'rotate-left': '<svg width="24" height="24"><path d="M4.7 10H9a1 1 0 0 1 0 2H3a1 1 0 0 1-1-1V5a1 1 0 1 1 2 0v3l2.5-2.4a9.2 9.2 0 0 1 10.8-1.5A9 9 0 0 1 13.4 21c-2.4.1-4.7-.7-6.5-2.2a1 1 0 1 1 1.3-1.5 7.2 7.2 0 0 0 11.6-3.7 7 7 0 0 0-3.5-7.7A7.2 7.2 0 0 0 8 7L4.7 10Z" fill-rule="nonzero"/></svg>',
'rotate-right': '<svg width="24" height="24"><path d="M20 8V5a1 1 0 0 1 2 0v6c0 .6-.4 1-1 1h-6a1 1 0 0 1 0-2h4.3L16 7A7.2 7.2 0 0 0 7.7 6a7 7 0 0 0 3 13.1c1.9.1 3.7-.5 5-1.7a1 1 0 0 1 1.4 1.5A9.2 9.2 0 0 1 2.2 14c-.9-3.9 1-8 4.5-9.9 3.5-1.9 8-1.3 10.8 1.5L20 8Z" fill-rule="nonzero"/></svg>',
'rtl': '<svg width="24" height="24"><path d="M8 5h8v2h-2v12h-2V7h-2v12H8v-7c-.5 0-1 0-1.4-.3A3.4 3.4 0 0 1 4.8 10a3.3 3.3 0 0 1 0-2.8 3.4 3.4 0 0 1 1.8-1.8L8 5Zm12 11.2a1 1 0 1 1-1 1.6l-3-2a1 1 0 0 1 0-1.6l3-2a1 1 0 1 1 1 1.6L18.4 15l1.8 1.2Z" fill-rule="evenodd"/></svg>',
'saturation': '<svg width="24" height="24"><path fill-rule="evenodd" d="M12 20.5a6 6 0 1 1-5.9-10.2 6 6 0 1 1 11.8 0A6 6 0 1 1 12 20.5Zm-1.1-7.7a6 6 0 0 0-.2.3 4.3 4.3 0 0 1-2-1.3c.9.1 1.6.5 2.2 1Zm2.4.3a6 6 0 0 0-.2-.3 4.3 4.3 0 0 1 2.2-1 4.3 4.3 0 0 1-2 1.3ZM12.2 15a6.3 6.3 0 0 1-.4 0 4.3 4.3 0 0 0 .2 2.5 4.3 4.3 0 0 0 .2-2.5Zm.9 4.2a6 6 0 0 0 .8-4.5 6 6 0 0 0 3.4-2.8 4.3 4.3 0 0 1-1.3 8.4 4.3 4.3 0 0 1-2.9-1.1Zm-2.2 0a4.3 4.3 0 1 1-4.2-7.3 6 6 0 0 0 3.4 2.8 6 6 0 0 0 .8 4.5Zm-3-9.2a4.3 4.3 0 1 1 8.3 0 6 6 0 0 0-4.2 1.5A6 6 0 0 0 7.8 10Z"/></svg>',
'save': '<svg width="24" height="24"><path d="M5 16h14a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-2c0-1.1.9-2 2-2Zm0 2v2h14v-2H5Zm10 0h2v2h-2v-2Zm-4-6.4L8.7 9.3a1 1 0 1 0-1.4 1.4l4 4c.4.4 1 .4 1.4 0l4-4a1 1 0 1 0-1.4-1.4L13 11.6V4a1 1 0 0 0-2 0v7.6Z" fill-rule="nonzero"/></svg>',
'search': '<svg width="24" height="24"><path d="M16 17.3a8 8 0 1 1 1.4-1.4l4.3 4.4a1 1 0 0 1-1.4 1.4l-4.4-4.3Zm-5-.3a6 6 0 1 0 0-12 6 6 0 0 0 0 12Z" fill-rule="nonzero"/></svg>',
'select-all': '<svg width="24" height="24"><path d="M3 5h2V3a2 2 0 0 0-2 2Zm0 8h2v-2H3v2Zm4 8h2v-2H7v2ZM3 9h2V7H3v2Zm10-6h-2v2h2V3Zm6 0v2h2a2 2 0 0 0-2-2ZM5 21v-2H3c0 1.1.9 2 2 2Zm-2-4h2v-2H3v2ZM9 3H7v2h2V3Zm2 18h2v-2h-2v2Zm8-8h2v-2h-2v2Zm0 8a2 2 0 0 0 2-2h-2v2Zm0-12h2V7h-2v2Zm0 8h2v-2h-2v2Zm-4 4h2v-2h-2v2Zm0-16h2V3h-2v2ZM7 17h10V7H7v10Zm2-8h6v6H9V9Z" fill-rule="nonzero"/></svg>',
'selected': '<svg width="24" height="24"><path fill-rule="nonzero" d="M6 4h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2Zm3.6 10.9L7 12.3a.7.7 0 0 0-1 1L9.6 17 18 8.6a.7.7 0 0 0 0-1 .7.7 0 0 0-1 0l-7.4 7.3Z"/></svg>',
'send': '<svg width="24" height="24"><path fill-rule="evenodd" clip-rule="evenodd" d="m13.3 22 7-18.3-18.3 7L9 15l4.3 7ZM18 6.8l-.7-.7L9.4 14l.7.7L18 6.8Z"/></svg>',
'settings': '<svg width="24" height="24"><path d="M11 6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8v.3c0 .2 0 .3-.2.5l-.6.2H7.8c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6V8H5a1 1 0 1 1 0-2h2v-.3c0-.2 0-.3.2-.5l.5-.2h2.5c.3 0 .4 0 .6.2l.2.5V6ZM8 8h2V6H8v2Zm9 2.8v.2h2c.6 0 1 .4 1 1s-.4 1-1 1h-2v.3c0 .2 0 .3-.2.5l-.6.2h-2.4c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6V13H5a1 1 0 0 1 0-2h8v-.3c0-.2 0-.3.2-.5l.6-.2h2.4c.3 0 .4 0 .6.2l.2.6ZM14 13h2v-2h-2v2Zm-3 2.8v.2h8c.6 0 1 .4 1 1s-.4 1-1 1h-8v.3c0 .2 0 .3-.2.5l-.6.2H7.8c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6V18H5a1 1 0 0 1 0-2h2v-.3c0-.2 0-.3.2-.5l.5-.2h2.5c.3 0 .4 0 .6.2l.2.6ZM8 18h2v-2H8v2Z" fill-rule="evenodd"/></svg>',
'sharpen': '<svg width="24" height="24"><path fill-rule="evenodd" d="m16 6 4 4-8 9-8-9 4-4h8Zm-4 10.2 5.5-6.2-.1-.1H12v-.3h5.1l-.2-.2H12V9h4.6l-.2-.2H12v-.3h4.1l-.2-.2H12V8h3.6l-.2-.2H8.7L6.5 10l.1.1H12v.3H6.9l.2.2H12v.3H7.3l.2.2H12v.3H7.7l.3.2h4v.3H8.2l.2.2H12v.3H8.6l.3.2H12v.3H9l.3.2H12v.3H9.5l.2.2H12v.3h-2l.2.2H12v.3h-1.6l.2.2H12v.3h-1.1l.2.2h.9v.3h-.7l.2.2h.5v.3h-.3l.3.2Z"/></svg>',
'sourcecode': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="M9.8 15.7c.3.3.3.8 0 1-.3.4-.9.4-1.2 0l-4.4-4.1a.8.8 0 0 1 0-1.2l4.4-4.2c.3-.3.9-.3 1.2 0 .3.3.3.8 0 1.1L6 12l3.8 3.7ZM14.2 15.7c-.3.3-.3.8 0 1 .4.4.9.4 1.2 0l4.4-4.1c.3-.3.3-.9 0-1.2l-4.4-4.2a.8.8 0 0 0-1.2 0c-.3.3-.3.8 0 1.1L18 12l-3.8 3.7Z"/></g></svg>',
'spell-check': '<svg width="24" height="24"><path d="M6 8v3H5V5c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h2c.3 0 .5.1.7.3.2.2.3.4.3.7v6H8V8H6Zm0-3v2h2V5H6Zm13 0h-3v5h3v1h-3a1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7V5c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h3v1Zm-5 1.5-.1.7c-.1.2-.3.3-.6.3.3 0 .5.1.6.3l.1.7V10c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3h-3V4h3c.3 0 .5.1.7.3.2.2.3.4.3.7v1.5ZM13 10V8h-2v2h2Zm0-3V5h-2v2h2Zm3 5 1 1-6.5 7L7 15.5l1.3-1 2.2 2.2L16 12Z" fill-rule="evenodd"/></svg>',
'strike-through': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M15.6 8.5c-.5-.7-1-1.1-1.3-1.3-.6-.4-1.3-.6-2-.6-2.7 0-2.8 1.7-2.8 2.1 0 1.6 1.8 2 3.2 2.3 4.4.9 4.6 2.8 4.6 3.9 0 1.4-.7 4.1-5 4.1A6.2 6.2 0 0 1 7 16.4l1.5-1.1c.4.6 1.6 2 3.7 2 1.6 0 2.5-.4 3-1.2.4-.8.3-2-.8-2.6-.7-.4-1.6-.7-2.9-1-1-.2-3.9-.8-3.9-3.6C7.6 6 10.3 5 12.4 5c2.9 0 4.2 1.6 4.7 2.4l-1.5 1.1Z"/><path d="M5 11h14a1 1 0 0 1 0 2H5a1 1 0 0 1 0-2Z" fill-rule="nonzero"/></g></svg>',
'subscript': '<svg width="24" height="24"><path d="m10.4 10 4.6 4.6-1.4 1.4L9 11.4 4.4 16 3 14.6 7.6 10 3 5.4 4.4 4 9 8.6 13.6 4 15 5.4 10.4 10ZM21 19h-5v-1l1-.8 1.7-1.6c.3-.4.5-.8.5-1.2 0-.3 0-.6-.2-.7-.2-.2-.5-.3-.9-.3a2 2 0 0 0-.8.2l-.7.3-.4-1.1 1-.6 1.2-.2c.8 0 1.4.3 1.8.7.4.4.6.9.6 1.5s-.2 1.1-.5 1.6a8 8 0 0 1-1.3 1.3l-.6.6h2.6V19Z" fill-rule="nonzero"/></svg>',
'suggestededits-badge': '<svg height="24" width="24"><path d="M11 3H7a2 2 0 0 0-2 2v14c0 1.1.9 2 2 2h10a2 2 0 0 0 2-2V9.7a6 6 0 0 1-2 .3v9H7V5h4a6 6 0 0 1 0-2z"/><path d="M15 13v-2h-4v2zm-3 2H9v2h3zm-1-8H9v2h2zm4 10v-2h-2v2z"/><path d="M21 4a4 4 0 1 1-8 0 4 4 0 0 1 8 0z" class="tox-icon--badge"/></svg>',
'suggestededits': '<svg width="24" height="24"><path d="M7 3h7.4L19 7.6V19a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V5c0-1.1.9-2 2-2Zm0 16h10V9h-3V5H7v14Z" clip-rule="evenodd"/><path d="M9 7h2v2H9V7Zm2 4h4v2h-4v-2Zm-2 4h3v2H9v-2Z"/><path d="M9 7h2v2H9V7Zm4 8h2v2h-2v-2Z"/></svg>',
'superscript': '<svg width="24" height="24"><path d="M15 9.4 10.4 14l4.6 4.6-1.4 1.4L9 15.4 4.4 20 3 18.6 7.6 14 3 9.4 4.4 8 9 12.6 13.6 8 15 9.4Zm5.9 1.6h-5v-1l1-.8 1.7-1.6c.3-.5.5-.9.5-1.3 0-.3 0-.5-.2-.7-.2-.2-.5-.3-.9-.3l-.8.2-.7.4-.4-1.2c.2-.2.5-.4 1-.5.3-.2.8-.2 1.2-.2.8 0 1.4.2 1.8.6.4.4.6 1 .6 1.6 0 .5-.2 1-.5 1.5l-1.3 1.4-.6.5h2.6V11Z" fill-rule="nonzero"/></svg>',
'table-caption': '<svg width="24" height="24"><g fill-rule="nonzero"><rect width="12" height="2" x="3" y="4" rx="1"/><path d="M19 8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-8c0-1.1.9-2 2-2h14ZM5 15v3h6v-3H5Zm14 0h-6v3h6v-3Zm0-5h-6v3h6v-3ZM5 13h6v-3H5v3Z"/></g></svg>',
'table-cell-classes': '<svg width="24" height="24"><g fill-rule="evenodd"><path fill-rule="nonzero" d="M13 4v9H3V6c0-1.1.9-2 2-2h8Zm-2 2H5v5h6V6Z"/><path fill-rule="nonzero" d="M13 4h6a2 2 0 0 1 2 2v7h-8v-2h6V6h-6V4Z" opacity=".2"/><path d="m18 20-2.6 1.6.7-3-2.4-2 3.1-.2 1.2-2.9 1.2 2.9 3.1.2-2.4 2 .7 3z"/><path fill-rule="nonzero" d="M3 13v5c0 1.1.9 2 2 2h8v-7h-2v5H5v-5H3Z" opacity=".2"/></g></svg>',
'table-cell-properties': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14Zm-8 9H5v5h6v-5Zm8 0h-6v5h6v-5Zm-8-7H5v5h6V6Z"/></svg>',
'table-cell-select-all': '<svg width="24" height="24"><g fill-rule="evenodd"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14Zm0 2H5v12h14V6Z"/><path d="M13 6v5h6v2h-6v5h-2v-5H5v-2h6V6h2Z" opacity=".2"/></g></svg>',
'table-cell-select-inner': '<svg width="24" height="24"><g fill-rule="evenodd"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14Zm0 2H5v12h14V6Z" opacity=".2"/><path d="M13 6v5h6v2h-6v5h-2v-5H5v-2h6V6h2Z"/></g></svg>',
'table-classes': '<svg width="24" height="24"><g fill-rule="evenodd"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v7h-8v7H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14Zm-8 9H5v5h6v-5Zm8-7h-6v5h6V6Zm-8 0H5v5h6V6Z"/><path d="m18 20-2.6 1.6.7-3-2.4-2 3.1-.2 1.2-2.9 1.2 2.9 3.1.2-2.4 2 .7 3z"/></g></svg>',
'table-delete-column': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14Zm-4 4h-2V6h-2v2H9V6H5v12h4v-2h2v2h2v-2h2v2h4V6h-4v2Zm.3.5 1 1.2-3 2.3 3 2.3-1 1.2L12 13l-3.3 2.6-1-1.2 3-2.3-3-2.3 1-1.2L12 11l3.3-2.5Z"/></svg>',
'table-delete-row': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14Zm0 2H5v3h2.5v2H5v2h2.5v2H5v3h14v-3h-2.5v-2H19v-2h-2.5V9H19V6Zm-4.7 1.8 1.2 1L13 12l2.6 3.3-1.2 1-2.3-3-2.3 3-1.2-1L11 12 8.5 8.7l1.2-1 2.3 3 2.3-3Z"/></svg>',
'table-delete-table': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14ZM5 6v12h14V6H5Z"/><path d="m14.4 8.6 1.1 1-2.4 2.4 2.4 2.4-1.1 1.1-2.4-2.4-2.4 2.4-1-1.1 2.3-2.4-2.3-2.4 1-1 2.4 2.3z"/></g></svg>',
'table-insert-column-after': '<svg width="24" height="24"><path fill-rule="nonzero" d="M20 4c.6 0 1 .4 1 1v2a1 1 0 0 1-2 0V6h-8v12h8v-1a1 1 0 0 1 2 0v2c0 .5-.4 1-.9 1H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h15ZM9 13H5v5h4v-5Zm7-5c.5 0 1 .4 1 .9V11h2a1 1 0 0 1 .1 2H17v2a1 1 0 0 1-2 .1V13h-2a1 1 0 0 1-.1-2H15V9c0-.6.4-1 1-1ZM9 6H5v5h4V6Z"/></svg>',
'table-insert-column-before': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a1 1 0 0 1-1-1v-2a1 1 0 0 1 2 0v1h8V6H5v1a1 1 0 1 1-2 0V5c0-.6.4-1 1-1h15Zm0 9h-4v5h4v-5ZM8 8c.5 0 1 .4 1 .9V11h2a1 1 0 0 1 .1 2H9v2a1 1 0 0 1-2 .1V13H5a1 1 0 0 1-.1-2H7V9c0-.6.4-1 1-1Zm11-2h-4v5h4V6Z"/></svg>',
'table-insert-row-above': '<svg width="24" height="24"><path fill-rule="nonzero" d="M6 4a1 1 0 1 1 0 2H5v6h14V6h-1a1 1 0 0 1 0-2h2c.6 0 1 .4 1 1v13a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5c0-.6.4-1 1-1h2Zm5 10H5v4h6v-4Zm8 0h-6v4h6v-4ZM12 3c.5 0 1 .4 1 .9V6h2a1 1 0 0 1 0 2h-2v2a1 1 0 0 1-2 .1V8H9a1 1 0 0 1 0-2h2V4c0-.6.4-1 1-1Z"/></svg>',
'table-insert-row-after': '<svg width="24" height="24"><path fill-rule="nonzero" d="M12 13c.5 0 1 .4 1 .9V16h2a1 1 0 0 1 .1 2H13v2a1 1 0 0 1-2 .1V18H9a1 1 0 0 1-.1-2H11v-2c0-.6.4-1 1-1Zm6 7a1 1 0 0 1 0-2h1v-6H5v6h1a1 1 0 0 1 0 2H4a1 1 0 0 1-1-1V6c0-1.1.9-2 2-2h14a2 2 0 0 1 2 2v13c0 .5-.4 1-.9 1H18ZM11 6H5v4h6V6Zm8 0h-6v4h6V6Z"/></svg>',
'table-left-header': '<svg width="24" height="24"><path d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14Zm0 9h-4v5h4v-5Zm-6 0H9v5h4v-5Zm0-7H9v5h4V6Zm6 0h-4v5h4V6Z"/></svg>',
'table-merge-cells': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14ZM5 15.5V18h3v-2.5H5Zm14-5h-9V18h9v-7.5ZM19 6h-4v2.5h4V6ZM8 6H5v2.5h3V6Zm5 0h-3v2.5h3V6Zm-8 7.5h3v-3H5v3Z"/></svg>',
'table-row-numbering-rtl': '<svg width="24" height="24"><path d="M6 4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2h12a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H6Zm0 12h8v3H6v-3Zm11 0c.6 0 1 .4 1 1v1a1 1 0 0 1-2 0v-1c0-.6.4-1 1-1ZM6 11h8v3H6v-3Zm11 0c.6 0 1 .4 1 1v1a1 1 0 0 1-2 0v-1c0-.6.4-1 1-1ZM6 6h8v3H6V6Zm11 0c.6 0 1 .4 1 1v1a1 1 0 1 1-2 0V7c0-.6.4-1 1-1Z"/></svg>',
'table-row-numbering': '<svg width="24" height="24"><path d="M18 4a2 2 0 0 1 2 2v13a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h12Zm0 12h-8v3h8v-3ZM7 16a1 1 0 0 0-1 1v1a1 1 0 0 0 2 0v-1c0-.6-.4-1-1-1Zm11-5h-8v3h8v-3ZM7 11a1 1 0 0 0-1 1v1a1 1 0 0 0 2 0v-1c0-.6-.4-1-1-1Zm11-5h-8v3h8V6ZM7 6a1 1 0 0 0-1 1v1a1 1 0 1 0 2 0V7c0-.6-.4-1-1-1Z"/></svg>',
'table-row-properties': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14ZM5 15v3h6v-3H5Zm14 0h-6v3h6v-3Zm0-9h-6v3h6V6ZM5 9h6V6H5v3Z"/></svg>',
'table-split-cells': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14ZM8 15.5H5V18h3v-2.5Zm11-5h-9V18h9v-7.5Zm-2.5 1 1 1-2 2 2 2-1 1-2-2-2 2-1-1 2-2-2-2 1-1 2 2 2-2Zm-8.5-1H5v3h3v-3ZM19 6h-4v2.5h4V6ZM8 6H5v2.5h3V6Zm5 0h-3v2.5h3V6Z"/></svg>',
'table-top-header': '<svg width="24" height="24"><path d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14Zm-8 11H5v3h6v-3Zm8 0h-6v3h6v-3Zm0-5h-6v3h6v-3ZM5 13h6v-3H5v3Z"/></svg>',
'table': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14ZM5 14v4h6v-4H5Zm14 0h-6v4h6v-4Zm0-6h-6v4h6V8ZM5 12h6V8H5v4Z"/></svg>',
'template-add': '<svg width="24" height="24"><path fill-rule="evenodd" clip-rule="evenodd" d="M9 12v4H5a2 2 0 0 0-2 2v3h9.3a6 6 0 0 1-.3-2H5v-1h7a6 6 0 0 1 .8-2H11v-5l-.8-.6a3 3 0 1 1 3.6 0l-.8.6v4.7a6 6 0 0 1 2-1.9V12a5 5 0 1 0-6 0Z"/><path d="M18 15c.5 0 1 .4 1 .9V18h2a1 1 0 0 1 .1 2H19v2a1 1 0 0 1-2 .1V20h-2a1 1 0 0 1-.1-2H17v-2c0-.6.4-1 1-1Z"/></svg>',
'template': '<svg width="24" height="24"><path d="M19 19v-1H5v1h14ZM9 16v-4a5 5 0 1 1 6 0v4h4a2 2 0 0 1 2 2v3H3v-3c0-1.1.9-2 2-2h4Zm4 0v-5l.8-.6a3 3 0 1 0-3.6 0l.8.6v5h2Z" fill-rule="nonzero"/></svg>',
'temporary-placeholder': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M9 7.6V6h2.5V4.5a.5.5 0 1 1 1 0V6H15v1.6a8 8 0 1 1-6 0Zm-2.6 5.3a.5.5 0 0 0 .3.6c.3 0 .6 0 .6-.3l.1-.2a5 5 0 0 1 3.3-2.8c.3-.1.4-.4.4-.6-.1-.3-.4-.5-.6-.4a6 6 0 0 0-4.1 3.7Z"/><circle cx="14" cy="4" r="1"/><circle cx="12" cy="2" r="1"/><circle cx="10" cy="4" r="1"/></g></svg>',
'text-color': '<svg width="24" height="24"><g fill-rule="evenodd"><path class="tox-icon-text-color__color" d="M3 18h18v3H3z"/><path d="M8.7 16h-.8a.5.5 0 0 1-.5-.6l2.7-9c.1-.3.3-.4.5-.4h2.8c.2 0 .4.1.5.4l2.7 9a.5.5 0 0 1-.5.6h-.8a.5.5 0 0 1-.4-.4l-.7-2.2c0-.3-.3-.4-.5-.4h-3.4c-.2 0-.4.1-.5.4l-.7 2.2c0 .3-.2.4-.4.4Zm2.6-7.6-.6 2a.5.5 0 0 0 .5.6h1.6a.5.5 0 0 0 .5-.6l-.6-2c0-.3-.3-.4-.5-.4h-.4c-.2 0-.4.1-.5.4Z"/></g></svg>',
'text-size-decrease': '<svg width="24" height="24"><path fill-rule="evenodd" clip-rule="evenodd" d="M14 5a1 1 0 1 1 0 2h-4v11a1 1 0 1 1-2 0V7H4a1 1 0 0 1 0-2h10ZM14 12a1 1 0 1 0 0 2h6a1 1 0 1 0 0-2h-6Z"/></svg>',
'text-size-increase': '<svg width="24" height="24"><path fill-rule="evenodd" clip-rule="evenodd" d="M14 5a1 1 0 1 1 0 2h-4v11a1 1 0 1 1-2 0V7H4a1 1 0 0 1 0-2h10ZM17 9a1 1 0 0 0-1 1v2h-2a1 1 0 1 0 0 2h2v2a1 1 0 1 0 2 0v-2h2a1 1 0 1 0 0-2h-2v-2c0-.6-.4-1-1-1Z"/></svg>',
'toc': '<svg width="24" height="24"><path d="M5 5c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 1 1 0-2Zm3 0h11c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 1 1 0-2Zm-3 8c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2Zm3 0h11c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 0 1 0-2Zm0-4c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 1 1 0-2Zm3 0h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2Zm-3 8c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2Zm3 0h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2Z" fill-rule="evenodd"/></svg>',
'transform-image': '<svg height="24" width="24"><path d="M3 21v-6h2V9H3V3h6v2h6V3h6v6h-2v6h2v6h-6v-2H9v2zm6-4h6v-2h2V9h-2V7H9v2H7v6h2zM5 7h2V5H5zm12 0h2V5h-2zm0 12h2v-2h-2zM5 19h2v-2H5z"/></svg>',
'translate': '<svg width="24" height="24"><path d="m12.7 14.3-.3.7-.4.7-2.2-2.2-3.1 3c-.3.4-.8.4-1 0a.7.7 0 0 1 0-1l3.1-3A12.4 12.4 0 0 1 6.7 9H8a10.1 10.1 0 0 0 1.7 2.4c.5-.5 1-1.1 1.4-1.8l.9-2H4.7a.7.7 0 1 1 0-1.5h4.4v-.7c0-.4.3-.8.7-.8.4 0 .7.4.7.8v.7H15c.4 0 .8.3.8.7 0 .4-.4.8-.8.8h-1.4a12.3 12.3 0 0 1-1 2.4 13.5 13.5 0 0 1-1.7 2.3l1.9 1.8Zm4.3-3 2.7 7.3a.5.5 0 0 1-.4.7 1 1 0 0 1-1-.7l-.6-1.5h-3.4l-.6 1.5a1 1 0 0 1-1 .7.5.5 0 0 1-.4-.7l2.7-7.4a1 1 0 0 1 2 0Zm-2.2 4.4h2.4L16 12.5l-1.2 3.2Z" fill-rule="evenodd"/></svg>',
'typography': '<svg width="24" height="24"><path fill-rule="evenodd" clip-rule="evenodd" d="M17 5a1 1 0 1 1 0 2h-4v11a1 1 0 1 1-2 0V7H7a1 1 0 0 1 0-2h10Z"/><path d="m17.5 14 .8-1.7 1.7-.8-1.7-.8-.8-1.7-.8 1.7-1.7.8 1.7.8.8 1.7ZM7 14l1 2 2 1-2 1-1 2-1-2-2-1 2-1 1-2Z"/></svg>',
'underline': '<svg width="24" height="24"><path d="M16 5c.6 0 1 .4 1 1v5.5a4 4 0 0 1-.4 1.8l-1 1.4a5.3 5.3 0 0 1-5.5 1 5 5 0 0 1-1.6-1c-.5-.4-.8-.9-1.1-1.4a4 4 0 0 1-.4-1.8V6c0-.6.4-1 1-1s1 .4 1 1v5.5c0 .3 0 .6.2 1l.6.7a3.3 3.3 0 0 0 2.2.8 3.4 3.4 0 0 0 2.2-.8c.3-.2.4-.5.6-.8l.2-.9V6c0-.6.4-1 1-1ZM8 17h8c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 0 1 0-2Z" fill-rule="evenodd"/></svg>',
'undo': '<svg width="24" height="24"><path d="M6.4 8H12c3.7 0 6.2 2 6.8 5.1.6 2.7-.4 5.6-2.3 6.8a1 1 0 0 1-1-1.8c1.1-.6 1.8-2.7 1.4-4.6-.5-2.1-2.1-3.5-4.9-3.5H6.4l3.3 3.3a1 1 0 1 1-1.4 1.4l-5-5a1 1 0 0 1 0-1.4l5-5a1 1 0 0 1 1.4 1.4L6.4 8Z" fill-rule="nonzero"/></svg>',
'unlink': '<svg width="24" height="24"><path d="M6.2 12.3a1 1 0 0 1 1.4 1.4l-2 2a2 2 0 1 0 2.6 2.8l4.8-4.8a1 1 0 0 0 0-1.4 1 1 0 1 1 1.4-1.3 2.9 2.9 0 0 1 0 4L9.6 20a3.9 3.9 0 0 1-5.5-5.5l2-2Zm11.6-.6a1 1 0 0 1-1.4-1.4l2.1-2a2 2 0 1 0-2.7-2.8L11 10.3a1 1 0 0 0 0 1.4A1 1 0 1 1 9.6 13a2.9 2.9 0 0 1 0-4L14.4 4a3.9 3.9 0 0 1 5.5 5.5l-2 2ZM7.6 6.3a.8.8 0 0 1-1 1.1L3.3 4.2a.7.7 0 1 1 1-1l3.2 3.1ZM5.1 8.6a.8.8 0 0 1 0 1.5H3a.8.8 0 0 1 0-1.5H5Zm5-3.5a.8.8 0 0 1-1.5 0V3a.8.8 0 0 1 1.5 0V5Zm6 11.8a.8.8 0 0 1 1-1l3.2 3.2a.8.8 0 0 1-1 1L16 17Zm-2.2 2a.8.8 0 0 1 1.5 0V21a.8.8 0 0 1-1.5 0V19Zm5-3.5a.7.7 0 1 1 0-1.5H21a.8.8 0 0 1 0 1.5H19Z" fill-rule="nonzero"/></svg>',
'unlock': '<svg width="24" height="24"><path d="M16 5c.8 0 1.5.3 2.1.9.6.6.9 1.3.9 2.1v3h-2V8a1 1 0 0 0-.3-.7A1 1 0 0 0 16 7h-2a1 1 0 0 0-.7.3 1 1 0 0 0-.3.7v3h.3c.2 0 .3 0 .5.2l.2.6v7.4c0 .3 0 .4-.2.6l-.6.2H4.8c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6v-7.4c0-.3 0-.4.2-.6l.5-.2H11V8c0-.8.3-1.5.9-2.1.6-.6 1.3-.9 2.1-.9h2Z" fill-rule="evenodd"/></svg>',
'unordered-list': '<svg width="24" height="24"><path d="M11 5h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2Zm0 6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2Zm0 6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2ZM4.5 6c0-.4.1-.8.4-1 .3-.4.7-.5 1.1-.5.4 0 .8.1 1 .4.4.3.5.7.5 1.1 0 .4-.1.8-.4 1-.3.4-.7.5-1.1.5-.4 0-.8-.1-1-.4-.4-.3-.5-.7-.5-1.1Zm0 6c0-.4.1-.8.4-1 .3-.4.7-.5 1.1-.5.4 0 .8.1 1 .4.4.3.5.7.5 1.1 0 .4-.1.8-.4 1-.3.4-.7.5-1.1.5-.4 0-.8-.1-1-.4-.4-.3-.5-.7-.5-1.1Zm0 6c0-.4.1-.8.4-1 .3-.4.7-.5 1.1-.5.4 0 .8.1 1 .4.4.3.5.7.5 1.1 0 .4-.1.8-.4 1-.3.4-.7.5-1.1.5-.4 0-.8-.1-1-.4-.4-.3-.5-.7-.5-1.1Z" fill-rule="evenodd"/></svg>',
'unselected': '<svg width="24" height="24"><path fill-rule="nonzero" d="M6 4h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2Zm0 1a1 1 0 0 0-1 1v12c0 .6.4 1 1 1h12c.6 0 1-.4 1-1V6c0-.6-.4-1-1-1H6Z"/></svg>',
'upload-from-device': '<svg width="24" height="25"><path d="M11 19a1 1 0 1 0 2 0v-3.2l1.5 1a1 1 0 1 0 1-1.7L12 12.8l-3.5 2.3a1 1 0 0 0 1 1.7l1.5-1V19Z"/><path d="M9.6 4c.3 0 .6.2.8.5l1.3 2h6.7c.7 0 1.4.2 1.8.7.5.5.8 1.2.8 1.9v8.3c0 .7-.3 1.3-.8 1.8a2.6 2.6 0 0 1-1.8.8H16v-2h2.4a.6.6 0 0 0 .4-.2.6.6 0 0 0 .2-.4V9a.6.6 0 0 0-.2-.5.6.6 0 0 0-.4-.1h-7.2a1 1 0 0 1-.8-.5L9 6H5.6a.6.6 0 0 0-.4.2.6.6 0 0 0-.2.4v10.8c0 .1 0 .3.2.4a.6.6 0 0 0 .4.2H8v2H5.6a2.6 2.6 0 0 1-1.8-.8 2.7 2.7 0 0 1-.8-1.8V6.6c0-.7.3-1.3.8-1.8A2.6 2.6 0 0 1 5.6 4h4Z"/></svg>',
'upload-from-link': '<svg height="25" width="24"><path d="M11.5 11.8a1 1 0 0 1 1.9-.5 5 5 0 0 1-1.3 4.8l-2.4 2.3A4 4 0 1 1 4 13L5 12a1 1 0 0 1 1.4 1.4l-.7.8A2 2 0 1 0 8.3 17l2.4-2.4a3 3 0 0 0 .8-2.8z"/><path d="M10.1 11.8a1 1 0 0 1-2 .5 5 5 0 0 1 1.4-4.8L12 5.1a4 4 0 0 1 5.5 5.6l-.7.8a1 1 0 0 1-1.5-1.4l.8-.8a2 2 0 1 0-2.7-2.7l-2.4 2.3a3 3 0 0 0-.8 3zm5.7 7.2a1 1 0 1 0 2 0v-3l1.4 1.1a1 1 0 0 0 1.2-1.5l-3.6-2.9-3.6 2.9a1 1 0 0 0 1.2 1.5l1.4-1z"/></svg>',
'upload': '<svg width="24" height="24"><path d="M18 19v-2a1 1 0 0 1 2 0v3c0 .6-.4 1-1 1H5a1 1 0 0 1-1-1v-3a1 1 0 0 1 2 0v2h12ZM11 6.4 8.7 8.7a1 1 0 0 1-1.4-1.4l4-4a1 1 0 0 1 1.4 0l4 4a1 1 0 1 1-1.4 1.4L13 6.4V16a1 1 0 0 1-2 0V6.4Z" fill-rule="nonzero"/></svg>',
'user': '<svg width="24" height="24"><path d="M12 24a12 12 0 1 1 0-24 12 12 0 0 1 0 24Zm-8.7-5.3a11 11 0 0 0 17.4 0C19.4 16.3 14.6 15 12 15c-2.6 0-7.4 1.3-8.7 3.7ZM12 13c2.2 0 4-2 4-4.5S14.2 4 12 4 8 6 8 8.5 9.8 13 12 13Z" fill-rule="nonzero"/></svg>',
'vertical-align': '<svg width="24" height="24"><g fill-rule="nonzero"><rect width="18" height="2" x="3" y="11" rx="1"/><path d="M12 2c.6 0 1 .4 1 1v4l2-1.3a1 1 0 0 1 1.2 1.5l-.1.1-4.1 3-4-3a1 1 0 0 1 1-1.7l2 1.5V3c0-.6.4-1 1-1zm0 11.8 4 2.9a1 1 0 0 1-1 1.7l-2-1.5V21c0 .5-.4 1-.9 1H12a1 1 0 0 1-1-1v-4l-2 1.3a1 1 0 0 1-1.2-.1l-.1-.1a1 1 0 0 1 .1-1.3l.1-.1 4.1-3z"/></g></svg>',
'vibrance': '<svg height="24" width="24"><path d="M12 20 22 4H2zm2.6-8 1.3-2H8l1.3 2h5.2zm-1.2 2h-2.8l1.4 2.2zm5-8L17 8H7L5.6 6h12.8z" fill-rule="evenodd"/></svg>',
'visualblocks': '<svg width="24" height="24"><path d="M9 19v2H7v-2h2Zm-4 0v2a2 2 0 0 1-2-2h2Zm8 0v2h-2v-2h2Zm8 0a2 2 0 0 1-2 2v-2h2Zm-4 0v2h-2v-2h2ZM15 7a1 1 0 0 1 0 2v7a1 1 0 0 1-2 0V9h-1v7a1 1 0 0 1-2 0v-4a2.5 2.5 0 0 1-.2-5H15ZM5 15v2H3v-2h2Zm16 0v2h-2v-2h2ZM5 11v2H3v-2h2Zm16 0v2h-2v-2h2ZM5 7v2H3V7h2Zm16 0v2h-2V7h2ZM5 3v2H3c0-1.1.9-2 2-2Zm8 0v2h-2V3h2Zm6 0a2 2 0 0 1 2 2h-2V3ZM9 3v2H7V3h2Zm8 0v2h-2V3h2Z" fill-rule="evenodd"/></svg>',
'visualchars': '<svg width="24" height="24"><path d="M10 5h7a1 1 0 0 1 0 2h-1v11a1 1 0 0 1-2 0V7h-2v11a1 1 0 0 1-2 0v-6c-.5 0-1 0-1.4-.3A3.4 3.4 0 0 1 6.8 10a3.3 3.3 0 0 1 0-2.8 3.4 3.4 0 0 1 1.8-1.8L10 5Z" fill-rule="evenodd"/></svg>',
'vk': '<svg width="24" height="24"><path fill-rule="evenodd" d="M14.8 17.4a2 2 0 0 1-1.3.7 8 8 0 0 1-7.7-3.6c-1.4-2-2.2-4.4-2.6-5.7L3 8.6A2 2 0 0 1 5 6h2.5c.4 0 .8.1 1.2.4A2 2 0 0 1 9.8 6h3.5a2 2 0 0 1 1.4.6 2 2 0 0 1 1.5-.6h2.4a2 2 0 0 1 2 2.5c-.5 1.5-1.2 2.6-1.8 3.6a12.5 12.5 0 0 1 2 3.2A2 2 0 0 1 19 18h-2.6a2 2 0 0 1-1.3-.5 6.9 6.9 0 0 1-.3-.2Zm.5-2.5-1.2-1a3 3 0 0 0-.8-.2v2.4h-1.7a5.6 5.6 0 0 1-.3 0c-3-.7-4.7-3.7-5.6-6.1A38.1 38.1 0 0 1 5 8.1V8h2.5a80.5 80.5 0 0 1 1.2 2.5c.6 1.2 1.2 2 2 2.1V9l-.9-1h3.5v4.1a5 5 0 0 0 .4-.3c.7-.7 1.2-1.4 1.6-2.2l.2-.3.7-1.3h2.4a8.5 8.5 0 0 1-.8 2l-1.3 2-.3.3a10.5 10.5 0 0 1 2.8 3.8h-2.6l-.8-.9a20.6 20.6 0 0 0-.3-.3Z" clip-rule="evenodd"/></svg>',
'warmth': '<svg height="24" width="24"><path d="M12 21.1c-1.4 0-2.6-.5-3.6-1.5s-1.5-2.1-1.5-3.5c0-.8.2-1.6.6-2.2A5 5 0 0 1 8.9 12v-6c0-.8.3-1.5 1-2.1a2.9 2.9 0 0 1 2-.9c.9 0 1.6.3 2.2.9.5.6.8 1.3.8 2.1v6a5 5 0 0 1 1.5 1.8A4.9 4.9 0 0 1 17 16c0 1.4-.5 2.6-1.4 3.5s-2.2 1.5-3.6 1.5zm-3-5h6c0-.5-.2-1-.4-1.4a3 3 0 0 0-.9-1l-.8-.6v-7a1 1 0 0 0-.3-.7A1 1 0 0 0 12 5a1 1 0 0 0-.7.3 1 1 0 0 0-.3.7v7l-.8.6a2.9 2.9 0 0 0-.9 1 3 3 0 0 0-.3 1.4z"/></svg>',
'warning': '<svg width="24" height="24"><path d="M19.8 18.3c.2.5.3.9 0 1.2-.1.3-.5.5-1 .5H5.2c-.5 0-.9-.2-1-.5-.3-.3-.2-.7 0-1.2L11 4.7l.5-.5.5-.2c.2 0 .3 0 .5.2.2 0 .3.3.5.5l6.8 13.6ZM12 18c.3 0 .5-.1.7-.3.2-.2.3-.4.3-.7a1 1 0 0 0-.3-.7 1 1 0 0 0-.7-.3 1 1 0 0 0-.7.3 1 1 0 0 0-.3.7c0 .3.1.5.3.7.2.2.4.3.7.3Zm.7-3 .3-4a1 1 0 0 0-.3-.7 1 1 0 0 0-.7-.3 1 1 0 0 0-.7.3 1 1 0 0 0-.3.7l.3 4h1.4Z" fill-rule="evenodd"/></svg>',
'zoom-in': '<svg width="24" height="24"><path d="M16 17.3a8 8 0 1 1 1.4-1.4l4.3 4.4a1 1 0 0 1-1.4 1.4l-4.4-4.3Zm-5-.3a6 6 0 1 0 0-12 6 6 0 0 0 0 12Zm-1-9a1 1 0 0 1 2 0v6a1 1 0 0 1-2 0V8Zm-2 4a1 1 0 0 1 0-2h6a1 1 0 0 1 0 2H8Z" fill-rule="nonzero"/></svg>',
'zoom-out': '<svg width="24" height="24"><path d="M16 17.3a8 8 0 1 1 1.4-1.4l4.3 4.4a1 1 0 0 1-1.4 1.4l-4.4-4.3Zm-5-.3a6 6 0 1 0 0-12 6 6 0 0 0 0 12Zm-3-5a1 1 0 0 1 0-2h6a1 1 0 0 1 0 2H8Z" fill-rule="nonzero"/></svg>',
}
});

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
// Exports the "default" icons for usage with module loaders
// Usage:
// CommonJS:
// require('tinymce/icons/default')
// ES2015:
// import 'tinymce/icons/default'
require('./icons.js');

View File

@@ -0,0 +1,9 @@
Copyright (c) 2025 Ephox Corporation DBA Tiny Technologies, Inc.
SOFTWARE TERMS & CONDITIONS OF USE
Licensed under, and subject to the restrictions of:
1. The terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html); or
2. The Tiny Technologies, Inc Software Terms & Conditions of Use presented at <https://about.tiny.cloud/legal/> and specifically the Tiny Self-Hosted License Agreement, unless you have signed a negotiated commercial license agreement with us in which case your use is governed by those terms. By use of this Software you have agreed to these Tiny Technologies, Inc Software Terms & Conditions of Use.
If you are uncertain about your licensing requirements, please contact <sales@tiny.cloud> for further clarification.

View File

@@ -0,0 +1,7 @@
// Exports the "dom" model for usage with module loaders
// Usage:
// CommonJS:
// require('tinymce/models/dom')
// ES2015:
// import 'tinymce/models/dom'
require('./model.js');

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
// Exports the "dom" model for usage with module loaders
// Usage:
// CommonJS:
// require('tinymce/models/dom')
// ES2015:
// import 'tinymce/models/dom'
require('./model.js');

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,21 @@
Below is a list of third party libraries that this software uses:
----------------------------------------------------------------
dompurify
owner: Mario Heiderich
repo: https://github.com/cure53/DOMPurify
version: 3.2.6
license: MPL-2.0 OR Apache-2.0
prismjs
owner: Lea Verou
repo: https://github.com/PrismJS/prism
version: 1.25.0
license: MIT
prism-themes
owner: Lea Verou
repo: https://github.com/PrismJS/prism-themes
version: 1.9.0
license: MIT

View File

@@ -0,0 +1,32 @@
{
"name": "tinymce",
"version": "8.3.2",
"repository": {
"type": "git",
"url": "https://github.com/tinymce/tinymce.git",
"directory": "modules/tinymce"
},
"description": "Web based JavaScript HTML WYSIWYG editor control.",
"author": "Ephox Corporation DBA Tiny Technologies, Inc",
"main": "tinymce.js",
"types": "tinymce.d.ts",
"license": "SEE LICENSE IN license.md",
"keywords": [
"wysiwyg",
"tinymce",
"richtext",
"javascript",
"html",
"text",
"rich editor",
"rich text editor",
"rte",
"rich text",
"contenteditable",
"editing"
],
"homepage": "https://www.tiny.cloud/",
"bugs": {
"url": "https://github.com/tinymce/tinymce/issues"
}
}

View File

@@ -0,0 +1,7 @@
// Exports the "accordion" plugin for usage with module loaders
// Usage:
// CommonJS:
// require('tinymce/plugins/accordion')
// ES2015:
// import 'tinymce/plugins/accordion'
require('./plugin.js');

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
// Exports the "advlist" plugin for usage with module loaders
// Usage:
// CommonJS:
// require('tinymce/plugins/advlist')
// ES2015:
// import 'tinymce/plugins/advlist'
require('./plugin.js');

View File

@@ -0,0 +1,473 @@
/**
* TinyMCE version 8.3.2 (2026-01-14)
*/
(function () {
'use strict';
var global$1 = tinymce.util.Tools.resolve('tinymce.PluginManager');
const applyListFormat = (editor, listName, styleValue) => {
const cmd = listName === 'UL' ? 'InsertUnorderedList' : 'InsertOrderedList';
editor.execCommand(cmd, false, styleValue === false ? null : { 'list-style-type': styleValue });
};
const register$2 = (editor) => {
editor.addCommand('ApplyUnorderedListStyle', (ui, value) => {
applyListFormat(editor, 'UL', value['list-style-type']);
});
editor.addCommand('ApplyOrderedListStyle', (ui, value) => {
applyListFormat(editor, 'OL', value['list-style-type']);
});
};
const option = (name) => (editor) => editor.options.get(name);
const register$1 = (editor) => {
const registerOption = editor.options.register;
registerOption('advlist_number_styles', {
processor: 'string[]',
default: 'default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman'.split(',')
});
registerOption('advlist_bullet_styles', {
processor: 'string[]',
default: 'default,disc,circle,square'.split(',')
});
};
const getNumberStyles = option('advlist_number_styles');
const getBulletStyles = option('advlist_bullet_styles');
/* eslint-disable @typescript-eslint/no-wrapper-object-types */
const isNullable = (a) => a === null || a === undefined;
const isNonNullable = (a) => !isNullable(a);
/**
* The `Optional` type represents a value (of any type) that potentially does
* not exist. Any `Optional<T>` can either be a `Some<T>` (in which case the
* value does exist) or a `None` (in which case the value does not exist). This
* module defines a whole lot of FP-inspired utility functions for dealing with
* `Optional` objects.
*
* Comparison with null or undefined:
* - We don't get fancy null coalescing operators with `Optional`
* - We do get fancy helper functions with `Optional`
* - `Optional` support nesting, and allow for the type to still be nullable (or
* another `Optional`)
* - There is no option to turn off strict-optional-checks like there is for
* strict-null-checks
*/
class Optional {
tag;
value;
// Sneaky optimisation: every instance of Optional.none is identical, so just
// reuse the same object
static singletonNone = new Optional(false);
// The internal representation has a `tag` and a `value`, but both are
// private: able to be console.logged, but not able to be accessed by code
constructor(tag, value) {
this.tag = tag;
this.value = value;
}
// --- Identities ---
/**
* Creates a new `Optional<T>` that **does** contain a value.
*/
static some(value) {
return new Optional(true, value);
}
/**
* Create a new `Optional<T>` that **does not** contain a value. `T` can be
* any type because we don't actually have a `T`.
*/
static none() {
return Optional.singletonNone;
}
/**
* Perform a transform on an `Optional` type. Regardless of whether this
* `Optional` contains a value or not, `fold` will return a value of type `U`.
* If this `Optional` does not contain a value, the `U` will be created by
* calling `onNone`. If this `Optional` does contain a value, the `U` will be
* created by calling `onSome`.
*
* For the FP enthusiasts in the room, this function:
* 1. Could be used to implement all of the functions below
* 2. Forms a catamorphism
*/
fold(onNone, onSome) {
if (this.tag) {
return onSome(this.value);
}
else {
return onNone();
}
}
/**
* Determine if this `Optional` object contains a value.
*/
isSome() {
return this.tag;
}
/**
* Determine if this `Optional` object **does not** contain a value.
*/
isNone() {
return !this.tag;
}
// --- Functor (name stolen from Haskell / maths) ---
/**
* Perform a transform on an `Optional` object, **if** there is a value. If
* you provide a function to turn a T into a U, this is the function you use
* to turn an `Optional<T>` into an `Optional<U>`. If this **does** contain
* a value then the output will also contain a value (that value being the
* output of `mapper(this.value)`), and if this **does not** contain a value
* then neither will the output.
*/
map(mapper) {
if (this.tag) {
return Optional.some(mapper(this.value));
}
else {
return Optional.none();
}
}
// --- Monad (name stolen from Haskell / maths) ---
/**
* Perform a transform on an `Optional` object, **if** there is a value.
* Unlike `map`, here the transform itself also returns an `Optional`.
*/
bind(binder) {
if (this.tag) {
return binder(this.value);
}
else {
return Optional.none();
}
}
// --- Traversable (name stolen from Haskell / maths) ---
/**
* For a given predicate, this function finds out if there **exists** a value
* inside this `Optional` object that meets the predicate. In practice, this
* means that for `Optional`s that do not contain a value it returns false (as
* no predicate-meeting value exists).
*/
exists(predicate) {
return this.tag && predicate(this.value);
}
/**
* For a given predicate, this function finds out if **all** the values inside
* this `Optional` object meet the predicate. In practice, this means that
* for `Optional`s that do not contain a value it returns true (as all 0
* objects do meet the predicate).
*/
forall(predicate) {
return !this.tag || predicate(this.value);
}
filter(predicate) {
if (!this.tag || predicate(this.value)) {
return this;
}
else {
return Optional.none();
}
}
// --- Getters ---
/**
* Get the value out of the inside of the `Optional` object, using a default
* `replacement` value if the provided `Optional` object does not contain a
* value.
*/
getOr(replacement) {
return this.tag ? this.value : replacement;
}
/**
* Get the value out of the inside of the `Optional` object, using a default
* `replacement` value if the provided `Optional` object does not contain a
* value. Unlike `getOr`, in this method the `replacement` object is also
* `Optional` - meaning that this method will always return an `Optional`.
*/
or(replacement) {
return this.tag ? this : replacement;
}
/**
* Get the value out of the inside of the `Optional` object, using a default
* `replacement` value if the provided `Optional` object does not contain a
* value. Unlike `getOr`, in this method the `replacement` value is
* "thunked" - that is to say that you don't pass a value to `getOrThunk`, you
* pass a function which (if called) will **return** the `value` you want to
* use.
*/
getOrThunk(thunk) {
return this.tag ? this.value : thunk();
}
/**
* Get the value out of the inside of the `Optional` object, using a default
* `replacement` value if the provided Optional object does not contain a
* value.
*
* Unlike `or`, in this method the `replacement` value is "thunked" - that is
* to say that you don't pass a value to `orThunk`, you pass a function which
* (if called) will **return** the `value` you want to use.
*
* Unlike `getOrThunk`, in this method the `replacement` value is also
* `Optional`, meaning that this method will always return an `Optional`.
*/
orThunk(thunk) {
return this.tag ? this : thunk();
}
/**
* Get the value out of the inside of the `Optional` object, throwing an
* exception if the provided `Optional` object does not contain a value.
*
* WARNING:
* You should only be using this function if you know that the `Optional`
* object **is not** empty (otherwise you're throwing exceptions in production
* code, which is bad).
*
* In tests this is more acceptable.
*
* Prefer other methods to this, such as `.each`.
*/
getOrDie(message) {
if (!this.tag) {
throw new Error(message ?? 'Called getOrDie on None');
}
else {
return this.value;
}
}
// --- Interop with null and undefined ---
/**
* Creates an `Optional` value from a nullable (or undefined-able) input.
* Null, or undefined, is converted to `None`, and anything else is converted
* to `Some`.
*/
static from(value) {
return isNonNullable(value) ? Optional.some(value) : Optional.none();
}
/**
* Converts an `Optional` to a nullable type, by getting the value if it
* exists, or returning `null` if it does not.
*/
getOrNull() {
return this.tag ? this.value : null;
}
/**
* Converts an `Optional` to an undefined-able type, by getting the value if
* it exists, or returning `undefined` if it does not.
*/
getOrUndefined() {
return this.value;
}
// --- Utilities ---
/**
* If the `Optional` contains a value, perform an action on that value.
* Unlike the rest of the methods on this type, `.each` has side-effects. If
* you want to transform an `Optional<T>` **into** something, then this is not
* the method for you. If you want to use an `Optional<T>` to **do**
* something, then this is the method for you - provided you're okay with not
* doing anything in the case where the `Optional` doesn't have a value inside
* it. If you're not sure whether your use-case fits into transforming
* **into** something or **doing** something, check whether it has a return
* value. If it does, you should be performing a transform.
*/
each(worker) {
if (this.tag) {
worker(this.value);
}
}
/**
* Turn the `Optional` object into an array that contains all of the values
* stored inside the `Optional`. In practice, this means the output will have
* either 0 or 1 elements.
*/
toArray() {
return this.tag ? [this.value] : [];
}
/**
* Turn the `Optional` object into a string for debugging or printing. Not
* recommended for production code, but good for debugging. Also note that
* these days an `Optional` object can be logged to the console directly, and
* its inner value (if it exists) will be visible.
*/
toString() {
return this.tag ? `some(${this.value})` : 'none()';
}
}
const nativeIndexOf = Array.prototype.indexOf;
const rawIndexOf = (ts, t) => nativeIndexOf.call(ts, t);
const contains = (xs, x) => rawIndexOf(xs, x) > -1;
const findUntil = (xs, pred, until) => {
for (let i = 0, len = xs.length; i < len; i++) {
const x = xs[i];
if (pred(x, i)) {
return Optional.some(x);
}
else if (until(x, i)) {
break;
}
}
return Optional.none();
};
// There are many variations of Object iteration that are faster than the 'for-in' style:
// http://jsperf.com/object-keys-iteration/107
//
// Use the native keys if it is available (IE9+), otherwise fall back to manually filtering
const keys = Object.keys;
const each = (obj, f) => {
const props = keys(obj);
for (let k = 0, len = props.length; k < len; k++) {
const i = props[k];
const x = obj[i];
f(x, i);
}
};
const map = (obj, f) => {
return tupleMap(obj, (x, i) => ({
k: i,
v: f(x, i)
}));
};
const tupleMap = (obj, f) => {
const r = {};
each(obj, (x, i) => {
const tuple = f(x, i);
r[tuple.k] = tuple.v;
});
return r;
};
var global = tinymce.util.Tools.resolve('tinymce.util.Tools');
const isCustomList = (list) => /\btox\-/.test(list.className);
const isChildOfBody = (editor, elm) => {
return editor.dom.isChildOf(elm, editor.getBody());
};
const matchNodeNames = (regex) => (node) => isNonNullable(node) && regex.test(node.nodeName);
const isListNode = matchNodeNames(/^(OL|UL|DL)$/);
const isTableCellNode = matchNodeNames(/^(TH|TD)$/);
const inList = (editor, parents, nodeName) => findUntil(parents, (parent) => isListNode(parent) && !isCustomList(parent), isTableCellNode)
.exists((list) => list.nodeName === nodeName && isChildOfBody(editor, list));
const getSelectedStyleType = (editor) => {
const listElm = editor.dom.getParent(editor.selection.getNode(), 'ol,ul');
const style = editor.dom.getStyle(listElm, 'listStyleType');
return Optional.from(style);
};
// Lists/core/Util.ts - Duplicated in Lists plugin
const isWithinNonEditable = (editor, element) => element !== null && !editor.dom.isEditable(element);
const isWithinNonEditableList = (editor, element) => {
const parentList = editor.dom.getParent(element, 'ol,ul,dl');
return isWithinNonEditable(editor, parentList) || !editor.selection.isEditable();
};
const setNodeChangeHandler = (editor, nodeChangeHandler) => {
const initialNode = editor.selection.getNode();
// Set the initial state
nodeChangeHandler({
parents: editor.dom.getParents(initialNode),
element: initialNode
});
editor.on('NodeChange', nodeChangeHandler);
return () => editor.off('NodeChange', nodeChangeHandler);
};
// <ListStyles>
const styleValueToText = (styleValue) => {
return styleValue.replace(/\-/g, ' ').replace(/\b\w/g, (chr) => {
return chr.toUpperCase();
});
};
const normalizeStyleValue = (styleValue) => isNullable(styleValue) || styleValue === 'default' ? '' : styleValue;
const makeSetupHandler = (editor, nodeName) => (api) => {
const updateButtonState = (editor, parents) => {
const element = editor.selection.getStart(true);
api.setActive(inList(editor, parents, nodeName));
api.setEnabled(!isWithinNonEditableList(editor, element));
};
const nodeChangeHandler = (e) => updateButtonState(editor, e.parents);
return setNodeChangeHandler(editor, nodeChangeHandler);
};
const addSplitButton = (editor, id, tooltip, cmd, nodeName, styles) => {
const listStyleTypeAliases = {
'lower-latin': 'lower-alpha',
'upper-latin': 'upper-alpha',
'lower-alpha': 'lower-latin',
'upper-alpha': 'upper-latin'
};
const stylesContainsAliasMap = map(listStyleTypeAliases, (alias) => contains(styles, alias));
editor.ui.registry.addSplitButton(id, {
tooltip,
chevronTooltip: tooltip,
icon: nodeName === "OL" /* ListType.OrderedList */ ? 'ordered-list' : 'unordered-list',
presets: 'listpreview',
columns: nodeName === "OL" /* ListType.OrderedList */ ? 3 : 4,
fetch: (callback) => {
const items = global.map(styles, (styleValue) => {
const iconStyle = nodeName === "OL" /* ListType.OrderedList */ ? 'num' : 'bull';
const iconName = styleValue === 'decimal' ? 'default' : styleValue;
const itemValue = normalizeStyleValue(styleValue);
const displayText = styleValueToText(styleValue);
return {
type: 'choiceitem',
value: itemValue,
icon: 'list-' + iconStyle + '-' + iconName,
text: displayText
};
});
callback(items);
},
onAction: () => editor.execCommand(cmd),
onItemAction: (_splitButtonApi, value) => {
applyListFormat(editor, nodeName, value);
},
select: (value) => {
const listStyleType = getSelectedStyleType(editor);
return listStyleType.exists((listStyle) => value === listStyle || (listStyleTypeAliases[listStyle] === value && !stylesContainsAliasMap[value]));
},
onSetup: makeSetupHandler(editor, nodeName)
});
};
const addButton = (editor, id, tooltip, cmd, nodeName, styleValue) => {
editor.ui.registry.addToggleButton(id, {
active: false,
tooltip,
icon: nodeName === "OL" /* ListType.OrderedList */ ? 'ordered-list' : 'unordered-list',
onSetup: makeSetupHandler(editor, nodeName),
// Need to make sure the button removes rather than applies if a list of the same type is selected
onAction: () => editor.queryCommandState(cmd) || styleValue === '' ? editor.execCommand(cmd) : applyListFormat(editor, nodeName, styleValue)
});
};
const addControl = (editor, id, tooltip, cmd, nodeName, styles) => {
if (styles.length > 1) {
addSplitButton(editor, id, tooltip, cmd, nodeName, styles);
}
else {
addButton(editor, id, tooltip, cmd, nodeName, normalizeStyleValue(styles[0]));
}
};
const register = (editor) => {
addControl(editor, 'numlist', 'Numbered list', 'InsertOrderedList', "OL" /* ListType.OrderedList */, getNumberStyles(editor));
addControl(editor, 'bullist', 'Bullet list', 'InsertUnorderedList', "UL" /* ListType.UnorderedList */, getBulletStyles(editor));
};
var Plugin = () => {
global$1.add('advlist', (editor) => {
if (editor.hasPlugin('lists')) {
register$1(editor);
register(editor);
register$2(editor);
}
else {
// eslint-disable-next-line no-console
console.error('Please use the Lists plugin together with the List Styles plugin.');
}
});
};
Plugin();
/** *****
* DO NOT EXPORT ANYTHING
*
* IF YOU DO ROLLUP WILL LEAVE A GLOBAL ON THE PAGE
*******/
})();

View File

@@ -0,0 +1 @@
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=(t,e,s)=>{const r="UL"===e?"InsertUnorderedList":"InsertOrderedList";t.execCommand(r,!1,!1===s?null:{"list-style-type":s})},s=t=>e=>e.options.get(t),r=s("advlist_number_styles"),n=s("advlist_bullet_styles"),l=t=>null==t,i=t=>!l(t);class o{tag;value;static singletonNone=new o(!1);constructor(t,e){this.tag=t,this.value=e}static some(t){return new o(!0,t)}static none(){return o.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?o.some(t(this.value)):o.none()}bind(t){return this.tag?t(this.value):o.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:o.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(t??"Called getOrDie on None")}static from(t){return i(t)?o.some(t):o.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}const a=Array.prototype.indexOf,u=Object.keys;var d=tinymce.util.Tools.resolve("tinymce.util.Tools");const c=t=>e=>i(e)&&t.test(e.nodeName),h=c(/^(OL|UL|DL)$/),g=c(/^(TH|TD)$/),p=t=>l(t)||"default"===t?"":t,m=(t,e)=>s=>((t,e)=>{const s=t.selection.getNode();return e({parents:t.dom.getParents(s),element:s}),t.on("NodeChange",e),()=>t.off("NodeChange",e)})(t,(r=>((t,r)=>{const n=t.selection.getStart(!0);s.setActive(((t,e,s)=>((t,e,s)=>{for(let e=0,n=t.length;e<n;e++){const n=t[e];if(h(r=n)&&!/\btox\-/.test(r.className))return o.some(n);if(s(n,e))break}var r;return o.none()})(e,0,g).exists((e=>e.nodeName===s&&((t,e)=>t.dom.isChildOf(e,t.getBody()))(t,e))))(t,r,e)),s.setEnabled(!((t,e)=>{const s=t.dom.getParent(e,"ol,ul,dl");return((t,e)=>null!==e&&!t.dom.isEditable(e))(t,s)||!t.selection.isEditable()})(t,n))})(t,r.parents))),v=(t,s,r,n,l,i)=>{const c={"lower-latin":"lower-alpha","upper-latin":"upper-alpha","lower-alpha":"lower-latin","upper-alpha":"upper-latin"},h=(g=t=>{return e=i,s=t,a.call(e,s)>-1;var e,s},((t,e)=>{const s={};return((t,e)=>{const s=u(t);for(let r=0,n=s.length;r<n;r++){const n=s[r];e(t[n],n)}})(t,((t,r)=>{const n=e(t,r);s[n.k]=n.v})),s})(c,((t,e)=>({k:e,v:g(t)}))));var g;t.ui.registry.addSplitButton(s,{tooltip:r,chevronTooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",presets:"listpreview",columns:"OL"===l?3:4,fetch:t=>{t(d.map(i,(t=>{const e="OL"===l?"num":"bull",s="decimal"===t?"default":t,r=p(t),n=(t=>t.replace(/\-/g," ").replace(/\b\w/g,(t=>t.toUpperCase())))(t);return{type:"choiceitem",value:r,icon:"list-"+e+"-"+s,text:n}})))},onAction:()=>t.execCommand(n),onItemAction:(s,r)=>{e(t,l,r)},select:e=>{const s=(t=>{const e=t.dom.getParent(t.selection.getNode(),"ol,ul"),s=t.dom.getStyle(e,"listStyleType");return o.from(s)})(t);return s.exists((t=>e===t||c[t]===e&&!h[e]))},onSetup:m(t,l)})},y=(t,s,r,n,l,i)=>{i.length>1?v(t,s,r,n,l,i):((t,s,r,n,l,i)=>{t.ui.registry.addToggleButton(s,{active:!1,tooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",onSetup:m(t,l),onAction:()=>t.queryCommandState(n)||""===i?t.execCommand(n):e(t,l,i)})})(t,s,r,n,l,p(i[0]))};t.add("advlist",(t=>{t.hasPlugin("lists")?((t=>{const e=t.options.register;e("advlist_number_styles",{processor:"string[]",default:"default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman".split(",")}),e("advlist_bullet_styles",{processor:"string[]",default:"default,disc,circle,square".split(",")})})(t),(t=>{y(t,"numlist","Numbered list","InsertOrderedList","OL",r(t)),y(t,"bullist","Bullet list","InsertUnorderedList","UL",n(t))})(t),(t=>{t.addCommand("ApplyUnorderedListStyle",((s,r)=>{e(t,"UL",r["list-style-type"])})),t.addCommand("ApplyOrderedListStyle",((s,r)=>{e(t,"OL",r["list-style-type"])}))})(t)):console.error("Please use the Lists plugin together with the List Styles plugin.")}))}();

View File

@@ -0,0 +1,7 @@
// Exports the "anchor" plugin for usage with module loaders
// Usage:
// CommonJS:
// require('tinymce/plugins/anchor')
// ES2015:
// import 'tinymce/plugins/anchor'
require('./plugin.js');

View File

@@ -0,0 +1,237 @@
/**
* TinyMCE version 8.3.2 (2026-01-14)
*/
(function () {
'use strict';
var global$2 = tinymce.util.Tools.resolve('tinymce.PluginManager');
var global$1 = tinymce.util.Tools.resolve('tinymce.dom.RangeUtils');
var global = tinymce.util.Tools.resolve('tinymce.util.Tools');
const option = (name) => (editor) => editor.options.get(name);
const register$2 = (editor) => {
const registerOption = editor.options.register;
registerOption('allow_html_in_named_anchor', {
processor: 'boolean',
default: false
});
};
const allowHtmlInNamedAnchor = option('allow_html_in_named_anchor');
const namedAnchorSelector = 'a:not([href])';
const isEmptyString = (str) => !str;
const getIdFromAnchor = (elm) => {
const id = elm.getAttribute('id') || elm.getAttribute('name');
return id || '';
};
const isAnchor = (elm) => elm.nodeName.toLowerCase() === 'a';
const isNamedAnchor = (elm) => isAnchor(elm) && !elm.getAttribute('href') && getIdFromAnchor(elm) !== '';
const isEmptyNamedAnchor = (elm) => isNamedAnchor(elm) && !elm.firstChild;
const removeEmptyNamedAnchorsInSelection = (editor) => {
const dom = editor.dom;
global$1(dom).walk(editor.selection.getRng(), (nodes) => {
global.each(nodes, (node) => {
if (isEmptyNamedAnchor(node)) {
dom.remove(node, false);
}
});
});
};
const isValidId = (id) =>
// Follows HTML4 rules: https://www.w3.org/TR/html401/types.html#type-id
/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(id);
const getNamedAnchor = (editor) => editor.dom.getParent(editor.selection.getStart(), namedAnchorSelector);
const getId = (editor) => {
const anchor = getNamedAnchor(editor);
if (anchor) {
return getIdFromAnchor(anchor);
}
else {
return '';
}
};
const createAnchor = (editor, id) => {
editor.undoManager.transact(() => {
if (!allowHtmlInNamedAnchor(editor)) {
editor.selection.collapse(true);
}
if (editor.selection.isCollapsed()) {
editor.insertContent(editor.dom.createHTML('a', { id }));
}
else {
// Remove any empty named anchors in the selection as they cannot be removed by the formatter since they are cef
removeEmptyNamedAnchorsInSelection(editor);
// Format is set up to truncate any partially selected named anchors so that they are not completely removed
editor.formatter.remove('namedAnchor', undefined, undefined, true);
// Insert new anchor using the formatter - will wrap selected content in anchor
editor.formatter.apply('namedAnchor', { value: id });
// Need to add visual classes to anchors if required
editor.addVisual();
}
});
};
const updateAnchor = (editor, id, anchorElement) => {
anchorElement.removeAttribute('name');
anchorElement.id = id;
editor.addVisual(); // Need to add visual classes to anchors if required
editor.undoManager.add();
};
const insert = (editor, id) => {
const anchor = getNamedAnchor(editor);
if (anchor) {
updateAnchor(editor, id, anchor);
}
else {
createAnchor(editor, id);
}
editor.focus();
};
const insertAnchor = (editor, newId) => {
if (!isValidId(newId)) {
editor.windowManager.alert('ID should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.');
return false;
}
else {
insert(editor, newId);
return true;
}
};
const open = (editor) => {
const currentId = getId(editor);
editor.windowManager.open({
title: 'Anchor',
size: 'normal',
body: {
type: 'panel',
items: [
{
name: 'id',
type: 'input',
label: 'ID',
placeholder: 'example'
}
]
},
buttons: [
{
type: 'cancel',
name: 'cancel',
text: 'Cancel'
},
{
type: 'submit',
name: 'save',
text: 'Save',
primary: true
}
],
initialData: {
id: currentId
},
onSubmit: (api) => {
if (insertAnchor(editor, api.getData().id)) { // TODO we need a better way to do validation
api.close();
}
}
});
};
const register$1 = (editor) => {
editor.addCommand('mceAnchor', () => {
open(editor);
});
};
// Note: node.firstChild check is for the 'allow_html_in_named_anchor' setting
// Only want to add contenteditable attributes if there is no text within the anchor
const isNamedAnchorNode = (node) => isEmptyString(node.attr('href')) && !isEmptyString(node.attr('id') || node.attr('name'));
const isEmptyNamedAnchorNode = (node) => isNamedAnchorNode(node) && !node.firstChild;
const setContentEditable = (state) => (nodes) => {
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i];
if (isEmptyNamedAnchorNode(node)) {
node.attr('contenteditable', state);
}
}
};
const setup = (editor) => {
editor.on('PreInit', () => {
editor.parser.addNodeFilter('a', setContentEditable('false'));
editor.serializer.addNodeFilter('a', setContentEditable(null));
});
};
const registerFormats = (editor) => {
editor.formatter.register('namedAnchor', {
inline: 'a',
selector: namedAnchorSelector,
remove: 'all',
split: true,
deep: true,
attributes: {
id: '%value'
},
onmatch: (node, _fmt, _itemName) => {
return isNamedAnchor(node);
}
});
};
const onSetupEditable = (editor) => (api) => {
const nodeChanged = () => {
api.setEnabled(editor.selection.isEditable());
};
editor.on('NodeChange', nodeChanged);
nodeChanged();
return () => {
editor.off('NodeChange', nodeChanged);
};
};
const register = (editor) => {
const onAction = () => editor.execCommand('mceAnchor');
editor.ui.registry.addToggleButton('anchor', {
icon: 'bookmark',
tooltip: 'Anchor',
onAction,
onSetup: (buttonApi) => {
const unbindSelectorChanged = editor.selection.selectorChangedWithUnbind('a:not([href])', buttonApi.setActive).unbind;
const unbindEditableChanged = onSetupEditable(editor)(buttonApi);
return () => {
unbindSelectorChanged();
unbindEditableChanged();
};
}
});
editor.ui.registry.addMenuItem('anchor', {
icon: 'bookmark',
text: 'Anchor...',
onAction,
onSetup: onSetupEditable(editor)
});
};
var Plugin = () => {
global$2.add('anchor', (editor) => {
register$2(editor);
setup(editor);
register$1(editor);
register(editor);
editor.on('PreInit', () => {
registerFormats(editor);
});
});
};
Plugin();
/** *****
* DO NOT EXPORT ANYTHING
*
* IF YOU DO ROLLUP WILL LEAVE A GLOBAL ON THE PAGE
*******/
})();

View File

@@ -0,0 +1 @@
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.dom.RangeUtils"),o=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=e=>e.options.get("allow_html_in_named_anchor");const a="a:not([href])",r=e=>!e,i=e=>e.getAttribute("id")||e.getAttribute("name")||"",l=e=>(e=>"a"===e.nodeName.toLowerCase())(e)&&!e.getAttribute("href")&&""!==i(e),s=e=>e.dom.getParent(e.selection.getStart(),a),d=(e,a)=>{const r=s(e);r?((e,t,o)=>{o.removeAttribute("name"),o.id=t,e.addVisual(),e.undoManager.add()})(e,a,r):((e,a)=>{e.undoManager.transact((()=>{n(e)||e.selection.collapse(!0),e.selection.isCollapsed()?e.insertContent(e.dom.createHTML("a",{id:a})):((e=>{const n=e.dom;t(n).walk(e.selection.getRng(),(e=>{o.each(e,(e=>{var t;l(t=e)&&!t.firstChild&&n.remove(e,!1)}))}))})(e),e.formatter.remove("namedAnchor",void 0,void 0,!0),e.formatter.apply("namedAnchor",{value:a}),e.addVisual())}))})(e,a),e.focus()},c=e=>(e=>r(e.attr("href"))&&!r(e.attr("id")||e.attr("name")))(e)&&!e.firstChild,m=e=>t=>{for(let o=0;o<t.length;o++){const n=t[o];c(n)&&n.attr("contenteditable",e)}},u=e=>t=>{const o=()=>{t.setEnabled(e.selection.isEditable())};return e.on("NodeChange",o),o(),()=>{e.off("NodeChange",o)}};e.add("anchor",(e=>{(e=>{(0,e.options.register)("allow_html_in_named_anchor",{processor:"boolean",default:!1})})(e),(e=>{e.on("PreInit",(()=>{e.parser.addNodeFilter("a",m("false")),e.serializer.addNodeFilter("a",m(null))}))})(e),(e=>{e.addCommand("mceAnchor",(()=>{(e=>{const t=(e=>{const t=s(e);return t?i(t):""})(e);e.windowManager.open({title:"Anchor",size:"normal",body:{type:"panel",items:[{name:"id",type:"input",label:"ID",placeholder:"example"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{id:t},onSubmit:t=>{((e,t)=>/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(t)?(d(e,t),!0):(e.windowManager.alert("ID should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores."),!1))(e,t.getData().id)&&t.close()}})})(e)}))})(e),(e=>{const t=()=>e.execCommand("mceAnchor");e.ui.registry.addToggleButton("anchor",{icon:"bookmark",tooltip:"Anchor",onAction:t,onSetup:t=>{const o=e.selection.selectorChangedWithUnbind("a:not([href])",t.setActive).unbind,n=u(e)(t);return()=>{o(),n()}}}),e.ui.registry.addMenuItem("anchor",{icon:"bookmark",text:"Anchor...",onAction:t,onSetup:u(e)})})(e),e.on("PreInit",(()=>{(e=>{e.formatter.register("namedAnchor",{inline:"a",selector:a,remove:"all",split:!0,deep:!0,attributes:{id:"%value"},onmatch:(e,t,o)=>l(e)})})(e)}))}))}();

View File

@@ -0,0 +1,7 @@
// Exports the "autolink" plugin for usage with module loaders
// Usage:
// CommonJS:
// require('tinymce/plugins/autolink')
// ES2015:
// import 'tinymce/plugins/autolink'
require('./plugin.js');

View File

@@ -0,0 +1,315 @@
/**
* TinyMCE version 8.3.2 (2026-01-14)
*/
(function () {
'use strict';
var global$1 = tinymce.util.Tools.resolve('tinymce.PluginManager');
/* eslint-disable @typescript-eslint/no-wrapper-object-types */
const hasProto = (v, constructor, predicate) => {
if (predicate(v, constructor.prototype)) {
return true;
}
else {
// String-based fallback time
return v.constructor?.name === constructor.name;
}
};
const typeOf = (x) => {
const t = typeof x;
if (x === null) {
return 'null';
}
else if (t === 'object' && Array.isArray(x)) {
return 'array';
}
else if (t === 'object' && hasProto(x, String, (o, proto) => proto.isPrototypeOf(o))) {
return 'string';
}
else {
return t;
}
};
const isType = (type) => (value) => typeOf(value) === type;
const eq = (t) => (a) => t === a;
const isString = isType('string');
const isUndefined = eq(undefined);
const isNullable = (a) => a === null || a === undefined;
const isNonNullable = (a) => !isNullable(a);
const not = (f) => (t) => !f(t);
const hasOwnProperty = Object.hasOwnProperty;
const has = (obj, key) => hasOwnProperty.call(obj, key);
const checkRange = (str, substr, start) => substr === '' || str.length >= substr.length && str.substr(start, start + substr.length) === substr;
const contains = (str, substr, start = 0, end) => {
const idx = str.indexOf(substr, start);
if (idx !== -1) {
return isUndefined(end) ? true : idx + substr.length <= end;
}
else {
return false;
}
};
/** Does 'str' start with 'prefix'?
* Note: all strings start with the empty string.
* More formally, for all strings x, startsWith(x, "").
* This is so that for all strings x and y, startsWith(y + x, y)
*/
const startsWith = (str, prefix) => {
return checkRange(str, prefix, 0);
};
const zeroWidth = '\uFEFF';
const isZwsp = (char) => char === zeroWidth;
const removeZwsp = (s) => s.replace(/\uFEFF/g, '');
/*
The RegEx parses the following components (https://www.rfc-editor.org/rfc/rfc3986.txt):
scheme:[//[user:password@]host[:port]][/]path[?query][#fragment]
foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
Originally from:
http://blog.mattheworiordan.com/post/13174566389/url-regular-expression-for-links-with-or-without-the
Modified to:
- include port numbers
- allow full stops in email addresses
- allow [-.~*+=!&;:'%@?^${}(),\/\w] after the #
- allow [-.~*+=!&;:'%@?^${}(),\/\w] after the ?
- move allow -_.~*+=!&;:'%@?^${}() in email usernames to the first @ match (TBIO-4809)
- enforce domains to be [A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)* so they can't end in a period (TBIO-4809)
- removed a bunch of escaping, made every group non-capturing (during TBIO-4809)
- colons are only valid when followed directly by // or some text and then @ (TBIO-4867)
- only include the fragment '#' if it has 1 or more trailing matches
- only include the query '?' if it has 1 or more trailing matches
- allow commas in URL path
- exclude trailing comma and period in URL path
- allow up to 15 character schemes including all valid characters from the spec https://url.spec.whatwg.org/#url-scheme-string (TINY-5074)
- changed instances of 0-9 to be \d (TINY-5074)
- reduced duplication (TINY-5074)
- allow [*!;:'@$] in the path segment as they are valid characters per the spec: https://url.spec.whatwg.org/#url-path-segment-string (TINY-8069)
(?:
(?:
[A-Za-z][A-Za-z\d.+-]{0,14}:\/\/(?:[-.~*+=!&;:'%@?^${}(),\w]+@)?
| www\.
| [-;:&=+$,.\w]+@
)
[A-Za-z\d-]+
(?:\.[A-Za-z\d-]+)*
)
(?::\d+)?
(?:
\/
(?:
[-.~*+=!;:'%@$(),\/\w]*[-~*+=%@$()\/\w]
)?
)?
(?:
\?
(?:
[-.~*+=!&;:'%@?^${}(),\/\w]+
)
)?
(?:
#
(?:
[-.~*+=!&;:'%@?^${}(),\/\w]+
)
)?
*/
const link = () =>
// eslint-disable-next-line max-len
/(?:[A-Za-z][A-Za-z\d.+-]{0,14}:\/\/(?:[-.~*+=!&;:'%@?^${}(),\w]+@)?|www\.|[-;:&=+$,.\w]+@)[A-Za-z\d-]+(?:\.[A-Za-z\d-]+)*(?::\d+)?(?:\/(?:[-.~*+=!;:'%@$(),\/\w]*[-~*+=%@$()\/\w])?)?(?:\?(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?(?:#(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?/g;
const option = (name) => (editor) => editor.options.get(name);
const register = (editor) => {
const registerOption = editor.options.register;
registerOption('autolink_pattern', {
processor: 'regexp',
// Use the Polaris link detection, however for autolink we need to make it be an exact match
default: new RegExp('^' + link().source + '$', 'i')
});
registerOption('link_default_target', {
processor: 'string'
});
registerOption('link_default_protocol', {
processor: 'string',
default: 'https'
});
};
const getAutoLinkPattern = option('autolink_pattern');
const getDefaultLinkTarget = option('link_default_target');
const getDefaultLinkProtocol = option('link_default_protocol');
const allowUnsafeLinkTarget = option('allow_unsafe_link_target');
var global = tinymce.util.Tools.resolve('tinymce.dom.TextSeeker');
const isTextNode = (node) => node.nodeType === 3;
const isElement = (node) => node.nodeType === 1;
const isBracketOrSpace = (char) => /^[(\[{ \u00a0]$/.test(char);
// Note: This is similar to the Polaris protocol detection, except it also handles `mailto` and any length scheme
const hasProtocol = (url) => /^([A-Za-z][A-Za-z\d.+-]*:\/\/)|mailto:/.test(url);
// A limited list of punctuation characters that might be used after a link
const isPunctuation = (char) => /[?!,.;:]/.test(char);
const findChar = (text, index, predicate) => {
for (let i = index - 1; i >= 0; i--) {
const char = text.charAt(i);
if (!isZwsp(char) && predicate(char)) {
return i;
}
}
return -1;
};
const freefallRtl = (container, offset) => {
let tempNode = container;
let tempOffset = offset;
while (isElement(tempNode) && tempNode.childNodes[tempOffset]) {
tempNode = tempNode.childNodes[tempOffset];
tempOffset = isTextNode(tempNode) ? tempNode.data.length : tempNode.childNodes.length;
}
return { container: tempNode, offset: tempOffset };
};
const parseCurrentLine = (editor, offset) => {
const voidElements = editor.schema.getVoidElements();
const autoLinkPattern = getAutoLinkPattern(editor);
const { dom, selection } = editor;
// Never create a link when we are inside a link
if (dom.getParent(selection.getNode(), 'a[href]') !== null || editor.mode.isReadOnly()) {
return null;
}
const rng = selection.getRng();
const textSeeker = global(dom, (node) => {
return dom.isBlock(node) || has(voidElements, node.nodeName.toLowerCase()) || dom.getContentEditable(node) === 'false' || dom.getParent(node, 'a[href]') !== null;
});
// Descend down the end container to find the text node
const { container: endContainer, offset: endOffset } = freefallRtl(rng.endContainer, rng.endOffset);
// Find the root container to use when walking
const root = dom.getParent(endContainer, dom.isBlock) ?? dom.getRoot();
// Move the selection backwards to the start of the potential URL to account for the pressed character
// while also excluding the last full stop from a word like "www.site.com."
const endSpot = textSeeker.backwards(endContainer, endOffset + offset, (node, offset) => {
const text = node.data;
const idx = findChar(text, offset, not(isBracketOrSpace));
// Move forward one so the offset is after the found character unless the found char is a punctuation char
return idx === -1 || isPunctuation(text[idx]) ? idx : idx + 1;
}, root);
if (!endSpot) {
return null;
}
// Walk backwards until we find a boundary or a bracket/space
let lastTextNode = endSpot.container;
const startSpot = textSeeker.backwards(endSpot.container, endSpot.offset, (node, offset) => {
lastTextNode = node;
const idx = findChar(node.data, offset, isBracketOrSpace);
// Move forward one so that the offset is after the bracket/space
return idx === -1 ? idx : idx + 1;
}, root);
const newRng = dom.createRng();
if (!startSpot) {
newRng.setStart(lastTextNode, 0);
}
else {
newRng.setStart(startSpot.container, startSpot.offset);
}
newRng.setEnd(endSpot.container, endSpot.offset);
const rngText = removeZwsp(newRng.toString());
const matches = rngText.match(autoLinkPattern);
if (matches) {
let url = matches[0];
if (startsWith(url, 'www.')) {
const protocol = getDefaultLinkProtocol(editor);
url = protocol + '://' + url;
}
else if (contains(url, '@') && !hasProtocol(url)) {
url = 'mailto:' + url;
}
return { rng: newRng, url };
}
else {
return null;
}
};
const convertToLink = (editor, result) => {
const { dom, selection } = editor;
const { rng, url } = result;
const bookmark = selection.getBookmark();
selection.setRng(rng);
// Needs to be a native createlink command since this is executed in a keypress event handler
// so the pending character that is to be inserted needs to be inserted after the link. That will not
// happen if we use the formatter create link version. Since we're using the native command
// then we also need to ensure the exec command events are fired for backwards compatibility.
const command = 'createlink';
const args = { command, ui: false, value: url };
const beforeExecEvent = editor.dispatch('BeforeExecCommand', args);
if (!beforeExecEvent.isDefaultPrevented()) {
editor.getDoc().execCommand(command, false, url);
editor.dispatch('ExecCommand', args);
const defaultLinkTarget = getDefaultLinkTarget(editor);
if (isString(defaultLinkTarget)) {
const anchor = selection.getNode();
dom.setAttrib(anchor, 'target', defaultLinkTarget);
// Ensure noopener is added for blank targets to prevent window opener attacks
if (defaultLinkTarget === '_blank' && !allowUnsafeLinkTarget(editor)) {
dom.setAttrib(anchor, 'rel', 'noopener');
}
}
}
selection.moveToBookmark(bookmark);
editor.nodeChanged();
};
const handleSpacebar = (editor) => {
const result = parseCurrentLine(editor, -1);
if (isNonNullable(result)) {
convertToLink(editor, result);
}
};
const handleBracket = handleSpacebar;
const handleEnter = (editor) => {
const result = parseCurrentLine(editor, 0);
if (isNonNullable(result)) {
convertToLink(editor, result);
}
};
const setup = (editor) => {
editor.on('keydown', (e) => {
if (e.keyCode === 13 && !e.isDefaultPrevented()) {
handleEnter(editor);
}
});
editor.on('keyup', (e) => {
if (e.keyCode === 32) {
handleSpacebar(editor);
// One of the closing bracket keys: ), ] or }
}
else if (e.keyCode === 48 && e.shiftKey || e.keyCode === 221) {
handleBracket(editor);
}
});
};
var Plugin = () => {
global$1.add('autolink', (editor) => {
register(editor);
setup(editor);
});
};
Plugin();
/** *****
* DO NOT EXPORT ANYTHING
*
* IF YOU DO ROLLUP WILL LEAVE A GLOBAL ON THE PAGE
*******/
})();

View File

@@ -0,0 +1 @@
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>"string"===(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=o=e,(r=String).prototype.isPrototypeOf(n)||o.constructor?.name===r.name)?"string":t;var n,o,r})(e);const n=e=>undefined===e;const o=e=>!(e=>null==e)(e),r=Object.hasOwnProperty,a=e=>"\ufeff"===e,s=e=>t=>t.options.get(e),l=s("autolink_pattern"),c=s("link_default_target"),i=s("link_default_protocol"),d=s("allow_unsafe_link_target");var u=tinymce.util.Tools.resolve("tinymce.dom.TextSeeker");const f=e=>/^[(\[{ \u00a0]$/.test(e),g=(e,t,n)=>{for(let o=t-1;o>=0;o--){const t=e.charAt(o);if(!a(t)&&n(t))return o}return-1},m=(e,t)=>{const o=e.schema.getVoidElements(),a=l(e),{dom:s,selection:c}=e;if(null!==s.getParent(c.getNode(),"a[href]")||e.mode.isReadOnly())return null;const d=c.getRng(),m=u(s,(e=>{return s.isBlock(e)||(t=o,n=e.nodeName.toLowerCase(),r.call(t,n))||"false"===s.getContentEditable(e)||null!==s.getParent(e,"a[href]");var t,n})),{container:k,offset:p}=((e,t)=>{let n=e,o=t;for(;1===n.nodeType&&n.childNodes[o];)n=n.childNodes[o],o=3===n.nodeType?n.data.length:n.childNodes.length;return{container:n,offset:o}})(d.endContainer,d.endOffset),y=s.getParent(k,s.isBlock)??s.getRoot(),w=m.backwards(k,p+t,((e,t)=>{const n=e.data,o=g(n,t,(r=f,e=>!r(e)));var r,a;return-1===o||(a=n[o],/[?!,.;:]/.test(a))?o:o+1}),y);if(!w)return null;let h=w.container;const _=m.backwards(w.container,w.offset,((e,t)=>{h=e;const n=g(e.data,t,f);return-1===n?n:n+1}),y),v=s.createRng();_?v.setStart(_.container,_.offset):v.setStart(h,0),v.setEnd(w.container,w.offset);const A=v.toString().replace(/\uFEFF/g,"").match(a);if(A){let t=A[0];return b="www.",(C=t).length>=4&&C.substr(0,4)===b?t=i(e)+"://"+t:((e,t,o=0,r)=>{const a=e.indexOf(t,o);return-1!==a&&(!!n(r)||a+t.length<=r)})(t,"@")&&!(e=>/^([A-Za-z][A-Za-z\d.+-]*:\/\/)|mailto:/.test(e))(t)&&(t="mailto:"+t),{rng:v,url:t}}var C,b;return null},k=(e,n)=>{const{dom:o,selection:r}=e,{rng:a,url:s}=n,l=r.getBookmark();r.setRng(a);const i="createlink",u={command:i,ui:!1,value:s};if(!e.dispatch("BeforeExecCommand",u).isDefaultPrevented()){e.getDoc().execCommand(i,!1,s),e.dispatch("ExecCommand",u);const n=c(e);if(t(n)){const t=r.getNode();o.setAttrib(t,"target",n),"_blank"!==n||d(e)||o.setAttrib(t,"rel","noopener")}}r.moveToBookmark(l),e.nodeChanged()},p=e=>{const t=m(e,-1);o(t)&&k(e,t)},y=p;e.add("autolink",(e=>{(e=>{const t=e.options.register;t("autolink_pattern",{processor:"regexp",default:new RegExp("^"+/(?:[A-Za-z][A-Za-z\d.+-]{0,14}:\/\/(?:[-.~*+=!&;:'%@?^${}(),\w]+@)?|www\.|[-;:&=+$,.\w]+@)[A-Za-z\d-]+(?:\.[A-Za-z\d-]+)*(?::\d+)?(?:\/(?:[-.~*+=!;:'%@$(),\/\w]*[-~*+=%@$()\/\w])?)?(?:\?(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?(?:#(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?/g.source+"$","i")}),t("link_default_target",{processor:"string"}),t("link_default_protocol",{processor:"string",default:"https"})})(e),(e=>{e.on("keydown",(t=>{13!==t.keyCode||t.isDefaultPrevented()||(e=>{const t=m(e,0);o(t)&&k(e,t)})(e)})),e.on("keyup",(t=>{32===t.keyCode?p(e):(48===t.keyCode&&t.shiftKey||221===t.keyCode)&&y(e)}))})(e)}))}();

View File

@@ -0,0 +1,7 @@
// Exports the "autoresize" plugin for usage with module loaders
// Usage:
// CommonJS:
// require('tinymce/plugins/autoresize')
// ES2015:
// import 'tinymce/plugins/autoresize'
require('./plugin.js');

View File

@@ -0,0 +1,221 @@
/**
* TinyMCE version 8.3.2 (2026-01-14)
*/
(function () {
'use strict';
const Cell = (initial) => {
let value = initial;
const get = () => {
return value;
};
const set = (v) => {
value = v;
};
return {
get,
set
};
};
var global$1 = tinymce.util.Tools.resolve('tinymce.PluginManager');
var global = tinymce.util.Tools.resolve('tinymce.Env');
const fireResizeEditor = (editor) => editor.dispatch('ResizeEditor');
const option = (name) => (editor) => editor.options.get(name);
const register$1 = (editor) => {
const registerOption = editor.options.register;
registerOption('autoresize_overflow_padding', {
processor: 'number',
default: 1
});
registerOption('autoresize_bottom_margin', {
processor: 'number',
default: 50
});
};
const getMinHeight = option('min_height');
const getMaxHeight = option('max_height');
const getAutoResizeOverflowPadding = option('autoresize_overflow_padding');
const getAutoResizeBottomMargin = option('autoresize_bottom_margin');
/**
* This class contains all core logic for the autoresize plugin.
*
* @class tinymce.autoresize.Plugin
* @private
*/
const isFullscreen = (editor) => editor.plugins.fullscreen && editor.plugins.fullscreen.isFullscreen();
const toggleScrolling = (editor, state) => {
const body = editor.getBody();
if (body) {
body.style.overflowY = state ? '' : 'hidden';
if (!state) {
body.scrollTop = 0;
}
}
};
const parseCssValueToInt = (dom, elm, name, computed) => {
const value = parseInt(dom.getStyle(elm, name, computed) ?? '', 10);
// The value maybe be an empty string, so in that case treat it as being 0
return isNaN(value) ? 0 : value;
};
const shouldScrollIntoView = (trigger) => {
// Only scroll the selection into view when we're inserting content. Any other
// triggers the selection should already be in view and resizing would only
// extend the content area.
if (trigger?.type.toLowerCase() === 'setcontent') {
const setContentEvent = trigger;
return setContentEvent.selection === true || setContentEvent.paste === true;
}
else {
return false;
}
};
/**
* This method gets executed each time the editor needs to resize.
*/
const resize = (editor, oldSize, trigger, getExtraMarginBottom) => {
const dom = editor.dom;
const doc = editor.getDoc();
if (!doc) {
return;
}
if (isFullscreen(editor)) {
toggleScrolling(editor, true);
return;
}
const docEle = doc.documentElement;
const resizeBottomMargin = getExtraMarginBottom ? getExtraMarginBottom() : getAutoResizeOverflowPadding(editor);
const minHeight = getMinHeight(editor) ?? editor.getElement().offsetHeight;
let resizeHeight = minHeight;
// Calculate outer height of the doc element using CSS styles
const marginTop = parseCssValueToInt(dom, docEle, 'margin-top', true);
const marginBottom = parseCssValueToInt(dom, docEle, 'margin-bottom', true);
let contentHeight = docEle.offsetHeight + marginTop + marginBottom + resizeBottomMargin;
// Make sure we have a valid height
if (contentHeight < 0) {
contentHeight = 0;
}
// Determine the size of the chroming (menubar, toolbar, etc...)
const containerHeight = editor.getContainer().offsetHeight;
const contentAreaHeight = editor.getContentAreaContainer().offsetHeight;
const chromeHeight = containerHeight - contentAreaHeight;
// Don't make it smaller than the minimum height
if (contentHeight + chromeHeight > minHeight) {
resizeHeight = contentHeight + chromeHeight;
}
// If a maximum height has been defined don't exceed this height
const maxHeight = getMaxHeight(editor);
if (maxHeight && resizeHeight > maxHeight) {
resizeHeight = maxHeight;
toggleScrolling(editor, true);
}
else {
toggleScrolling(editor, false);
}
const old = oldSize.get();
if (old.set) {
editor.dom.setStyles(editor.getDoc().documentElement, { 'min-height': 0 });
editor.dom.setStyles(editor.getBody(), { 'min-height': 'inherit' });
}
// Resize content element
if (resizeHeight !== old.totalHeight && (contentHeight - resizeBottomMargin !== old.contentHeight || !old.set)) {
const deltaSize = (resizeHeight - old.totalHeight);
dom.setStyle(editor.getContainer(), 'height', resizeHeight + 'px');
oldSize.set({
totalHeight: resizeHeight,
contentHeight,
set: true,
});
fireResizeEditor(editor);
// iPadOS has an issue where it won't rerender the body when the iframe is resized
// however if we reset the scroll position then it re-renders correctly
if (global.browser.isSafari() && (global.os.isMacOS() || global.os.isiOS())) {
const win = editor.getWin();
win.scrollTo(win.pageXOffset, win.pageYOffset);
}
// Ensure the selection is in view, as it's potentially out of view after inserting content into the editor
if (editor.hasFocus() && shouldScrollIntoView(trigger)) {
editor.selection.scrollIntoView();
}
// WebKit doesn't decrease the size of the body element until the iframe gets resized
// So we need to continue to resize the iframe down until the size gets fixed
if ((global.browser.isSafari() || global.browser.isChromium()) && deltaSize < 0) {
resize(editor, oldSize, trigger, getExtraMarginBottom);
}
}
};
const setup = (editor, oldSize) => {
const getExtraMarginBottom = () => getAutoResizeBottomMargin(editor);
editor.on('init', (e) => {
const overflowPadding = getAutoResizeOverflowPadding(editor);
const dom = editor.dom;
// Disable height 100% on the root document element otherwise we'll end up resizing indefinitely
dom.setStyles(editor.getDoc().documentElement, {
height: 'auto'
});
if (global.browser.isEdge() || global.browser.isIE()) {
dom.setStyles(editor.getBody(), {
'paddingLeft': overflowPadding,
'paddingRight': overflowPadding,
// IE & Edge have a min height of 150px by default on the body, so override that
'min-height': 0
});
}
else {
dom.setStyles(editor.getBody(), {
paddingLeft: overflowPadding,
paddingRight: overflowPadding
});
}
resize(editor, oldSize, e, getExtraMarginBottom);
});
editor.on('NodeChange SetContent keyup FullscreenStateChanged ResizeContent', (e) => {
resize(editor, oldSize, e, getExtraMarginBottom);
});
};
const register = (editor, oldSize) => {
editor.addCommand('mceAutoResize', () => {
resize(editor, oldSize);
});
};
/**
* This class contains all core logic for the autoresize plugin.
*
* @class tinymce.autoresize.Plugin
* @private
*/
var Plugin = () => {
global$1.add('autoresize', (editor) => {
register$1(editor);
// If autoresize is enabled, disable resize if the user hasn't explicitly enabled it
// TINY-8288: This currently does nothing because of a bug in the theme
if (!editor.options.isSet('resize')) {
editor.options.set('resize', false);
}
if (!editor.inline) {
const oldSize = Cell({
totalHeight: 0,
contentHeight: 0,
set: false,
});
register(editor, oldSize);
setup(editor, oldSize);
}
});
};
Plugin();
/** *****
* DO NOT EXPORT ANYTHING
*
* IF YOU DO ROLLUP WILL LEAVE A GLOBAL ON THE PAGE
*******/
})();

View File

@@ -0,0 +1 @@
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.Env");const o=e=>t=>t.options.get(e),s=o("min_height"),n=o("max_height"),i=o("autoresize_overflow_padding"),r=o("autoresize_bottom_margin"),g=(e,t)=>{const o=e.getBody();o&&(o.style.overflowY=t?"":"hidden",t||(o.scrollTop=0))},l=(e,t,o,s)=>{const n=parseInt(e.getStyle(t,o,s)??"",10);return isNaN(n)?0:n},a=(e,o,r,c)=>{const d=e.dom,h=e.getDoc();if(!h)return;if((e=>e.plugins.fullscreen&&e.plugins.fullscreen.isFullscreen())(e))return void g(e,!0);const m=h.documentElement,u=c?c():i(e),f=s(e)??e.getElement().offsetHeight;let p=f;const y=l(d,m,"margin-top",!0),S=l(d,m,"margin-bottom",!0);let C=m.offsetHeight+y+S+u;C<0&&(C=0);const H=e.getContainer().offsetHeight-e.getContentAreaContainer().offsetHeight;C+H>f&&(p=C+H);const b=n(e);b&&p>b?(p=b,g(e,!0)):g(e,!1);const w=o.get();if(w.set&&(e.dom.setStyles(e.getDoc().documentElement,{"min-height":0}),e.dom.setStyles(e.getBody(),{"min-height":"inherit"})),p!==w.totalHeight&&(C-u!==w.contentHeight||!w.set)){const s=p-w.totalHeight;if(d.setStyle(e.getContainer(),"height",p+"px"),o.set({totalHeight:p,contentHeight:C,set:!0}),(e=>{e.dispatch("ResizeEditor")})(e),t.browser.isSafari()&&(t.os.isMacOS()||t.os.isiOS())){const t=e.getWin();t.scrollTo(t.pageXOffset,t.pageYOffset)}e.hasFocus()&&(e=>{if("setcontent"===e?.type.toLowerCase()){const t=e;return!0===t.selection||!0===t.paste}return!1})(r)&&e.selection.scrollIntoView(),(t.browser.isSafari()||t.browser.isChromium())&&s<0&&a(e,o,r,c)}};e.add("autoresize",(e=>{if((e=>{const t=e.options.register;t("autoresize_overflow_padding",{processor:"number",default:1}),t("autoresize_bottom_margin",{processor:"number",default:50})})(e),e.options.isSet("resize")||e.options.set("resize",!1),!e.inline){const o=(()=>{let e={totalHeight:0,contentHeight:0,set:!1};return{get:()=>e,set:t=>{e=t}}})();((e,t)=>{e.addCommand("mceAutoResize",(()=>{a(e,t)}))})(e,o),((e,o)=>{const s=()=>r(e);e.on("init",(n=>{const r=i(e),g=e.dom;g.setStyles(e.getDoc().documentElement,{height:"auto"}),t.browser.isEdge()||t.browser.isIE()?g.setStyles(e.getBody(),{paddingLeft:r,paddingRight:r,"min-height":0}):g.setStyles(e.getBody(),{paddingLeft:r,paddingRight:r}),a(e,o,n,s)})),e.on("NodeChange SetContent keyup FullscreenStateChanged ResizeContent",(t=>{a(e,o,t,s)}))})(e,o)}}))}();

View File

@@ -0,0 +1,7 @@
// Exports the "autosave" plugin for usage with module loaders
// Usage:
// CommonJS:
// require('tinymce/plugins/autosave')
// ES2015:
// import 'tinymce/plugins/autosave'
require('./plugin.js');

View File

@@ -0,0 +1,249 @@
/**
* TinyMCE version 8.3.2 (2026-01-14)
*/
(function () {
'use strict';
var global$4 = tinymce.util.Tools.resolve('tinymce.PluginManager');
/* eslint-disable @typescript-eslint/no-wrapper-object-types */
const hasProto = (v, constructor, predicate) => {
if (predicate(v, constructor.prototype)) {
return true;
}
else {
// String-based fallback time
return v.constructor?.name === constructor.name;
}
};
const typeOf = (x) => {
const t = typeof x;
if (x === null) {
return 'null';
}
else if (t === 'object' && Array.isArray(x)) {
return 'array';
}
else if (t === 'object' && hasProto(x, String, (o, proto) => proto.isPrototypeOf(o))) {
return 'string';
}
else {
return t;
}
};
const isType = (type) => (value) => typeOf(value) === type;
const eq = (t) => (a) => t === a;
const isString = isType('string');
const isUndefined = eq(undefined);
var global$3 = tinymce.util.Tools.resolve('tinymce.util.Delay');
var global$2 = tinymce.util.Tools.resolve('tinymce.util.LocalStorage');
var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools');
const fireRestoreDraft = (editor) => editor.dispatch('RestoreDraft');
const fireStoreDraft = (editor) => editor.dispatch('StoreDraft');
const fireRemoveDraft = (editor) => editor.dispatch('RemoveDraft');
const parse = (timeString) => {
const multiples = {
s: 1000,
m: 60000
};
const parsedTime = /^(\d+)([ms]?)$/.exec(timeString);
return (parsedTime && parsedTime[2] ? multiples[parsedTime[2]] : 1) * parseInt(timeString, 10);
};
const option = (name) => (editor) => editor.options.get(name);
const register$1 = (editor) => {
const registerOption = editor.options.register;
const timeProcessor = (value) => {
const valid = isString(value);
if (valid) {
return { value: parse(value), valid };
}
else {
return { valid: false, message: 'Must be a string.' };
}
};
registerOption('autosave_ask_before_unload', {
processor: 'boolean',
default: true
});
registerOption('autosave_prefix', {
processor: 'string',
default: 'tinymce-autosave-{path}{query}{hash}-{id}-'
});
registerOption('autosave_restore_when_empty', {
processor: 'boolean',
default: false
});
registerOption('autosave_interval', {
processor: timeProcessor,
default: '30s'
});
registerOption('autosave_retention', {
processor: timeProcessor,
default: '20m'
});
};
const shouldAskBeforeUnload = option('autosave_ask_before_unload');
const shouldRestoreWhenEmpty = option('autosave_restore_when_empty');
const getAutoSaveInterval = option('autosave_interval');
const getAutoSaveRetention = option('autosave_retention');
const getAutoSavePrefix = (editor) => {
const location = document.location;
return editor.options.get('autosave_prefix').replace(/{path}/g, location.pathname)
.replace(/{query}/g, location.search)
.replace(/{hash}/g, location.hash)
.replace(/{id}/g, editor.id);
};
const isEmpty = (editor, html) => {
if (isUndefined(html)) {
return editor.dom.isEmpty(editor.getBody());
}
else {
const trimmedHtml = global$1.trim(html);
if (trimmedHtml === '') {
return true;
}
else {
const fragment = new DOMParser().parseFromString(trimmedHtml, 'text/html');
return editor.dom.isEmpty(fragment);
}
}
};
const hasDraft = (editor) => {
const time = parseInt(global$2.getItem(getAutoSavePrefix(editor) + 'time') ?? '0', 10) || 0;
if (new Date().getTime() - time > getAutoSaveRetention(editor)) {
removeDraft(editor, false);
return false;
}
return true;
};
const removeDraft = (editor, fire) => {
const prefix = getAutoSavePrefix(editor);
global$2.removeItem(prefix + 'draft');
global$2.removeItem(prefix + 'time');
if (fire !== false) {
fireRemoveDraft(editor);
}
};
const storeDraft = (editor) => {
const prefix = getAutoSavePrefix(editor);
if (!isEmpty(editor) && editor.isDirty()) {
global$2.setItem(prefix + 'draft', editor.getContent({ format: 'raw', no_events: true }));
global$2.setItem(prefix + 'time', new Date().getTime().toString());
fireStoreDraft(editor);
}
};
const restoreDraft = (editor) => {
const prefix = getAutoSavePrefix(editor);
if (hasDraft(editor)) {
editor.setContent(global$2.getItem(prefix + 'draft') ?? '', { format: 'raw' });
fireRestoreDraft(editor);
}
};
const startStoreDraft = (editor) => {
const interval = getAutoSaveInterval(editor);
global$3.setEditorInterval(editor, () => {
storeDraft(editor);
}, interval);
};
const restoreLastDraft = (editor) => {
editor.undoManager.transact(() => {
restoreDraft(editor);
removeDraft(editor);
});
editor.focus();
};
const get = (editor) => ({
hasDraft: () => hasDraft(editor),
storeDraft: () => storeDraft(editor),
restoreDraft: () => restoreDraft(editor),
removeDraft: (fire) => removeDraft(editor, fire),
isEmpty: (html) => isEmpty(editor, html)
});
var global = tinymce.util.Tools.resolve('tinymce.EditorManager');
const setup = (editor) => {
editor.editorManager.on('BeforeUnload', (e) => {
let msg;
global$1.each(global.get(), (editor) => {
// Store a draft for each editor instance
if (editor.plugins.autosave) {
editor.plugins.autosave.storeDraft();
}
// Setup a return message if the editor is dirty
if (!msg && editor.isDirty() && shouldAskBeforeUnload(editor)) {
msg = editor.translate('You have unsaved changes are you sure you want to navigate away?');
}
});
if (msg) {
e.preventDefault();
e.returnValue = msg;
}
});
};
const makeSetupHandler = (editor) => (api) => {
const shouldEnable = () => hasDraft(editor) && !editor.mode.isReadOnly();
api.setEnabled(shouldEnable());
const editorEventCallback = () => api.setEnabled(shouldEnable());
editor.on('StoreDraft RestoreDraft RemoveDraft', editorEventCallback);
return () => editor.off('StoreDraft RestoreDraft RemoveDraft', editorEventCallback);
};
const register = (editor) => {
// TODO: This was moved from makeSetupHandler as it would only be called when the menu item was rendered?
// Is it safe to start this process when the plugin is registered?
startStoreDraft(editor);
const onAction = () => {
restoreLastDraft(editor);
};
editor.ui.registry.addButton('restoredraft', {
tooltip: 'Restore last draft',
icon: 'restore-draft',
onAction,
onSetup: makeSetupHandler(editor)
});
editor.ui.registry.addMenuItem('restoredraft', {
text: 'Restore last draft',
icon: 'restore-draft',
onAction,
onSetup: makeSetupHandler(editor)
});
};
/**
* This class contains all core logic for the autosave plugin.
*
* @class tinymce.autosave.Plugin
* @private
*/
var Plugin = () => {
global$4.add('autosave', (editor) => {
register$1(editor);
setup(editor);
register(editor);
editor.on('init', () => {
if (shouldRestoreWhenEmpty(editor) && editor.dom.isEmpty(editor.getBody())) {
restoreDraft(editor);
}
});
return get(editor);
});
};
Plugin();
/** *****
* DO NOT EXPORT ANYTHING
*
* IF YOU DO ROLLUP WILL LEAVE A GLOBAL ON THE PAGE
*******/
})();

View File

@@ -0,0 +1 @@
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(r=o=t,(a=String).prototype.isPrototypeOf(r)||o.constructor?.name===a.name)?"string":e;var r,o,a})(t);const r=t=>undefined===t;var o=tinymce.util.Tools.resolve("tinymce.util.Delay"),a=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),s=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=t=>{const e=/^(\d+)([ms]?)$/.exec(t);return(e&&e[2]?{s:1e3,m:6e4}[e[2]]:1)*parseInt(t,10)},i=t=>e=>e.options.get(t),u=i("autosave_ask_before_unload"),c=i("autosave_restore_when_empty"),l=i("autosave_interval"),m=i("autosave_retention"),d=t=>{const e=document.location;return t.options.get("autosave_prefix").replace(/{path}/g,e.pathname).replace(/{query}/g,e.search).replace(/{hash}/g,e.hash).replace(/{id}/g,t.id)},f=(t,e)=>{if(r(e))return t.dom.isEmpty(t.getBody());{const r=s.trim(e);if(""===r)return!0;{const e=(new DOMParser).parseFromString(r,"text/html");return t.dom.isEmpty(e)}}},v=t=>{const e=parseInt(a.getItem(d(t)+"time")??"0",10)||0;return!((new Date).getTime()-e>m(t)&&(p(t,!1),1))},p=(t,e)=>{const r=d(t);a.removeItem(r+"draft"),a.removeItem(r+"time"),!1!==e&&(t=>{t.dispatch("RemoveDraft")})(t)},y=t=>{const e=d(t);!f(t)&&t.isDirty()&&(a.setItem(e+"draft",t.getContent({format:"raw",no_events:!0})),a.setItem(e+"time",(new Date).getTime().toString()),(t=>{t.dispatch("StoreDraft")})(t))},g=t=>{const e=d(t);v(t)&&(t.setContent(a.getItem(e+"draft")??"",{format:"raw"}),(t=>{t.dispatch("RestoreDraft")})(t))};var D=tinymce.util.Tools.resolve("tinymce.EditorManager");const h=t=>e=>{const r=()=>v(t)&&!t.mode.isReadOnly();e.setEnabled(r());const o=()=>e.setEnabled(r());return t.on("StoreDraft RestoreDraft RemoveDraft",o),()=>t.off("StoreDraft RestoreDraft RemoveDraft",o)};t.add("autosave",(t=>((t=>{const r=t.options.register,o=t=>{const r=e(t);return r?{value:n(t),valid:r}:{valid:!1,message:"Must be a string."}};r("autosave_ask_before_unload",{processor:"boolean",default:!0}),r("autosave_prefix",{processor:"string",default:"tinymce-autosave-{path}{query}{hash}-{id}-"}),r("autosave_restore_when_empty",{processor:"boolean",default:!1}),r("autosave_interval",{processor:o,default:"30s"}),r("autosave_retention",{processor:o,default:"20m"})})(t),(t=>{t.editorManager.on("BeforeUnload",(t=>{let e;s.each(D.get(),(t=>{t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&u(t)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))})),e&&(t.preventDefault(),t.returnValue=e)}))})(t),(t=>{(t=>{const e=l(t);o.setEditorInterval(t,(()=>{y(t)}),e)})(t);const e=()=>{(t=>{t.undoManager.transact((()=>{g(t),p(t)})),t.focus()})(t)};t.ui.registry.addButton("restoredraft",{tooltip:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)}),t.ui.registry.addMenuItem("restoredraft",{text:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)})})(t),t.on("init",(()=>{c(t)&&t.dom.isEmpty(t.getBody())&&g(t)})),(t=>({hasDraft:()=>v(t),storeDraft:()=>y(t),restoreDraft:()=>g(t),removeDraft:e=>p(t,e),isEmpty:e=>f(t,e)}))(t))))}();

View File

@@ -0,0 +1,7 @@
// Exports the "charmap" plugin for usage with module loaders
// Usage:
// CommonJS:
// require('tinymce/plugins/charmap')
// ES2015:
// import 'tinymce/plugins/charmap'
require('./plugin.js');

View File

@@ -0,0 +1,997 @@
/**
* TinyMCE version 8.3.2 (2026-01-14)
*/
(function () {
'use strict';
var global$1 = tinymce.util.Tools.resolve('tinymce.PluginManager');
const fireInsertCustomChar = (editor, chr) => {
return editor.dispatch('insertCustomChar', { chr });
};
const insertChar = (editor, chr) => {
const evtChr = fireInsertCustomChar(editor, chr).chr;
editor.execCommand('mceInsertContent', false, evtChr);
};
/* eslint-disable @typescript-eslint/no-wrapper-object-types */
const hasProto = (v, constructor, predicate) => {
if (predicate(v, constructor.prototype)) {
return true;
}
else {
// String-based fallback time
return v.constructor?.name === constructor.name;
}
};
const typeOf = (x) => {
const t = typeof x;
if (x === null) {
return 'null';
}
else if (t === 'object' && Array.isArray(x)) {
return 'array';
}
else if (t === 'object' && hasProto(x, String, (o, proto) => proto.isPrototypeOf(o))) {
return 'string';
}
else {
return t;
}
};
const isType = (type) => (value) => typeOf(value) === type;
const isSimpleType = (type) => (value) => typeof value === type;
const eq = (t) => (a) => t === a;
const isArray$1 = isType('array');
const isNull = eq(null);
const isUndefined = eq(undefined);
const isNullable = (a) => a === null || a === undefined;
const isNonNullable = (a) => !isNullable(a);
const isFunction = isSimpleType('function');
const constant = (value) => {
return () => {
return value;
};
};
const never = constant(false);
/**
* The `Optional` type represents a value (of any type) that potentially does
* not exist. Any `Optional<T>` can either be a `Some<T>` (in which case the
* value does exist) or a `None` (in which case the value does not exist). This
* module defines a whole lot of FP-inspired utility functions for dealing with
* `Optional` objects.
*
* Comparison with null or undefined:
* - We don't get fancy null coalescing operators with `Optional`
* - We do get fancy helper functions with `Optional`
* - `Optional` support nesting, and allow for the type to still be nullable (or
* another `Optional`)
* - There is no option to turn off strict-optional-checks like there is for
* strict-null-checks
*/
class Optional {
tag;
value;
// Sneaky optimisation: every instance of Optional.none is identical, so just
// reuse the same object
static singletonNone = new Optional(false);
// The internal representation has a `tag` and a `value`, but both are
// private: able to be console.logged, but not able to be accessed by code
constructor(tag, value) {
this.tag = tag;
this.value = value;
}
// --- Identities ---
/**
* Creates a new `Optional<T>` that **does** contain a value.
*/
static some(value) {
return new Optional(true, value);
}
/**
* Create a new `Optional<T>` that **does not** contain a value. `T` can be
* any type because we don't actually have a `T`.
*/
static none() {
return Optional.singletonNone;
}
/**
* Perform a transform on an `Optional` type. Regardless of whether this
* `Optional` contains a value or not, `fold` will return a value of type `U`.
* If this `Optional` does not contain a value, the `U` will be created by
* calling `onNone`. If this `Optional` does contain a value, the `U` will be
* created by calling `onSome`.
*
* For the FP enthusiasts in the room, this function:
* 1. Could be used to implement all of the functions below
* 2. Forms a catamorphism
*/
fold(onNone, onSome) {
if (this.tag) {
return onSome(this.value);
}
else {
return onNone();
}
}
/**
* Determine if this `Optional` object contains a value.
*/
isSome() {
return this.tag;
}
/**
* Determine if this `Optional` object **does not** contain a value.
*/
isNone() {
return !this.tag;
}
// --- Functor (name stolen from Haskell / maths) ---
/**
* Perform a transform on an `Optional` object, **if** there is a value. If
* you provide a function to turn a T into a U, this is the function you use
* to turn an `Optional<T>` into an `Optional<U>`. If this **does** contain
* a value then the output will also contain a value (that value being the
* output of `mapper(this.value)`), and if this **does not** contain a value
* then neither will the output.
*/
map(mapper) {
if (this.tag) {
return Optional.some(mapper(this.value));
}
else {
return Optional.none();
}
}
// --- Monad (name stolen from Haskell / maths) ---
/**
* Perform a transform on an `Optional` object, **if** there is a value.
* Unlike `map`, here the transform itself also returns an `Optional`.
*/
bind(binder) {
if (this.tag) {
return binder(this.value);
}
else {
return Optional.none();
}
}
// --- Traversable (name stolen from Haskell / maths) ---
/**
* For a given predicate, this function finds out if there **exists** a value
* inside this `Optional` object that meets the predicate. In practice, this
* means that for `Optional`s that do not contain a value it returns false (as
* no predicate-meeting value exists).
*/
exists(predicate) {
return this.tag && predicate(this.value);
}
/**
* For a given predicate, this function finds out if **all** the values inside
* this `Optional` object meet the predicate. In practice, this means that
* for `Optional`s that do not contain a value it returns true (as all 0
* objects do meet the predicate).
*/
forall(predicate) {
return !this.tag || predicate(this.value);
}
filter(predicate) {
if (!this.tag || predicate(this.value)) {
return this;
}
else {
return Optional.none();
}
}
// --- Getters ---
/**
* Get the value out of the inside of the `Optional` object, using a default
* `replacement` value if the provided `Optional` object does not contain a
* value.
*/
getOr(replacement) {
return this.tag ? this.value : replacement;
}
/**
* Get the value out of the inside of the `Optional` object, using a default
* `replacement` value if the provided `Optional` object does not contain a
* value. Unlike `getOr`, in this method the `replacement` object is also
* `Optional` - meaning that this method will always return an `Optional`.
*/
or(replacement) {
return this.tag ? this : replacement;
}
/**
* Get the value out of the inside of the `Optional` object, using a default
* `replacement` value if the provided `Optional` object does not contain a
* value. Unlike `getOr`, in this method the `replacement` value is
* "thunked" - that is to say that you don't pass a value to `getOrThunk`, you
* pass a function which (if called) will **return** the `value` you want to
* use.
*/
getOrThunk(thunk) {
return this.tag ? this.value : thunk();
}
/**
* Get the value out of the inside of the `Optional` object, using a default
* `replacement` value if the provided Optional object does not contain a
* value.
*
* Unlike `or`, in this method the `replacement` value is "thunked" - that is
* to say that you don't pass a value to `orThunk`, you pass a function which
* (if called) will **return** the `value` you want to use.
*
* Unlike `getOrThunk`, in this method the `replacement` value is also
* `Optional`, meaning that this method will always return an `Optional`.
*/
orThunk(thunk) {
return this.tag ? this : thunk();
}
/**
* Get the value out of the inside of the `Optional` object, throwing an
* exception if the provided `Optional` object does not contain a value.
*
* WARNING:
* You should only be using this function if you know that the `Optional`
* object **is not** empty (otherwise you're throwing exceptions in production
* code, which is bad).
*
* In tests this is more acceptable.
*
* Prefer other methods to this, such as `.each`.
*/
getOrDie(message) {
if (!this.tag) {
throw new Error(message ?? 'Called getOrDie on None');
}
else {
return this.value;
}
}
// --- Interop with null and undefined ---
/**
* Creates an `Optional` value from a nullable (or undefined-able) input.
* Null, or undefined, is converted to `None`, and anything else is converted
* to `Some`.
*/
static from(value) {
return isNonNullable(value) ? Optional.some(value) : Optional.none();
}
/**
* Converts an `Optional` to a nullable type, by getting the value if it
* exists, or returning `null` if it does not.
*/
getOrNull() {
return this.tag ? this.value : null;
}
/**
* Converts an `Optional` to an undefined-able type, by getting the value if
* it exists, or returning `undefined` if it does not.
*/
getOrUndefined() {
return this.value;
}
// --- Utilities ---
/**
* If the `Optional` contains a value, perform an action on that value.
* Unlike the rest of the methods on this type, `.each` has side-effects. If
* you want to transform an `Optional<T>` **into** something, then this is not
* the method for you. If you want to use an `Optional<T>` to **do**
* something, then this is the method for you - provided you're okay with not
* doing anything in the case where the `Optional` doesn't have a value inside
* it. If you're not sure whether your use-case fits into transforming
* **into** something or **doing** something, check whether it has a return
* value. If it does, you should be performing a transform.
*/
each(worker) {
if (this.tag) {
worker(this.value);
}
}
/**
* Turn the `Optional` object into an array that contains all of the values
* stored inside the `Optional`. In practice, this means the output will have
* either 0 or 1 elements.
*/
toArray() {
return this.tag ? [this.value] : [];
}
/**
* Turn the `Optional` object into a string for debugging or printing. Not
* recommended for production code, but good for debugging. Also note that
* these days an `Optional` object can be logged to the console directly, and
* its inner value (if it exists) will be visible.
*/
toString() {
return this.tag ? `some(${this.value})` : 'none()';
}
}
const nativeSlice = Array.prototype.slice;
const nativePush = Array.prototype.push;
const map = (xs, f) => {
// pre-allocating array size when it's guaranteed to be known
// http://jsperf.com/push-allocated-vs-dynamic/22
const len = xs.length;
const r = new Array(len);
for (let i = 0; i < len; i++) {
const x = xs[i];
r[i] = f(x, i);
}
return r;
};
// Unwound implementing other functions in terms of each.
// The code size is roughly the same, and it should allow for better optimisation.
// const each = function<T, U>(xs: T[], f: (x: T, i?: number, xs?: T[]) => void): void {
const each = (xs, f) => {
for (let i = 0, len = xs.length; i < len; i++) {
const x = xs[i];
f(x, i);
}
};
const findUntil = (xs, pred, until) => {
for (let i = 0, len = xs.length; i < len; i++) {
const x = xs[i];
if (pred(x, i)) {
return Optional.some(x);
}
else if (until(x, i)) {
break;
}
}
return Optional.none();
};
const find = (xs, pred) => {
return findUntil(xs, pred, never);
};
const flatten = (xs) => {
// Note, this is possible because push supports multiple arguments:
// http://jsperf.com/concat-push/6
// Note that in the past, concat() would silently work (very slowly) for array-like objects.
// With this change it will throw an error.
const r = [];
for (let i = 0, len = xs.length; i < len; ++i) {
// Ensure that each value is an array itself
if (!isArray$1(xs[i])) {
throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
}
nativePush.apply(r, xs[i]);
}
return r;
};
const bind = (xs, f) => flatten(map(xs, f));
isFunction(Array.from) ? Array.from : (x) => nativeSlice.call(x);
const Cell = (initial) => {
let value = initial;
const get = () => {
return value;
};
const set = (v) => {
value = v;
};
return {
get,
set
};
};
const contains = (str, substr, start = 0, end) => {
const idx = str.indexOf(substr, start);
if (idx !== -1) {
return isUndefined(end) ? true : idx + substr.length <= end;
}
else {
return false;
}
};
const fromCodePoint = String.fromCodePoint;
// Run a function fn after rate ms. If another invocation occurs
// during the time it is waiting, reschedule the function again
// with the new arguments.
const last = (fn, rate) => {
let timer = null;
const cancel = () => {
if (!isNull(timer)) {
clearTimeout(timer);
timer = null;
}
};
const throttle = (...args) => {
cancel();
timer = setTimeout(() => {
timer = null;
fn.apply(null, args);
}, rate);
};
return {
cancel,
throttle
};
};
var global = tinymce.util.Tools.resolve('tinymce.util.Tools');
const option = (name) => (editor) => editor.options.get(name);
const register$2 = (editor) => {
const registerOption = editor.options.register;
const charMapProcessor = (value) => isFunction(value) || isArray$1(value);
registerOption('charmap', {
processor: charMapProcessor,
});
registerOption('charmap_append', {
processor: charMapProcessor
});
};
const getCharMap$1 = option('charmap');
const getCharMapAppend = option('charmap_append');
const isArray = global.isArray;
const UserDefined = 'User Defined';
const getDefaultCharMap = () => {
return [
// TODO: Merge categories with TBIO
// {
// name: 'Unknown',
// characters : [
// [160, 'no-break space'],
// [173, 'soft hyphen'],
// [34, 'quotation mark']
// ]
// },
{ name: 'Currency',
characters: [
[36, 'dollar sign'],
[162, 'cent sign'],
[8364, 'euro sign'],
[163, 'pound sign'],
[165, 'yen sign'],
[164, 'currency sign'],
[8352, 'euro-currency sign'],
[8353, 'colon sign'],
[8354, 'cruzeiro sign'],
[8355, 'french franc sign'],
[8356, 'lira sign'],
[8357, 'mill sign'],
[8358, 'naira sign'],
[8359, 'peseta sign'],
[8360, 'rupee sign'],
[8361, 'won sign'],
[8362, 'new sheqel sign'],
[8363, 'dong sign'],
[8365, 'kip sign'],
[8366, 'tugrik sign'],
[8367, 'drachma sign'],
[8368, 'german penny symbol'],
[8369, 'peso sign'],
[8370, 'guarani sign'],
[8371, 'austral sign'],
[8372, 'hryvnia sign'],
[8373, 'cedi sign'],
[8374, 'livre tournois sign'],
[8375, 'spesmilo sign'],
[8376, 'tenge sign'],
[8377, 'indian rupee sign'],
[8378, 'turkish lira sign'],
[8379, 'nordic mark sign'],
[8380, 'manat sign'],
[8381, 'ruble sign'],
[20870, 'yen character'],
[20803, 'yuan character'],
[22291, 'yuan character, in hong kong and taiwan'],
[22278, 'yen/yuan character variant one']
]
},
{ name: 'Text',
characters: [
[169, 'copyright sign'],
[174, 'registered sign'],
[8482, 'trade mark sign'],
[8240, 'per mille sign'],
[181, 'micro sign'],
[183, 'middle dot'],
[8226, 'bullet'],
[8230, 'three dot leader'],
[8242, 'minutes / feet'],
[8243, 'seconds / inches'],
[167, 'section sign'],
[182, 'paragraph sign'],
[223, 'sharp s / ess-zed']
]
},
{ name: 'Quotations',
characters: [
[8249, 'single left-pointing angle quotation mark'],
[8250, 'single right-pointing angle quotation mark'],
[171, 'left pointing guillemet'],
[187, 'right pointing guillemet'],
[8216, 'left single quotation mark'],
[8217, 'right single quotation mark'],
[8220, 'left double quotation mark'],
[8221, 'right double quotation mark'],
[8218, 'single low-9 quotation mark'],
[8222, 'double low-9 quotation mark'],
[60, 'less-than sign'],
[62, 'greater-than sign'],
[8804, 'less-than or equal to'],
[8805, 'greater-than or equal to'],
[8211, 'en dash'],
[8212, 'em dash'],
[175, 'macron'],
[8254, 'overline'],
[164, 'currency sign'],
[166, 'broken bar'],
[168, 'diaeresis'],
[161, 'inverted exclamation mark'],
[191, 'turned question mark'],
[710, 'circumflex accent'],
[732, 'small tilde'],
[176, 'degree sign'],
[8722, 'minus sign'],
[177, 'plus-minus sign'],
[247, 'division sign'],
[8260, 'fraction slash'],
[215, 'multiplication sign'],
[185, 'superscript one'],
[178, 'superscript two'],
[179, 'superscript three'],
[188, 'fraction one quarter'],
[189, 'fraction one half'],
[190, 'fraction three quarters']
]
},
{
name: 'Mathematical',
characters: [
[402, 'function / florin'],
[8747, 'integral'],
[8721, 'n-ary sumation'],
[8734, 'infinity'],
[8730, 'square root'],
[8764, 'similar to'],
[8773, 'approximately equal to'],
[8776, 'almost equal to'],
[8800, 'not equal to'],
[8801, 'identical to'],
[8712, 'element of'],
[8713, 'not an element of'],
[8715, 'contains as member'],
[8719, 'n-ary product'],
[8743, 'logical and'],
[8744, 'logical or'],
[172, 'not sign'],
[8745, 'intersection'],
[8746, 'union'],
[8706, 'partial differential'],
[8704, 'for all'],
[8707, 'there exists'],
[8709, 'diameter'],
[8711, 'backward difference'],
[8727, 'asterisk operator'],
[8733, 'proportional to'],
[8736, 'angle']
]
},
// TODO: Merge categories with TBIO
// {
// name: 'Undefined',
// characters: [
// [180, 'acute accent'],
// [184, 'cedilla'],
// [170, 'feminine ordinal indicator'],
// [186, 'masculine ordinal indicator'],
// [8224, 'dagger'],
// [8225, 'double dagger']
// ]
// },
{
name: 'Extended Latin',
characters: [
[192, 'A - grave'],
[193, 'A - acute'],
[194, 'A - circumflex'],
[195, 'A - tilde'],
[196, 'A - diaeresis'],
[197, 'A - ring above'],
[256, 'A - macron'],
[198, 'ligature AE'],
[199, 'C - cedilla'],
[200, 'E - grave'],
[201, 'E - acute'],
[202, 'E - circumflex'],
[203, 'E - diaeresis'],
[274, 'E - macron'],
[204, 'I - grave'],
[205, 'I - acute'],
[206, 'I - circumflex'],
[207, 'I - diaeresis'],
[298, 'I - macron'],
[208, 'ETH'],
[209, 'N - tilde'],
[210, 'O - grave'],
[211, 'O - acute'],
[212, 'O - circumflex'],
[213, 'O - tilde'],
[214, 'O - diaeresis'],
[216, 'O - slash'],
[332, 'O - macron'],
[338, 'ligature OE'],
[352, 'S - caron'],
[217, 'U - grave'],
[218, 'U - acute'],
[219, 'U - circumflex'],
[220, 'U - diaeresis'],
[362, 'U - macron'],
[221, 'Y - acute'],
[376, 'Y - diaeresis'],
[562, 'Y - macron'],
[222, 'THORN'],
[224, 'a - grave'],
[225, 'a - acute'],
[226, 'a - circumflex'],
[227, 'a - tilde'],
[228, 'a - diaeresis'],
[229, 'a - ring above'],
[257, 'a - macron'],
[230, 'ligature ae'],
[231, 'c - cedilla'],
[232, 'e - grave'],
[233, 'e - acute'],
[234, 'e - circumflex'],
[235, 'e - diaeresis'],
[275, 'e - macron'],
[236, 'i - grave'],
[237, 'i - acute'],
[238, 'i - circumflex'],
[239, 'i - diaeresis'],
[299, 'i - macron'],
[240, 'eth'],
[241, 'n - tilde'],
[242, 'o - grave'],
[243, 'o - acute'],
[244, 'o - circumflex'],
[245, 'o - tilde'],
[246, 'o - diaeresis'],
[248, 'o slash'],
[333, 'o macron'],
[339, 'ligature oe'],
[353, 's - caron'],
[249, 'u - grave'],
[250, 'u - acute'],
[251, 'u - circumflex'],
[252, 'u - diaeresis'],
[363, 'u - macron'],
[253, 'y - acute'],
[254, 'thorn'],
[255, 'y - diaeresis'],
[563, 'y - macron'],
[913, 'Alpha'],
[914, 'Beta'],
[915, 'Gamma'],
[916, 'Delta'],
[917, 'Epsilon'],
[918, 'Zeta'],
[919, 'Eta'],
[920, 'Theta'],
[921, 'Iota'],
[922, 'Kappa'],
[923, 'Lambda'],
[924, 'Mu'],
[925, 'Nu'],
[926, 'Xi'],
[927, 'Omicron'],
[928, 'Pi'],
[929, 'Rho'],
[931, 'Sigma'],
[932, 'Tau'],
[933, 'Upsilon'],
[934, 'Phi'],
[935, 'Chi'],
[936, 'Psi'],
[937, 'Omega'],
[945, 'alpha'],
[946, 'beta'],
[947, 'gamma'],
[948, 'delta'],
[949, 'epsilon'],
[950, 'zeta'],
[951, 'eta'],
[952, 'theta'],
[953, 'iota'],
[954, 'kappa'],
[955, 'lambda'],
[956, 'mu'],
[957, 'nu'],
[958, 'xi'],
[959, 'omicron'],
[960, 'pi'],
[961, 'rho'],
[962, 'final sigma'],
[963, 'sigma'],
[964, 'tau'],
[965, 'upsilon'],
[966, 'phi'],
[967, 'chi'],
[968, 'psi'],
[969, 'omega']
]
},
{
name: 'Symbols',
characters: [
[8501, 'alef symbol'],
[982, 'pi symbol'],
[8476, 'real part symbol'],
[978, 'upsilon - hook symbol'],
[8472, 'Weierstrass p'],
[8465, 'imaginary part']
]
},
{
name: 'Arrows',
characters: [
[8592, 'leftwards arrow'],
[8593, 'upwards arrow'],
[8594, 'rightwards arrow'],
[8595, 'downwards arrow'],
[8596, 'left right arrow'],
[8629, 'carriage return'],
[8656, 'leftwards double arrow'],
[8657, 'upwards double arrow'],
[8658, 'rightwards double arrow'],
[8659, 'downwards double arrow'],
[8660, 'left right double arrow'],
[8756, 'therefore'],
[8834, 'subset of'],
[8835, 'superset of'],
[8836, 'not a subset of'],
[8838, 'subset of or equal to'],
[8839, 'superset of or equal to'],
[8853, 'circled plus'],
[8855, 'circled times'],
[8869, 'perpendicular'],
[8901, 'dot operator'],
[8968, 'left ceiling'],
[8969, 'right ceiling'],
[8970, 'left floor'],
[8971, 'right floor'],
[9001, 'left-pointing angle bracket'],
[9002, 'right-pointing angle bracket'],
[9674, 'lozenge'],
[9824, 'black spade suit'],
[9827, 'black club suit'],
[9829, 'black heart suit'],
[9830, 'black diamond suit'],
[8194, 'en space'],
[8195, 'em space'],
[8201, 'thin space'],
[8204, 'zero width non-joiner'],
[8205, 'zero width joiner'],
[8206, 'left-to-right mark'],
[8207, 'right-to-left mark']
]
}
];
};
const charmapFilter = (charmap) => {
return global.grep(charmap, (item) => {
return isArray(item) && item.length === 2;
});
};
const getCharsFromOption = (optionValue) => {
if (isArray(optionValue)) {
return charmapFilter(optionValue);
}
if (typeof optionValue === 'function') {
return optionValue();
}
return [];
};
const extendCharMap = (editor, charmap) => {
const userCharMap = getCharMap$1(editor);
if (userCharMap) {
charmap = [{ name: UserDefined, characters: getCharsFromOption(userCharMap) }];
}
const userCharMapAppend = getCharMapAppend(editor);
if (userCharMapAppend) {
const userDefinedGroup = global.grep(charmap, (cg) => cg.name === UserDefined);
if (userDefinedGroup.length) {
userDefinedGroup[0].characters = [...userDefinedGroup[0].characters, ...getCharsFromOption(userCharMapAppend)];
return charmap;
}
return charmap.concat({ name: UserDefined, characters: getCharsFromOption(userCharMapAppend) });
}
return charmap;
};
const getCharMap = (editor) => {
const groups = extendCharMap(editor, getDefaultCharMap());
return groups.length > 1 ? [
{
name: 'All',
characters: bind(groups, (g) => g.characters)
}
].concat(groups) : groups;
};
const get = (editor) => {
const getCharMap$1 = () => {
return getCharMap(editor);
};
const insertChar$1 = (chr) => {
insertChar(editor, chr);
};
return {
getCharMap: getCharMap$1,
insertChar: insertChar$1
};
};
const charMatches = (charCode, name, lowerCasePattern) => {
if (contains(fromCodePoint(charCode).toLowerCase(), lowerCasePattern)) {
return true;
}
else {
return contains(name.toLowerCase(), lowerCasePattern) || contains(name.toLowerCase().replace(/\s+/g, ''), lowerCasePattern);
}
};
const scan = (group, pattern) => {
const matches = [];
const lowerCasePattern = pattern.toLowerCase();
each(group.characters, (g) => {
if (charMatches(g[0], g[1], lowerCasePattern)) {
matches.push(g);
}
});
return map(matches, (m) => ({
text: m[1],
value: fromCodePoint(m[0]),
icon: fromCodePoint(m[0])
}));
};
const patternName = 'pattern';
const open = (editor, charMap) => {
const makeGroupItems = () => [
{
label: 'Search',
type: 'input',
name: patternName
},
{
type: 'collection',
name: 'results'
// TODO TINY-3229 implement collection columns properly
// columns: 'auto'
}
];
const makeTabs = () => map(charMap, (charGroup) => ({
title: charGroup.name,
name: charGroup.name,
items: makeGroupItems()
}));
const makePanel = () => ({ type: 'panel', items: makeGroupItems() });
const makeTabPanel = () => ({ type: 'tabpanel', tabs: makeTabs() });
const currentTab = charMap.length === 1 ? Cell(UserDefined) : Cell('All');
const scanAndSet = (dialogApi, pattern) => {
find(charMap, (group) => group.name === currentTab.get()).each((f) => {
const items = scan(f, pattern);
dialogApi.setData({
results: items
});
});
};
const SEARCH_DELAY = 40;
const updateFilter = last((dialogApi) => {
const pattern = dialogApi.getData().pattern;
scanAndSet(dialogApi, pattern);
}, SEARCH_DELAY);
const body = charMap.length === 1 ? makePanel() : makeTabPanel();
const initialData = {
pattern: '',
results: scan(charMap[0], '')
};
const bridgeSpec = {
title: 'Special Character',
size: 'normal',
body,
buttons: [
{
type: 'cancel',
name: 'close',
text: 'Close',
primary: true
}
],
initialData,
onAction: (api, details) => {
if (details.name === 'results') {
insertChar(editor, details.value);
api.close();
}
},
onTabChange: (dialogApi, details) => {
currentTab.set(details.newTabName);
updateFilter.throttle(dialogApi);
},
onChange: (dialogApi, changeData) => {
if (changeData.name === patternName) {
updateFilter.throttle(dialogApi);
}
}
};
const dialogApi = editor.windowManager.open(bridgeSpec);
dialogApi.focus(patternName);
};
const register$1 = (editor, charMap) => {
editor.addCommand('mceShowCharmap', () => {
open(editor, charMap);
});
};
const init = (editor, all) => {
editor.ui.registry.addAutocompleter('charmap', {
trigger: ':',
columns: 'auto',
minChars: 2,
fetch: (pattern, _maxResults) => new Promise((resolve, _reject) => {
resolve(scan(all, pattern));
}),
onAction: (autocompleteApi, rng, value) => {
editor.selection.setRng(rng);
editor.insertContent(value);
autocompleteApi.hide();
}
});
};
const onSetupEditable = (editor) => (api) => {
const nodeChanged = () => {
api.setEnabled(editor.selection.isEditable());
};
editor.on('NodeChange', nodeChanged);
nodeChanged();
return () => {
editor.off('NodeChange', nodeChanged);
};
};
const register = (editor) => {
const onAction = () => editor.execCommand('mceShowCharmap');
editor.ui.registry.addButton('charmap', {
icon: 'insert-character',
tooltip: 'Special character',
onAction,
onSetup: onSetupEditable(editor)
});
editor.ui.registry.addMenuItem('charmap', {
icon: 'insert-character',
text: 'Special character...',
onAction,
onSetup: onSetupEditable(editor)
});
};
var Plugin = () => {
global$1.add('charmap', (editor) => {
register$2(editor);
const charMap = getCharMap(editor);
register$1(editor, charMap);
register(editor);
init(editor, charMap[0]);
return get(editor);
});
};
Plugin();
/** *****
* DO NOT EXPORT ANYTHING
*
* IF YOU DO ROLLUP WILL LEAVE A GLOBAL ON THE PAGE
*******/
})();

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
// Exports the "code" plugin for usage with module loaders
// Usage:
// CommonJS:
// require('tinymce/plugins/code')
// ES2015:
// import 'tinymce/plugins/code'
require('./plugin.js');

View File

@@ -0,0 +1,98 @@
/**
* TinyMCE version 8.3.2 (2026-01-14)
*/
(function () {
'use strict';
var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
const setContent = (editor, html) => {
// We get a lovely "Wrong document" error in IE 11 if we
// don't move the focus to the editor before creating an undo
// transaction since it tries to make a bookmark for the current selection
editor.focus();
editor.undoManager.transact(() => {
editor.setContent(html);
});
editor.selection.setCursorLocation();
editor.nodeChanged();
};
const getContent = (editor) => {
return editor.getContent({ source_view: true });
};
const open = (editor) => {
const editorContent = getContent(editor);
editor.windowManager.open({
title: 'Source Code',
size: 'large',
body: {
type: 'panel',
items: [
{
type: 'textarea',
name: 'code',
spellcheck: false,
}
]
},
buttons: [
{
type: 'cancel',
name: 'cancel',
text: 'Cancel'
},
{
type: 'submit',
name: 'save',
text: 'Save',
primary: true
}
],
initialData: {
code: editorContent
},
onSubmit: (api) => {
setContent(editor, api.getData().code);
api.close();
}
});
};
const register$1 = (editor) => {
editor.addCommand('mceCodeEditor', () => {
open(editor);
});
};
const register = (editor) => {
const onAction = () => editor.execCommand('mceCodeEditor');
editor.ui.registry.addButton('code', {
icon: 'sourcecode',
tooltip: 'Source code',
onAction
});
editor.ui.registry.addMenuItem('code', {
icon: 'sourcecode',
text: 'Source code',
onAction
});
};
var Plugin = () => {
global.add('code', (editor) => {
register$1(editor);
register(editor);
return {};
});
};
Plugin();
/** *****
* DO NOT EXPORT ANYTHING
*
* IF YOU DO ROLLUP WILL LEAVE A GLOBAL ON THE PAGE
*******/
})();

View File

@@ -0,0 +1 @@
!function(){"use strict";tinymce.util.Tools.resolve("tinymce.PluginManager").add("code",(e=>((e=>{e.addCommand("mceCodeEditor",(()=>{(e=>{const o=(e=>e.getContent({source_view:!0}))(e);e.windowManager.open({title:"Source Code",size:"large",body:{type:"panel",items:[{type:"textarea",name:"code",spellcheck:!1}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{code:o},onSubmit:o=>{((e,o)=>{e.focus(),e.undoManager.transact((()=>{e.setContent(o)})),e.selection.setCursorLocation(),e.nodeChanged()})(e,o.getData().code),o.close()}})})(e)}))})(e),(e=>{const o=()=>e.execCommand("mceCodeEditor");e.ui.registry.addButton("code",{icon:"sourcecode",tooltip:"Source code",onAction:o}),e.ui.registry.addMenuItem("code",{icon:"sourcecode",text:"Source code",onAction:o})})(e),{})))}();

View File

@@ -0,0 +1,7 @@
// Exports the "codesample" plugin for usage with module loaders
// Usage:
// CommonJS:
// require('tinymce/plugins/codesample')
// ES2015:
// import 'tinymce/plugins/codesample'
require('./plugin.js');

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
// Exports the "directionality" plugin for usage with module loaders
// Usage:
// CommonJS:
// require('tinymce/plugins/directionality')
// ES2015:
// import 'tinymce/plugins/directionality'
require('./plugin.js');

View File

@@ -0,0 +1,634 @@
/**
* TinyMCE version 8.3.2 (2026-01-14)
*/
(function () {
'use strict';
var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
/* eslint-disable @typescript-eslint/no-wrapper-object-types */
const hasProto = (v, constructor, predicate) => {
if (predicate(v, constructor.prototype)) {
return true;
}
else {
// String-based fallback time
return v.constructor?.name === constructor.name;
}
};
const typeOf = (x) => {
const t = typeof x;
if (x === null) {
return 'null';
}
else if (t === 'object' && Array.isArray(x)) {
return 'array';
}
else if (t === 'object' && hasProto(x, String, (o, proto) => proto.isPrototypeOf(o))) {
return 'string';
}
else {
return t;
}
};
const isType$1 = (type) => (value) => typeOf(value) === type;
const isSimpleType = (type) => (value) => typeof value === type;
const isString = isType$1('string');
const isBoolean = isSimpleType('boolean');
const isNullable = (a) => a === null || a === undefined;
const isNonNullable = (a) => !isNullable(a);
const isFunction = isSimpleType('function');
const isNumber = isSimpleType('number');
/** Compose two unary functions. Similar to compose, but avoids using Function.prototype.apply. */
const compose1 = (fbc, fab) => (a) => fbc(fab(a));
const constant = (value) => {
return () => {
return value;
};
};
const never = constant(false);
/**
* The `Optional` type represents a value (of any type) that potentially does
* not exist. Any `Optional<T>` can either be a `Some<T>` (in which case the
* value does exist) or a `None` (in which case the value does not exist). This
* module defines a whole lot of FP-inspired utility functions for dealing with
* `Optional` objects.
*
* Comparison with null or undefined:
* - We don't get fancy null coalescing operators with `Optional`
* - We do get fancy helper functions with `Optional`
* - `Optional` support nesting, and allow for the type to still be nullable (or
* another `Optional`)
* - There is no option to turn off strict-optional-checks like there is for
* strict-null-checks
*/
class Optional {
tag;
value;
// Sneaky optimisation: every instance of Optional.none is identical, so just
// reuse the same object
static singletonNone = new Optional(false);
// The internal representation has a `tag` and a `value`, but both are
// private: able to be console.logged, but not able to be accessed by code
constructor(tag, value) {
this.tag = tag;
this.value = value;
}
// --- Identities ---
/**
* Creates a new `Optional<T>` that **does** contain a value.
*/
static some(value) {
return new Optional(true, value);
}
/**
* Create a new `Optional<T>` that **does not** contain a value. `T` can be
* any type because we don't actually have a `T`.
*/
static none() {
return Optional.singletonNone;
}
/**
* Perform a transform on an `Optional` type. Regardless of whether this
* `Optional` contains a value or not, `fold` will return a value of type `U`.
* If this `Optional` does not contain a value, the `U` will be created by
* calling `onNone`. If this `Optional` does contain a value, the `U` will be
* created by calling `onSome`.
*
* For the FP enthusiasts in the room, this function:
* 1. Could be used to implement all of the functions below
* 2. Forms a catamorphism
*/
fold(onNone, onSome) {
if (this.tag) {
return onSome(this.value);
}
else {
return onNone();
}
}
/**
* Determine if this `Optional` object contains a value.
*/
isSome() {
return this.tag;
}
/**
* Determine if this `Optional` object **does not** contain a value.
*/
isNone() {
return !this.tag;
}
// --- Functor (name stolen from Haskell / maths) ---
/**
* Perform a transform on an `Optional` object, **if** there is a value. If
* you provide a function to turn a T into a U, this is the function you use
* to turn an `Optional<T>` into an `Optional<U>`. If this **does** contain
* a value then the output will also contain a value (that value being the
* output of `mapper(this.value)`), and if this **does not** contain a value
* then neither will the output.
*/
map(mapper) {
if (this.tag) {
return Optional.some(mapper(this.value));
}
else {
return Optional.none();
}
}
// --- Monad (name stolen from Haskell / maths) ---
/**
* Perform a transform on an `Optional` object, **if** there is a value.
* Unlike `map`, here the transform itself also returns an `Optional`.
*/
bind(binder) {
if (this.tag) {
return binder(this.value);
}
else {
return Optional.none();
}
}
// --- Traversable (name stolen from Haskell / maths) ---
/**
* For a given predicate, this function finds out if there **exists** a value
* inside this `Optional` object that meets the predicate. In practice, this
* means that for `Optional`s that do not contain a value it returns false (as
* no predicate-meeting value exists).
*/
exists(predicate) {
return this.tag && predicate(this.value);
}
/**
* For a given predicate, this function finds out if **all** the values inside
* this `Optional` object meet the predicate. In practice, this means that
* for `Optional`s that do not contain a value it returns true (as all 0
* objects do meet the predicate).
*/
forall(predicate) {
return !this.tag || predicate(this.value);
}
filter(predicate) {
if (!this.tag || predicate(this.value)) {
return this;
}
else {
return Optional.none();
}
}
// --- Getters ---
/**
* Get the value out of the inside of the `Optional` object, using a default
* `replacement` value if the provided `Optional` object does not contain a
* value.
*/
getOr(replacement) {
return this.tag ? this.value : replacement;
}
/**
* Get the value out of the inside of the `Optional` object, using a default
* `replacement` value if the provided `Optional` object does not contain a
* value. Unlike `getOr`, in this method the `replacement` object is also
* `Optional` - meaning that this method will always return an `Optional`.
*/
or(replacement) {
return this.tag ? this : replacement;
}
/**
* Get the value out of the inside of the `Optional` object, using a default
* `replacement` value if the provided `Optional` object does not contain a
* value. Unlike `getOr`, in this method the `replacement` value is
* "thunked" - that is to say that you don't pass a value to `getOrThunk`, you
* pass a function which (if called) will **return** the `value` you want to
* use.
*/
getOrThunk(thunk) {
return this.tag ? this.value : thunk();
}
/**
* Get the value out of the inside of the `Optional` object, using a default
* `replacement` value if the provided Optional object does not contain a
* value.
*
* Unlike `or`, in this method the `replacement` value is "thunked" - that is
* to say that you don't pass a value to `orThunk`, you pass a function which
* (if called) will **return** the `value` you want to use.
*
* Unlike `getOrThunk`, in this method the `replacement` value is also
* `Optional`, meaning that this method will always return an `Optional`.
*/
orThunk(thunk) {
return this.tag ? this : thunk();
}
/**
* Get the value out of the inside of the `Optional` object, throwing an
* exception if the provided `Optional` object does not contain a value.
*
* WARNING:
* You should only be using this function if you know that the `Optional`
* object **is not** empty (otherwise you're throwing exceptions in production
* code, which is bad).
*
* In tests this is more acceptable.
*
* Prefer other methods to this, such as `.each`.
*/
getOrDie(message) {
if (!this.tag) {
throw new Error(message ?? 'Called getOrDie on None');
}
else {
return this.value;
}
}
// --- Interop with null and undefined ---
/**
* Creates an `Optional` value from a nullable (or undefined-able) input.
* Null, or undefined, is converted to `None`, and anything else is converted
* to `Some`.
*/
static from(value) {
return isNonNullable(value) ? Optional.some(value) : Optional.none();
}
/**
* Converts an `Optional` to a nullable type, by getting the value if it
* exists, or returning `null` if it does not.
*/
getOrNull() {
return this.tag ? this.value : null;
}
/**
* Converts an `Optional` to an undefined-able type, by getting the value if
* it exists, or returning `undefined` if it does not.
*/
getOrUndefined() {
return this.value;
}
// --- Utilities ---
/**
* If the `Optional` contains a value, perform an action on that value.
* Unlike the rest of the methods on this type, `.each` has side-effects. If
* you want to transform an `Optional<T>` **into** something, then this is not
* the method for you. If you want to use an `Optional<T>` to **do**
* something, then this is the method for you - provided you're okay with not
* doing anything in the case where the `Optional` doesn't have a value inside
* it. If you're not sure whether your use-case fits into transforming
* **into** something or **doing** something, check whether it has a return
* value. If it does, you should be performing a transform.
*/
each(worker) {
if (this.tag) {
worker(this.value);
}
}
/**
* Turn the `Optional` object into an array that contains all of the values
* stored inside the `Optional`. In practice, this means the output will have
* either 0 or 1 elements.
*/
toArray() {
return this.tag ? [this.value] : [];
}
/**
* Turn the `Optional` object into a string for debugging or printing. Not
* recommended for production code, but good for debugging. Also note that
* these days an `Optional` object can be logged to the console directly, and
* its inner value (if it exists) will be visible.
*/
toString() {
return this.tag ? `some(${this.value})` : 'none()';
}
}
const nativeSlice = Array.prototype.slice;
const map = (xs, f) => {
// pre-allocating array size when it's guaranteed to be known
// http://jsperf.com/push-allocated-vs-dynamic/22
const len = xs.length;
const r = new Array(len);
for (let i = 0; i < len; i++) {
const x = xs[i];
r[i] = f(x, i);
}
return r;
};
// Unwound implementing other functions in terms of each.
// The code size is roughly the same, and it should allow for better optimisation.
// const each = function<T, U>(xs: T[], f: (x: T, i?: number, xs?: T[]) => void): void {
const each = (xs, f) => {
for (let i = 0, len = xs.length; i < len; i++) {
const x = xs[i];
f(x, i);
}
};
const filter = (xs, pred) => {
const r = [];
for (let i = 0, len = xs.length; i < len; i++) {
const x = xs[i];
if (pred(x, i)) {
r.push(x);
}
}
return r;
};
isFunction(Array.from) ? Array.from : (x) => nativeSlice.call(x);
const fromHtml = (html, scope) => {
const doc = scope || document;
const div = doc.createElement('div');
div.innerHTML = html;
if (!div.hasChildNodes() || div.childNodes.length > 1) {
const message = 'HTML does not have a single root node';
// eslint-disable-next-line no-console
console.error(message, html);
throw new Error(message);
}
return fromDom(div.childNodes[0]);
};
const fromTag = (tag, scope) => {
const doc = scope || document;
const node = doc.createElement(tag);
return fromDom(node);
};
const fromText = (text, scope) => {
const doc = scope || document;
const node = doc.createTextNode(text);
return fromDom(node);
};
const fromDom = (node) => {
// TODO: Consider removing this check, but left atm for safety
if (node === null || node === undefined) {
throw new Error('Node cannot be null or undefined');
}
return {
dom: node
};
};
const fromPoint = (docElm, x, y) => Optional.from(docElm.dom.elementFromPoint(x, y)).map(fromDom);
// tslint:disable-next-line:variable-name
const SugarElement = {
fromHtml,
fromTag,
fromText,
fromDom,
fromPoint
};
const DOCUMENT_FRAGMENT = 11;
const ELEMENT = 1;
const TEXT = 3;
const is = (element, selector) => {
const dom = element.dom;
if (dom.nodeType !== ELEMENT) {
return false;
}
else {
const elem = dom;
if (elem.matches !== undefined) {
return elem.matches(selector);
}
else if (elem.msMatchesSelector !== undefined) {
return elem.msMatchesSelector(selector);
}
else if (elem.webkitMatchesSelector !== undefined) {
return elem.webkitMatchesSelector(selector);
}
else if (elem.mozMatchesSelector !== undefined) {
// cast to any as mozMatchesSelector doesn't exist in TS DOM lib
return elem.mozMatchesSelector(selector);
}
else {
throw new Error('Browser lacks native selectors');
} // unfortunately we can't throw this on startup :(
}
};
const name = (element) => {
const r = element.dom.nodeName;
return r.toLowerCase();
};
const type = (element) => element.dom.nodeType;
const isType = (t) => (element) => type(element) === t;
const isElement = isType(ELEMENT);
const isText = isType(TEXT);
const isDocumentFragment = isType(DOCUMENT_FRAGMENT);
const isTag = (tag) => (e) => isElement(e) && name(e) === tag;
const parent = (element) => Optional.from(element.dom.parentNode).map(SugarElement.fromDom);
const children$2 = (element) => map(element.dom.childNodes, SugarElement.fromDom);
/**
* Is the element a ShadowRoot?
*
* Note: this is insufficient to test if any element is a shadow root, but it is sufficient to differentiate between
* a Document and a ShadowRoot.
*/
const isShadowRoot = (dos) => isDocumentFragment(dos) && isNonNullable(dos.dom.host);
const getRootNode = (e) => SugarElement.fromDom(e.dom.getRootNode());
/** If this element is in a ShadowRoot, return it. */
const getShadowRoot = (e) => {
const r = getRootNode(e);
return isShadowRoot(r) ? Optional.some(r) : Optional.none();
};
/** Return the host of a ShadowRoot.
*
* This function will throw if Shadow DOM is unsupported in the browser, or if the host is null.
* If you actually have a ShadowRoot, this shouldn't happen.
*/
const getShadowHost = (e) => SugarElement.fromDom(e.dom.host);
const rawSet = (dom, key, value) => {
/*
* JQuery coerced everything to a string, and silently did nothing on text node/null/undefined.
*
* We fail on those invalid cases, only allowing numbers and booleans.
*/
if (isString(value) || isBoolean(value) || isNumber(value)) {
dom.setAttribute(key, value + '');
}
else {
// eslint-disable-next-line no-console
console.error('Invalid call to Attribute.set. Key ', key, ':: Value ', value, ':: Element ', dom);
throw new Error('Attribute value was not simple');
}
};
const set = (element, key, value) => {
rawSet(element.dom, key, value);
};
const remove = (element, key) => {
element.dom.removeAttribute(key);
};
// some elements, such as mathml, don't have style attributes
// others, such as angular elements, have style attributes that aren't a CSSStyleDeclaration
const isSupported = (dom) => dom.style !== undefined && isFunction(dom.style.getPropertyValue);
// Node.contains() is very, very, very good performance
// http://jsperf.com/closest-vs-contains/5
const inBody = (element) => {
// Technically this is only required on IE, where contains() returns false for text nodes.
// But it's cheap enough to run everywhere and Sugar doesn't have platform detection (yet).
const dom = isText(element) ? element.dom.parentNode : element.dom;
// use ownerDocument.body to ensure this works inside iframes.
// Normally contains is bad because an element "contains" itself, but here we want that.
if (dom === undefined || dom === null || dom.ownerDocument === null) {
return false;
}
const doc = dom.ownerDocument;
return getShadowRoot(SugarElement.fromDom(dom)).fold(() => doc.body.contains(dom), compose1(inBody, getShadowHost));
};
/*
* NOTE: For certain properties, this returns the "used value" which is subtly different to the "computed value" (despite calling getComputedStyle).
* Blame CSS 2.0.
*
* https://developer.mozilla.org/en-US/docs/Web/CSS/used_value
*/
const get = (element, property) => {
const dom = element.dom;
/*
* IE9 and above per
* https://developer.mozilla.org/en/docs/Web/API/window.getComputedStyle
*
* Not in numerosity, because it doesn't memoize and looking this up dynamically in performance critical code would be horrendous.
*
* JQuery has some magic here for IE popups, but we don't really need that.
* It also uses element.ownerDocument.defaultView to handle iframes but that hasn't been required since FF 3.6.
*/
const styles = window.getComputedStyle(dom);
const r = styles.getPropertyValue(property);
// jquery-ism: If r is an empty string, check that the element is not in a document. If it isn't, return the raw value.
// Turns out we do this a lot.
return (r === '' && !inBody(element)) ? getUnsafeProperty(dom, property) : r;
};
// removed: support for dom().style[property] where prop is camel case instead of normal property name
// empty string is what the browsers (IE11 and Chrome) return when the propertyValue doesn't exists.
const getUnsafeProperty = (dom, property) => isSupported(dom) ? dom.style.getPropertyValue(property) : '';
const getDirection = (element) => get(element, 'direction') === 'rtl' ? 'rtl' : 'ltr';
const ancestor$1 = (scope, predicate, isRoot) => {
let element = scope.dom;
const stop = isFunction(isRoot) ? isRoot : never;
while (element.parentNode) {
element = element.parentNode;
const el = SugarElement.fromDom(element);
if (predicate(el)) {
return Optional.some(el);
}
else if (stop(el)) {
break;
}
}
return Optional.none();
};
const ancestor = (scope, selector, isRoot) => ancestor$1(scope, (e) => is(e, selector), isRoot);
const children$1 = (scope, predicate) => filter(children$2(scope), predicate);
const children = (scope, selector) =>
// It may surprise you to learn this is exactly what JQuery does
// TODO: Avoid all the wrapping and unwrapping
children$1(scope, (e) => is(e, selector));
const getParentElement = (element) => parent(element).filter(isElement);
// if the block is a list item, we need to get the parent of the list itself
const getNormalizedBlock = (element, isListItem) => {
const normalizedElement = isListItem ? ancestor(element, 'ol,ul') : Optional.some(element);
return normalizedElement.getOr(element);
};
const isListItem = isTag('li');
const setDirOnElements = (dom, blocks, dir) => {
each(blocks, (block) => {
const blockElement = SugarElement.fromDom(block);
const isBlockElementListItem = isListItem(blockElement);
const normalizedBlock = getNormalizedBlock(blockElement, isBlockElementListItem);
const normalizedBlockParent = getParentElement(normalizedBlock);
normalizedBlockParent.each((parent) => {
// TINY-9314: Remove any inline direction style to ensure that it is only set when necessary and that
// the dir attribute is favored
dom.setStyle(normalizedBlock.dom, 'direction', null);
const parentDirection = getDirection(parent);
if (parentDirection === dir) {
remove(normalizedBlock, 'dir');
}
else {
set(normalizedBlock, 'dir', dir);
}
// TINY-9314: Set an inline direction style if computed css direction is still not as desired. This can
// happen when the direction style is derived from a stylesheet.
if (getDirection(normalizedBlock) !== dir) {
dom.setStyle(normalizedBlock.dom, 'direction', dir);
}
// Remove dir attr and direction style from list children
if (isBlockElementListItem) {
const listItems = children(normalizedBlock, 'li[dir],li[style]');
each(listItems, (listItem) => {
remove(listItem, 'dir');
dom.setStyle(listItem.dom, 'direction', null);
});
}
});
});
};
const setDir = (editor, dir) => {
if (editor.selection.isEditable()) {
setDirOnElements(editor.dom, editor.selection.getSelectedBlocks(), dir);
editor.nodeChanged();
}
};
const register$1 = (editor) => {
editor.addCommand('mceDirectionLTR', () => {
setDir(editor, 'ltr');
});
editor.addCommand('mceDirectionRTL', () => {
setDir(editor, 'rtl');
});
};
const getNodeChangeHandler = (editor, dir) => (api) => {
const nodeChangeHandler = (e) => {
const element = SugarElement.fromDom(e.element);
api.setActive(getDirection(element) === dir);
api.setEnabled(editor.selection.isEditable());
};
editor.on('NodeChange', nodeChangeHandler);
api.setEnabled(editor.selection.isEditable());
return () => editor.off('NodeChange', nodeChangeHandler);
};
const register = (editor) => {
editor.ui.registry.addToggleButton('ltr', {
tooltip: 'Left to right',
icon: 'ltr',
onAction: () => editor.execCommand('mceDirectionLTR'),
onSetup: getNodeChangeHandler(editor, 'ltr')
});
editor.ui.registry.addToggleButton('rtl', {
tooltip: 'Right to left',
icon: 'rtl',
onAction: () => editor.execCommand('mceDirectionRTL'),
onSetup: getNodeChangeHandler(editor, 'rtl')
});
};
var Plugin = () => {
global.add('directionality', (editor) => {
register$1(editor);
register(editor);
});
};
Plugin();
/** *****
* DO NOT EXPORT ANYTHING
*
* IF YOU DO ROLLUP WILL LEAVE A GLOBAL ON THE PAGE
*******/
})();

View File

@@ -0,0 +1 @@
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>e=>typeof e===t,r=t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(r=o=t,(n=String).prototype.isPrototypeOf(r)||o.constructor?.name===n.name)?"string":e;var r,o,n})(t),o=e("boolean"),n=t=>!(t=>null==t)(t),i=e("function"),s=e("number"),l=()=>false;class a{tag;value;static singletonNone=new a(!1);constructor(t,e){this.tag=t,this.value=e}static some(t){return new a(!0,t)}static none(){return a.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?a.some(t(this.value)):a.none()}bind(t){return this.tag?t(this.value):a.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:a.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(t??"Called getOrDie on None")}static from(t){return n(t)?a.some(t):a.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}Array.prototype.slice;const u=(t,e)=>{for(let r=0,o=t.length;r<o;r++)e(t[r],r)};i(Array.from)&&Array.from;const c=t=>{if(null==t)throw new Error("Node cannot be null or undefined");return{dom:t}},d=c,h=(t,e)=>{const r=t.dom;if(1!==r.nodeType)return!1;{const t=r;if(void 0!==t.matches)return t.matches(e);if(void 0!==t.msMatchesSelector)return t.msMatchesSelector(e);if(void 0!==t.webkitMatchesSelector)return t.webkitMatchesSelector(e);if(void 0!==t.mozMatchesSelector)return t.mozMatchesSelector(e);throw new Error("Browser lacks native selectors")}},m=t=>e=>(t=>t.dom.nodeType)(e)===t,g=m(1),f=m(3),v=m(11),y=t=>d(t.dom.host),p=(t,e)=>{t.dom.removeAttribute(e)},w=t=>{const e=f(t)?t.dom.parentNode:t.dom;if(null==e||null===e.ownerDocument)return!1;const r=e.ownerDocument;return(t=>{const e=(t=>d(t.dom.getRootNode()))(t);return v(r=e)&&n(r.dom.host)?a.some(e):a.none();var r})(d(e)).fold((()=>r.body.contains(e)),(o=w,i=y,t=>o(i(t))));var o,i},b=t=>"rtl"===((t,e)=>{const r=t.dom,o=window.getComputedStyle(r).getPropertyValue(e);return""!==o||w(t)?o:((t,e)=>(t=>void 0!==t.style&&i(t.style.getPropertyValue))(t)?t.style.getPropertyValue(e):"")(r,e)})(t,"direction")?"rtl":"ltr",S=(t,e)=>(t=>((t,e)=>{const r=[];for(let o=0,n=t.length;o<n;o++){const n=t[o];e(n,o)&&r.push(n)}return r})(((t,e)=>{const r=t.length,o=new Array(r);for(let n=0;n<r;n++){const r=t[n];o[n]=e(r,n)}return o})(t.dom.childNodes,d),(t=>h(t,e))))(t),N=t=>g(t)&&"li"===t.dom.nodeName.toLowerCase();const A=(t,e,n)=>{u(e,(e=>{const c=d(e),m=N(c),f=((t,e)=>{return(e?(r=t,o="ol,ul",((t,e,r)=>{let n=t.dom;const s=i(r)?r:l;for(;n.parentNode;){n=n.parentNode;const t=d(n);if(h(t,o))return a.some(t);if(s(t))break}return a.none()})(r,0,n)):a.some(t)).getOr(t);var r,o,n})(c,m);var v;(v=f,(t=>a.from(t.dom.parentNode).map(d))(v).filter(g)).each((e=>{if(t.setStyle(f.dom,"direction",null),b(e)===n?p(f,"dir"):((t,e,n)=>{((t,e,n)=>{if(!(r(n)||o(n)||s(n)))throw console.error("Invalid call to Attribute.set. Key ",e,":: Value ",n,":: Element ",t),new Error("Attribute value was not simple");t.setAttribute(e,n+"")})(t.dom,e,n)})(f,"dir",n),b(f)!==n&&t.setStyle(f.dom,"direction",n),m){const e=S(f,"li[dir],li[style]");u(e,(e=>{p(e,"dir"),t.setStyle(e.dom,"direction",null)}))}}))}))},T=(t,e)=>{t.selection.isEditable()&&(A(t.dom,t.selection.getSelectedBlocks(),e),t.nodeChanged())},C=(t,e)=>r=>{const o=o=>{const n=d(o.element);r.setActive(b(n)===e),r.setEnabled(t.selection.isEditable())};return t.on("NodeChange",o),r.setEnabled(t.selection.isEditable()),()=>t.off("NodeChange",o)};t.add("directionality",(t=>{(t=>{t.addCommand("mceDirectionLTR",(()=>{T(t,"ltr")})),t.addCommand("mceDirectionRTL",(()=>{T(t,"rtl")}))})(t),(t=>{t.ui.registry.addToggleButton("ltr",{tooltip:"Left to right",icon:"ltr",onAction:()=>t.execCommand("mceDirectionLTR"),onSetup:C(t,"ltr")}),t.ui.registry.addToggleButton("rtl",{tooltip:"Right to left",icon:"rtl",onAction:()=>t.execCommand("mceDirectionRTL"),onSetup:C(t,"rtl")})})(t)}))}();

View File

@@ -0,0 +1,7 @@
// Exports the "emoticons" plugin for usage with module loaders
// Usage:
// CommonJS:
// require('tinymce/plugins/emoticons')
// ES2015:
// import 'tinymce/plugins/emoticons'
require('./plugin.js');

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,809 @@
/**
* TinyMCE version 8.3.2 (2026-01-14)
*/
(function () {
'use strict';
var global$1 = tinymce.util.Tools.resolve('tinymce.PluginManager');
/* eslint-disable @typescript-eslint/no-wrapper-object-types */
const isSimpleType = (type) => (value) => typeof value === type;
const eq = (t) => (a) => t === a;
const isNull = eq(null);
const isUndefined = eq(undefined);
const isNullable = (a) => a === null || a === undefined;
const isNonNullable = (a) => !isNullable(a);
const isFunction = isSimpleType('function');
const noop = () => { };
const constant = (value) => {
return () => {
return value;
};
};
const never = constant(false);
/**
* The `Optional` type represents a value (of any type) that potentially does
* not exist. Any `Optional<T>` can either be a `Some<T>` (in which case the
* value does exist) or a `None` (in which case the value does not exist). This
* module defines a whole lot of FP-inspired utility functions for dealing with
* `Optional` objects.
*
* Comparison with null or undefined:
* - We don't get fancy null coalescing operators with `Optional`
* - We do get fancy helper functions with `Optional`
* - `Optional` support nesting, and allow for the type to still be nullable (or
* another `Optional`)
* - There is no option to turn off strict-optional-checks like there is for
* strict-null-checks
*/
class Optional {
tag;
value;
// Sneaky optimisation: every instance of Optional.none is identical, so just
// reuse the same object
static singletonNone = new Optional(false);
// The internal representation has a `tag` and a `value`, but both are
// private: able to be console.logged, but not able to be accessed by code
constructor(tag, value) {
this.tag = tag;
this.value = value;
}
// --- Identities ---
/**
* Creates a new `Optional<T>` that **does** contain a value.
*/
static some(value) {
return new Optional(true, value);
}
/**
* Create a new `Optional<T>` that **does not** contain a value. `T` can be
* any type because we don't actually have a `T`.
*/
static none() {
return Optional.singletonNone;
}
/**
* Perform a transform on an `Optional` type. Regardless of whether this
* `Optional` contains a value or not, `fold` will return a value of type `U`.
* If this `Optional` does not contain a value, the `U` will be created by
* calling `onNone`. If this `Optional` does contain a value, the `U` will be
* created by calling `onSome`.
*
* For the FP enthusiasts in the room, this function:
* 1. Could be used to implement all of the functions below
* 2. Forms a catamorphism
*/
fold(onNone, onSome) {
if (this.tag) {
return onSome(this.value);
}
else {
return onNone();
}
}
/**
* Determine if this `Optional` object contains a value.
*/
isSome() {
return this.tag;
}
/**
* Determine if this `Optional` object **does not** contain a value.
*/
isNone() {
return !this.tag;
}
// --- Functor (name stolen from Haskell / maths) ---
/**
* Perform a transform on an `Optional` object, **if** there is a value. If
* you provide a function to turn a T into a U, this is the function you use
* to turn an `Optional<T>` into an `Optional<U>`. If this **does** contain
* a value then the output will also contain a value (that value being the
* output of `mapper(this.value)`), and if this **does not** contain a value
* then neither will the output.
*/
map(mapper) {
if (this.tag) {
return Optional.some(mapper(this.value));
}
else {
return Optional.none();
}
}
// --- Monad (name stolen from Haskell / maths) ---
/**
* Perform a transform on an `Optional` object, **if** there is a value.
* Unlike `map`, here the transform itself also returns an `Optional`.
*/
bind(binder) {
if (this.tag) {
return binder(this.value);
}
else {
return Optional.none();
}
}
// --- Traversable (name stolen from Haskell / maths) ---
/**
* For a given predicate, this function finds out if there **exists** a value
* inside this `Optional` object that meets the predicate. In practice, this
* means that for `Optional`s that do not contain a value it returns false (as
* no predicate-meeting value exists).
*/
exists(predicate) {
return this.tag && predicate(this.value);
}
/**
* For a given predicate, this function finds out if **all** the values inside
* this `Optional` object meet the predicate. In practice, this means that
* for `Optional`s that do not contain a value it returns true (as all 0
* objects do meet the predicate).
*/
forall(predicate) {
return !this.tag || predicate(this.value);
}
filter(predicate) {
if (!this.tag || predicate(this.value)) {
return this;
}
else {
return Optional.none();
}
}
// --- Getters ---
/**
* Get the value out of the inside of the `Optional` object, using a default
* `replacement` value if the provided `Optional` object does not contain a
* value.
*/
getOr(replacement) {
return this.tag ? this.value : replacement;
}
/**
* Get the value out of the inside of the `Optional` object, using a default
* `replacement` value if the provided `Optional` object does not contain a
* value. Unlike `getOr`, in this method the `replacement` object is also
* `Optional` - meaning that this method will always return an `Optional`.
*/
or(replacement) {
return this.tag ? this : replacement;
}
/**
* Get the value out of the inside of the `Optional` object, using a default
* `replacement` value if the provided `Optional` object does not contain a
* value. Unlike `getOr`, in this method the `replacement` value is
* "thunked" - that is to say that you don't pass a value to `getOrThunk`, you
* pass a function which (if called) will **return** the `value` you want to
* use.
*/
getOrThunk(thunk) {
return this.tag ? this.value : thunk();
}
/**
* Get the value out of the inside of the `Optional` object, using a default
* `replacement` value if the provided Optional object does not contain a
* value.
*
* Unlike `or`, in this method the `replacement` value is "thunked" - that is
* to say that you don't pass a value to `orThunk`, you pass a function which
* (if called) will **return** the `value` you want to use.
*
* Unlike `getOrThunk`, in this method the `replacement` value is also
* `Optional`, meaning that this method will always return an `Optional`.
*/
orThunk(thunk) {
return this.tag ? this : thunk();
}
/**
* Get the value out of the inside of the `Optional` object, throwing an
* exception if the provided `Optional` object does not contain a value.
*
* WARNING:
* You should only be using this function if you know that the `Optional`
* object **is not** empty (otherwise you're throwing exceptions in production
* code, which is bad).
*
* In tests this is more acceptable.
*
* Prefer other methods to this, such as `.each`.
*/
getOrDie(message) {
if (!this.tag) {
throw new Error(message ?? 'Called getOrDie on None');
}
else {
return this.value;
}
}
// --- Interop with null and undefined ---
/**
* Creates an `Optional` value from a nullable (or undefined-able) input.
* Null, or undefined, is converted to `None`, and anything else is converted
* to `Some`.
*/
static from(value) {
return isNonNullable(value) ? Optional.some(value) : Optional.none();
}
/**
* Converts an `Optional` to a nullable type, by getting the value if it
* exists, or returning `null` if it does not.
*/
getOrNull() {
return this.tag ? this.value : null;
}
/**
* Converts an `Optional` to an undefined-able type, by getting the value if
* it exists, or returning `undefined` if it does not.
*/
getOrUndefined() {
return this.value;
}
// --- Utilities ---
/**
* If the `Optional` contains a value, perform an action on that value.
* Unlike the rest of the methods on this type, `.each` has side-effects. If
* you want to transform an `Optional<T>` **into** something, then this is not
* the method for you. If you want to use an `Optional<T>` to **do**
* something, then this is the method for you - provided you're okay with not
* doing anything in the case where the `Optional` doesn't have a value inside
* it. If you're not sure whether your use-case fits into transforming
* **into** something or **doing** something, check whether it has a return
* value. If it does, you should be performing a transform.
*/
each(worker) {
if (this.tag) {
worker(this.value);
}
}
/**
* Turn the `Optional` object into an array that contains all of the values
* stored inside the `Optional`. In practice, this means the output will have
* either 0 or 1 elements.
*/
toArray() {
return this.tag ? [this.value] : [];
}
/**
* Turn the `Optional` object into a string for debugging or printing. Not
* recommended for production code, but good for debugging. Also note that
* these days an `Optional` object can be logged to the console directly, and
* its inner value (if it exists) will be visible.
*/
toString() {
return this.tag ? `some(${this.value})` : 'none()';
}
}
const nativeSlice = Array.prototype.slice;
const exists = (xs, pred) => {
for (let i = 0, len = xs.length; i < len; i++) {
const x = xs[i];
if (pred(x, i)) {
return true;
}
}
return false;
};
const map$1 = (xs, f) => {
// pre-allocating array size when it's guaranteed to be known
// http://jsperf.com/push-allocated-vs-dynamic/22
const len = xs.length;
const r = new Array(len);
for (let i = 0; i < len; i++) {
const x = xs[i];
r[i] = f(x, i);
}
return r;
};
// Unwound implementing other functions in terms of each.
// The code size is roughly the same, and it should allow for better optimisation.
// const each = function<T, U>(xs: T[], f: (x: T, i?: number, xs?: T[]) => void): void {
const each$1 = (xs, f) => {
for (let i = 0, len = xs.length; i < len; i++) {
const x = xs[i];
f(x, i);
}
};
isFunction(Array.from) ? Array.from : (x) => nativeSlice.call(x);
// There are many variations of Object iteration that are faster than the 'for-in' style:
// http://jsperf.com/object-keys-iteration/107
//
// Use the native keys if it is available (IE9+), otherwise fall back to manually filtering
const keys = Object.keys;
const hasOwnProperty = Object.hasOwnProperty;
const each = (obj, f) => {
const props = keys(obj);
for (let k = 0, len = props.length; k < len; k++) {
const i = props[k];
const x = obj[i];
f(x, i);
}
};
const map = (obj, f) => {
return tupleMap(obj, (x, i) => ({
k: i,
v: f(x, i)
}));
};
const tupleMap = (obj, f) => {
const r = {};
each(obj, (x, i) => {
const tuple = f(x, i);
r[tuple.k] = tuple.v;
});
return r;
};
const has = (obj, key) => hasOwnProperty.call(obj, key);
const Cell = (initial) => {
let value = initial;
const get = () => {
return value;
};
const set = (v) => {
value = v;
};
return {
get,
set
};
};
const shallow = (old, nu) => {
return nu;
};
const baseMerge = (merger) => {
return (...objects) => {
if (objects.length === 0) {
throw new Error(`Can't merge zero objects`);
}
const ret = {};
for (let j = 0; j < objects.length; j++) {
const curObject = objects[j];
for (const key in curObject) {
if (has(curObject, key)) {
ret[key] = merger(ret[key], curObject[key]);
}
}
}
return ret;
};
};
const merge = baseMerge(shallow);
const singleton = (doRevoke) => {
const subject = Cell(Optional.none());
const revoke = () => subject.get().each(doRevoke);
const clear = () => {
revoke();
subject.set(Optional.none());
};
const isSet = () => subject.get().isSome();
const get = () => subject.get();
const set = (s) => {
revoke();
subject.set(Optional.some(s));
};
return {
clear,
isSet,
get,
set
};
};
const value = () => {
const subject = singleton(noop);
const on = (f) => subject.get().each(f);
return {
...subject,
on
};
};
const checkRange = (str, substr, start) => substr === '' || str.length >= substr.length && str.substr(start, start + substr.length) === substr;
const contains = (str, substr, start = 0, end) => {
const idx = str.indexOf(substr, start);
if (idx !== -1) {
return isUndefined(end) ? true : idx + substr.length <= end;
}
else {
return false;
}
};
/** Does 'str' start with 'prefix'?
* Note: all strings start with the empty string.
* More formally, for all strings x, startsWith(x, "").
* This is so that for all strings x and y, startsWith(y + x, y)
*/
const startsWith = (str, prefix) => {
return checkRange(str, prefix, 0);
};
// Run a function fn after rate ms. If another invocation occurs
// during the time it is waiting, reschedule the function again
// with the new arguments.
const last = (fn, rate) => {
let timer = null;
const cancel = () => {
if (!isNull(timer)) {
clearTimeout(timer);
timer = null;
}
};
const throttle = (...args) => {
cancel();
timer = setTimeout(() => {
timer = null;
fn.apply(null, args);
}, rate);
};
return {
cancel,
throttle
};
};
const insertEmoticon = (editor, ch) => {
editor.insertContent(ch);
};
var global = tinymce.util.Tools.resolve('tinymce.Resource');
const DEFAULT_ID = 'tinymce.plugins.emoticons';
const option = (name) => (editor) => editor.options.get(name);
const register$2 = (editor, pluginUrl) => {
const registerOption = editor.options.register;
registerOption('emoticons_database', {
processor: 'string',
default: 'emojis'
});
registerOption('emoticons_database_url', {
processor: 'string',
default: `${pluginUrl}/js/${getEmojiDatabase(editor)}${editor.suffix}.js`
});
registerOption('emoticons_database_id', {
processor: 'string',
default: DEFAULT_ID
});
registerOption('emoticons_append', {
processor: 'object',
default: {}
});
registerOption('emoticons_images_url', {
processor: 'string',
default: 'https://cdnjs.cloudflare.com/ajax/libs/twemoji/15.1.0/72x72/'
});
};
const getEmojiDatabase = option('emoticons_database');
const getEmojiDatabaseUrl = option('emoticons_database_url');
const getEmojiDatabaseId = option('emoticons_database_id');
const getAppendedEmoji = option('emoticons_append');
const getEmojiImageUrl = option('emoticons_images_url');
const ALL_CATEGORY = 'All';
const categoryNameMap = {
symbols: 'Symbols',
people: 'People',
animals_and_nature: 'Animals and Nature',
food_and_drink: 'Food and Drink',
activity: 'Activity',
travel_and_places: 'Travel and Places',
objects: 'Objects',
flags: 'Flags',
user: 'User Defined'
};
const translateCategory = (categories, name) => has(categories, name) ? categories[name] : name;
const getUserDefinedEmoji = (editor) => {
const userDefinedEmoticons = getAppendedEmoji(editor);
return map(userDefinedEmoticons, (value) =>
// Set some sane defaults for the custom emoji entry
({ keywords: [], category: 'user', ...value }));
};
// TODO: Consider how to share this loading across different editors
const initDatabase = (editor, databaseUrl, databaseId) => {
const categories = value();
const all = value();
const emojiImagesUrl = getEmojiImageUrl(editor);
const getEmoji = (lib) => {
// Note: This is a little hacky, but the database doesn't provide a way for us to tell what sort of database is being used
if (startsWith(lib.char, '<img')) {
return lib.char.replace(/src="([^"]+)"/, (match, url) => `src="${emojiImagesUrl}${url}"`);
}
else {
return lib.char;
}
};
const processEmojis = (emojis) => {
const cats = {};
const everything = [];
each(emojis, (lib, title) => {
const entry = {
// Omitting fitzpatrick_scale
title,
keywords: lib.keywords,
char: getEmoji(lib),
category: translateCategory(categoryNameMap, lib.category)
};
const current = cats[entry.category] !== undefined ? cats[entry.category] : [];
cats[entry.category] = current.concat([entry]);
everything.push(entry);
});
categories.set(cats);
all.set(everything);
};
editor.on('init', () => {
global.load(databaseId, databaseUrl).then((emojis) => {
const userEmojis = getUserDefinedEmoji(editor);
processEmojis(merge(emojis, userEmojis));
}, (err) => {
// eslint-disable-next-line no-console
console.log(`Failed to load emojis: ${err}`);
categories.set({});
all.set([]);
});
});
const listCategory = (category) => {
if (category === ALL_CATEGORY) {
return listAll();
}
return categories.get().bind((cats) => Optional.from(cats[category])).getOr([]);
};
const listAll = () => all.get().getOr([]);
const listCategories = () =>
// TODO: Category key order should be adjusted to match the standard
[ALL_CATEGORY].concat(keys(categories.get().getOr({})));
const waitForLoad = () => {
if (hasLoaded()) {
return Promise.resolve(true);
}
else {
return new Promise((resolve, reject) => {
let numRetries = 15;
const interval = setInterval(() => {
if (hasLoaded()) {
clearInterval(interval);
resolve(true);
}
else {
numRetries--;
if (numRetries < 0) {
// eslint-disable-next-line no-console
console.log('Could not load emojis from url: ' + databaseUrl);
clearInterval(interval);
reject(false);
}
}
}, 100);
});
}
};
const hasLoaded = () => categories.isSet() && all.isSet();
return {
listCategories,
hasLoaded,
waitForLoad,
listAll,
listCategory
};
};
const emojiMatches = (emoji, lowerCasePattern) => contains(emoji.title.toLowerCase(), lowerCasePattern) ||
exists(emoji.keywords, (k) => contains(k.toLowerCase(), lowerCasePattern));
const emojisFrom = (list, pattern, maxResults) => {
const matches = [];
const lowerCasePattern = pattern.toLowerCase();
const reachedLimit = maxResults.fold(() => never, (max) => (size) => size >= max);
for (let i = 0; i < list.length; i++) {
// TODO: more intelligent search by showing title matches at the top, keyword matches after that (use two arrays and concat at the end)
if (pattern.length === 0 || emojiMatches(list[i], lowerCasePattern)) {
matches.push({
value: list[i].char,
text: list[i].title,
icon: list[i].char
});
if (reachedLimit(matches.length)) {
break;
}
}
}
return matches;
};
const patternName = 'pattern';
const open = (editor, database) => {
const initialState = {
pattern: '',
results: emojisFrom(database.listAll(), '', Optional.some(300))
};
const currentTab = Cell(ALL_CATEGORY);
const scan = (dialogApi) => {
const dialogData = dialogApi.getData();
const category = currentTab.get();
const candidates = database.listCategory(category);
const results = emojisFrom(candidates, dialogData[patternName], category === ALL_CATEGORY ? Optional.some(300) : Optional.none());
dialogApi.setData({
results
});
};
const updateFilter = last((dialogApi) => {
scan(dialogApi);
}, 200);
const searchField = {
label: 'Search',
type: 'input',
name: patternName
};
const resultsField = {
type: 'collection',
name: 'results'
// TODO TINY-3229 implement collection columns properly
// columns: 'auto'
};
const getInitialState = () => {
const body = {
type: 'tabpanel',
// All tabs have the same fields.
tabs: map$1(database.listCategories(), (cat) => ({
title: cat,
name: cat,
items: [searchField, resultsField]
}))
};
return {
title: 'Emojis',
size: 'normal',
body,
initialData: initialState,
onTabChange: (dialogApi, details) => {
currentTab.set(details.newTabName);
updateFilter.throttle(dialogApi);
},
onChange: updateFilter.throttle,
onAction: (dialogApi, actionData) => {
if (actionData.name === 'results') {
insertEmoticon(editor, actionData.value);
dialogApi.close();
}
},
buttons: [
{
type: 'cancel',
text: 'Close',
primary: true
}
]
};
};
const dialogApi = editor.windowManager.open(getInitialState());
dialogApi.focus(patternName);
if (!database.hasLoaded()) {
dialogApi.block('Loading emojis...');
database.waitForLoad().then(() => {
dialogApi.redial(getInitialState());
updateFilter.throttle(dialogApi);
dialogApi.focus(patternName);
dialogApi.unblock();
}).catch((_err) => {
dialogApi.redial({
title: 'Emojis',
body: {
type: 'panel',
items: [
{
type: 'alertbanner',
level: 'error',
icon: 'warning',
text: 'Could not load emojis'
}
]
},
buttons: [
{
type: 'cancel',
text: 'Close',
primary: true
}
],
initialData: {
pattern: '',
results: []
}
});
dialogApi.focus(patternName);
dialogApi.unblock();
});
}
};
const register$1 = (editor, database) => {
editor.addCommand('mceEmoticons', () => open(editor, database));
};
const setup = (editor) => {
editor.on('PreInit', () => {
editor.parser.addAttributeFilter('data-emoticon', (nodes) => {
each$1(nodes, (node) => {
node.attr('data-mce-resize', 'false');
node.attr('data-mce-placeholder', '1');
});
});
});
};
const init = (editor, database) => {
editor.ui.registry.addAutocompleter('emoticons', {
trigger: ':',
columns: 'auto',
minChars: 2,
fetch: (pattern, maxResults) => database.waitForLoad().then(() => {
const candidates = database.listAll();
return emojisFrom(candidates, pattern, Optional.some(maxResults));
}),
onAction: (autocompleteApi, rng, value) => {
editor.selection.setRng(rng);
editor.insertContent(value);
autocompleteApi.hide();
}
});
};
const onSetupEditable = (editor) => (api) => {
const nodeChanged = () => {
api.setEnabled(editor.selection.isEditable());
};
editor.on('NodeChange', nodeChanged);
nodeChanged();
return () => {
editor.off('NodeChange', nodeChanged);
};
};
const register = (editor) => {
const onAction = () => editor.execCommand('mceEmoticons');
editor.ui.registry.addButton('emoticons', {
tooltip: 'Emojis',
icon: 'emoji',
onAction,
onSetup: onSetupEditable(editor)
});
editor.ui.registry.addMenuItem('emoticons', {
text: 'Emojis...',
icon: 'emoji',
onAction,
onSetup: onSetupEditable(editor)
});
};
/**
* This class contains all core logic for the emoticons plugin.
*
* @class tinymce.emoticons.Plugin
* @private
*/
var Plugin = () => {
global$1.add('emoticons', (editor, pluginUrl) => {
register$2(editor, pluginUrl);
const databaseUrl = getEmojiDatabaseUrl(editor);
const databaseId = getEmojiDatabaseId(editor);
const database = initDatabase(editor, databaseUrl, databaseId);
register$1(editor, database);
register(editor);
init(editor, database);
setup(editor);
return {
getAllEmojis: () => database.waitForLoad().then(() => database.listAll())
};
});
};
Plugin();
/** *****
* DO NOT EXPORT ANYTHING
*
* IF YOU DO ROLLUP WILL LEAVE A GLOBAL ON THE PAGE
*******/
})();

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
// Exports the "fullscreen" plugin for usage with module loaders
// Usage:
// CommonJS:
// require('tinymce/plugins/fullscreen')
// ES2015:
// import 'tinymce/plugins/fullscreen'
require('./plugin.js');

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
// Exports the "help" plugin for usage with module loaders
// Usage:
// CommonJS:
// require('tinymce/plugins/help')
// ES2015:
// import 'tinymce/plugins/help'
require('./plugin.js');

View File

@@ -0,0 +1,93 @@
tinymce.Resource.add('tinymce.html-i18n.help-keynav.ar',
'<h1>بدء التنقل بواسطة لوحة المفاتيح</h1>\n' +
'\n' +
'<dl>\n' +
' <dt>التركيز على شريط القوائم</dt>\n' +
' <dd>نظاما التشغيل Windows أو Linux: Alt + F9</dd>\n' +
' <dd>نظام التشغيل macOS: &#x2325;F9</dd>\n' +
' <dt>التركيز على شريط الأدوات</dt>\n' +
' <dd>نظاما التشغيل Windows أو Linux: Alt + F10</dd>\n' +
' <dd>نظام التشغيل macOS: &#x2325;F10</dd>\n' +
' <dt>التركيز على التذييل</dt>\n' +
' <dd>نظاما التشغيل Windows أو Linux: Alt + F11</dd>\n' +
' <dd>نظام التشغيل macOS: &#x2325;F11</dd>\n' +
' <dt>تركيز الإشعارات</dt>\n' +
' <dd>نظاما التشغيل Windows أو Linux: Alt + F12</dd>\n' +
' <dd>نظام التشغيل macOS: &#x2325;F12</dd>\n' +
' <dt>التركيز على شريط أدوات السياق</dt>\n' +
' <dd>أنظمة التشغيل Windows أو Linux أو macOS: Ctrl+F9</dd>\n' +
'</dl>\n' +
'\n' +
'<p>سيبدأ التنقل عند عنصر واجهة المستخدم الأول، والذي سيتم تمييزه أو تسطيره في حالة العنصر الأول في\n' +
' مسار عنصر التذييل.</p>\n' +
'\n' +
'<h1>التنقل بين أقسام واجهة المستخدم</h1>\n' +
'\n' +
'<p>للانتقال من أحد أقسام واجهة المستخدم إلى القسم التالي، اضغط على <strong>Tab</strong>.</p>\n' +
'\n' +
'<p>للانتقال من أحد أقسام واجهة المستخدم إلى القسم السابق، اضغط على <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<p>ترتيب علامات <strong>Tab</strong> لأقسام واجهة المستخدم هذه هو:</p>\n' +
'\n' +
'<ol>\n' +
' <li>شريط القوائم</li>\n' +
' <li>كل مجموعة شريط الأدوات</li>\n' +
' <li>الشريط الجانبي</li>\n' +
' <li>مسار العنصر في التذييل</li>\n' +
' <li>زر تبديل عدد الكلمات في التذييل</li>\n' +
' <li>رابط إدراج العلامة التجارية في التذييل</li>\n' +
' <li>مؤشر تغيير حجم المحرر في التذييل</li>\n' +
'</ol>\n' +
'\n' +
'<p>إذا لم يكن قسم واجهة المستخدم موجودًا، فسيتم تخطيه.</p>\n' +
'\n' +
'<p>إذا كان التذييل يحتوي على التركيز على ‏‫التنقل بواسطة لوحة المفاتيح، ولا يوجد شريط جانبي مرئي، فإن الضغط على <strong>Shift+Tab</strong>\n' +
' ينقل التركيز إلى مجموعة شريط الأدوات الأولى، وليس الأخيرة.</p>\n' +
'\n' +
'<h1>التنقل بين أقسام واجهة المستخدم</h1>\n' +
'\n' +
'<p>للانتقال من أحد عناصر واجهة المستخدم إلى العنصر التالي، اضغط على مفتاح <strong>السهم</strong> المناسب.</p>\n' +
'\n' +
'<p>مفتاحا السهمين <strong>اليسار‎</strong> و<strong>اليمين‎</strong></p>\n' +
'\n' +
'<ul>\n' +
' <li>التنقل بين القوائم في شريط القوائم.</li>\n' +
' <li>فتح قائمة فرعية في القائمة.</li>\n' +
' <li>التنقل بين الأزرار في مجموعة شريط الأدوات.</li>\n' +
' <li>التنقل بين العناصر في مسار عنصر التذييل.</li>\n' +
'</ul>\n' +
'\n' +
'<p>مفتاحا السهمين <strong>لأسفل‎</strong> و<strong>لأعلى‎</strong></p>\n' +
'\n' +
'<ul>\n' +
' <li>التنقل بين عناصر القائمة في القائمة.</li>\n' +
' <li>التنقل بين العناصر في قائمة شريط الأدوات المنبثقة.</li>\n' +
'</ul>\n' +
'\n' +
'<p>دورة مفاتيح <strong>الأسهم‎</strong> داخل قسم واجهة المستخدم التي تم التركيز عليها.</p>\n' +
'\n' +
'<p>لإغلاق قائمة مفتوحة أو قائمة فرعية مفتوحة أو قائمة منبثقة مفتوحة، اضغط على مفتاح <strong>Esc</strong>.</p>\n' +
'\n' +
'<p>إذا كان التركيز الحالي على "الجزء العلوي" من قسم معين لواجهة المستخدم، فإن الضغط على مفتاح <strong>Esc</strong> يؤدي أيضًا إلى الخروج\n' +
' من التنقل بواسطة لوحة المفاتيح بالكامل.</p>\n' +
'\n' +
'<h1>تنفيذ عنصر قائمة أو زر شريط أدوات</h1>\n' +
'\n' +
'<p>عندما يتم تمييز عنصر القائمة المطلوب أو زر شريط الأدوات، اضغط على زر <strong>Return</strong>، أو <strong>Enter</strong>،\n' +
' أو <strong>مفتاح المسافة</strong> لتنفيذ العنصر.</p>\n' +
'\n' +
'<h1>التنقل في مربعات الحوار غير المبوبة</h1>\n' +
'\n' +
'<p>في مربعات الحوار غير المبوبة، يتم التركيز على المكون التفاعلي الأول عند فتح مربع الحوار.</p>\n' +
'\n' +
'<p>التنقل بين مكونات الحوار التفاعلي بالضغط على زر <strong>Tab</strong> أو <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<h1>التنقل في مربعات الحوار المبوبة</h1>\n' +
'\n' +
'<p>في مربعات الحوار المبوبة، يتم التركيز على الزر الأول في قائمة علامات التبويب عند فتح مربع الحوار.</p>\n' +
'\n' +
'<p>التنقل بين المكونات التفاعلية لعلامة التبويب لمربع الحوار هذه بالضغط على زر <strong>Tab</strong> أو\n' +
' <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<p>التبديل إلى علامة تبويب أخرى لمربع الحوار من خلال التركيز على قائمة علامة التبويب ثم الضغط على زر <strong>السهم</strong> المناسب\n' +
' مفتاح للتنقل بين علامات التبويب المتاحة.</p>\n');

View File

@@ -0,0 +1,93 @@
tinymce.Resource.add('tinymce.html-i18n.help-keynav.bg-BG',
'<h1>Начало на навигацията с клавиатурата</h1>\n' +
'\n' +
'<dl>\n' +
' <dt>Фокусиране върху лентата с менюта</dt>\n' +
' <dd>Windows или Linux: Alt+F9</dd>\n' +
' <dd>macOS: &#x2325;F9</dd>\n' +
' <dt>Фокусиране върху лентата с инструменти</dt>\n' +
' <dd>Windows или Linux: Alt+F10</dd>\n' +
' <dd>macOS: &#x2325;F10</dd>\n' +
' <dt>Фокусиране върху долния колонтитул</dt>\n' +
' <dd>Windows или Linux: Alt+F11</dd>\n' +
' <dd>macOS: &#x2325;F11</dd>\n' +
' <dt>Фокусиране на известието</dt>\n' +
' <dd>Windows или Linux: Alt+F12</dd>\n' +
' <dd>macOS: &#x2325;F12</dd>\n' +
' <dt>Фокусиране върху контекстуалната лента с инструменти</dt>\n' +
' <dd>Windows, Linux или macOS: Ctrl+F9</dd>\n' +
'</dl>\n' +
'\n' +
'<p>Навигацията ще започне с първия елемент на ПИ, който ще бъде маркиран или подчертан в случая на първия елемент в\n' +
' пътя до елемента в долния колонтитул.</p>\n' +
'\n' +
'<h1>Навигиране между раздели на ПИ</h1>\n' +
'\n' +
'<p>За да преминете от един раздел на ПИ към следващия, натиснете <strong>Tab</strong>.</p>\n' +
'\n' +
'<p>За да преминете от един раздел на ПИ към предишния, натиснете <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<p>Редът за <strong>обхождане с табулация</strong> на тези раздели на ПИ е:</p>\n' +
'\n' +
'<ol>\n' +
' <li>Лентата с менюта</li>\n' +
' <li>Всяка група на лентата с инструменти</li>\n' +
' <li>Страничната лента</li>\n' +
' <li>Пътят до елемента в долния колонтитул</li>\n' +
' <li>Бутонът за превключване на броя на думите в долния колонтитул</li>\n' +
' <li>Връзката за търговска марка в долния колонтитул</li>\n' +
' <li>Манипулаторът за преоразмеряване на редактора в долния колонтитул</li>\n' +
'</ol>\n' +
'\n' +
'<p>Ако някой раздел на ПИ липсва, той се пропуска.</p>\n' +
'\n' +
'<p>Ако долният колонтитул има фокус за навигация с клавиатурата и няма странична лента, натискането на <strong>Shift+Tab</strong>\n' +
' премества фокуса към първата група на лентата с инструменти, а не към последната.</p>\n' +
'\n' +
'<h1>Навигиране в разделите на ПИ</h1>\n' +
'\n' +
'<p>За да преминете от един елемент на ПИ към следващия, натиснете съответния клавиш със <strong>стрелка</strong>.</p>\n' +
'\n' +
'<p>С клавишите със стрелка <strong>наляво</strong> и <strong>надясно</strong></p>\n' +
'\n' +
'<ul>\n' +
' <li>се придвижвате между менютата в лентата с менюто;</li>\n' +
' <li>отваряте подменю в меню;</li>\n' +
' <li>се придвижвате между бутоните в група на лентата с инструменти;</li>\n' +
' <li>се придвижвате между елементи в пътя до елемент в долния колонтитул.</li>\n' +
'</ul>\n' +
'\n' +
'<p>С клавишите със стрелка <strong>надолу</strong> и <strong>нагоре</strong></p>\n' +
'\n' +
'<ul>\n' +
' <li>се придвижвате между елементите от менюто в дадено меню;</li>\n' +
' <li>се придвижвате между елементите в изскачащо меню на лентата с инструменти.</li>\n' +
'</ul>\n' +
'\n' +
'<p>Клавишите със <strong>стрелки</strong> се придвижват в рамките на фокусирания раздел на ПИ.</p>\n' +
'\n' +
'<p>За да затворите отворено меню, подменю или изскачащо меню, натиснете клавиша <strong>Esc</strong>.</p>\n' +
'\n' +
'<p>Ако текущият фокус е върху „горната част“ на конкретен раздел на ПИ, натискането на клавиша <strong>Esc</strong> също излиза\n' +
' напълно от навигацията с клавиатурата.</p>\n' +
'\n' +
'<h1>Изпълнение на елемент от менюто или бутон от лентата с инструменти</h1>\n' +
'\n' +
'<p>Когато желаният елемент от менюто или бутон от лентата с инструменти е маркиран, натиснете <strong>Return</strong>, <strong>Enter</strong>\n' +
' или <strong>клавиша за интервал</strong>, за да изпълните елемента.</p>\n' +
'\n' +
'<h1>Навигиране в диалогови прозорци без раздели</h1>\n' +
'\n' +
'<p>В диалоговите прозорци без раздели първият интерактивен компонент се фокусира, когато се отвори диалоговият прозорец.</p>\n' +
'\n' +
'<p>Навигирайте между интерактивните компоненти на диалоговия прозорец, като натиснете <strong>Tab</strong> или <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<h1>Навигиране в диалогови прозорци с раздели</h1>\n' +
'\n' +
'<p>В диалоговите прозорци с раздели първият бутон в менюто с раздели се фокусира, когато се отвори диалоговият прозорец.</p>\n' +
'\n' +
'<p>Навигирайте между интерактивните компоненти на този диалогов раздел, като натиснете <strong>Tab</strong> или\n' +
' <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<p>Превключете към друг диалогов раздел, като фокусирате върху менюто с раздели и след това натиснете съответния клавиш със <strong>стрелка</strong>,\n' +
' за да преминете през наличните раздели.</p>\n');

View File

@@ -0,0 +1,93 @@
tinymce.Resource.add('tinymce.html-i18n.help-keynav.bg_BG',
'<h1>Начало на навигацията с клавиатурата</h1>\n' +
'\n' +
'<dl>\n' +
' <dt>Фокусиране върху лентата с менюта</dt>\n' +
' <dd>Windows или Linux: Alt+F9</dd>\n' +
' <dd>macOS: &#x2325;F9</dd>\n' +
' <dt>Фокусиране върху лентата с инструменти</dt>\n' +
' <dd>Windows или Linux: Alt+F10</dd>\n' +
' <dd>macOS: &#x2325;F10</dd>\n' +
' <dt>Фокусиране върху долния колонтитул</dt>\n' +
' <dd>Windows или Linux: Alt+F11</dd>\n' +
' <dd>macOS: &#x2325;F11</dd>\n' +
' <dt>Фокусиране на известието</dt>\n' +
' <dd>Windows или Linux: Alt+F12</dd>\n' +
' <dd>macOS: &#x2325;F12</dd>\n' +
' <dt>Фокусиране върху контекстуалната лента с инструменти</dt>\n' +
' <dd>Windows, Linux или macOS: Ctrl+F9</dd>\n' +
'</dl>\n' +
'\n' +
'<p>Навигацията ще започне с първия елемент на ПИ, който ще бъде маркиран или подчертан в случая на първия елемент в\n' +
' пътя до елемента в долния колонтитул.</p>\n' +
'\n' +
'<h1>Навигиране между раздели на ПИ</h1>\n' +
'\n' +
'<p>За да преминете от един раздел на ПИ към следващия, натиснете <strong>Tab</strong>.</p>\n' +
'\n' +
'<p>За да преминете от един раздел на ПИ към предишния, натиснете <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<p>Редът за <strong>обхождане с табулация</strong> на тези раздели на ПИ е:</p>\n' +
'\n' +
'<ol>\n' +
' <li>Лентата с менюта</li>\n' +
' <li>Всяка група на лентата с инструменти</li>\n' +
' <li>Страничната лента</li>\n' +
' <li>Пътят до елемента в долния колонтитул</li>\n' +
' <li>Бутонът за превключване на броя на думите в долния колонтитул</li>\n' +
' <li>Връзката за търговска марка в долния колонтитул</li>\n' +
' <li>Манипулаторът за преоразмеряване на редактора в долния колонтитул</li>\n' +
'</ol>\n' +
'\n' +
'<p>Ако някой раздел на ПИ липсва, той се пропуска.</p>\n' +
'\n' +
'<p>Ако долният колонтитул има фокус за навигация с клавиатурата и няма странична лента, натискането на <strong>Shift+Tab</strong>\n' +
' премества фокуса към първата група на лентата с инструменти, а не към последната.</p>\n' +
'\n' +
'<h1>Навигиране в разделите на ПИ</h1>\n' +
'\n' +
'<p>За да преминете от един елемент на ПИ към следващия, натиснете съответния клавиш със <strong>стрелка</strong>.</p>\n' +
'\n' +
'<p>С клавишите със стрелка <strong>наляво</strong> и <strong>надясно</strong></p>\n' +
'\n' +
'<ul>\n' +
' <li>се придвижвате между менютата в лентата с менюто;</li>\n' +
' <li>отваряте подменю в меню;</li>\n' +
' <li>се придвижвате между бутоните в група на лентата с инструменти;</li>\n' +
' <li>се придвижвате между елементи в пътя до елемент в долния колонтитул.</li>\n' +
'</ul>\n' +
'\n' +
'<p>С клавишите със стрелка <strong>надолу</strong> и <strong>нагоре</strong></p>\n' +
'\n' +
'<ul>\n' +
' <li>се придвижвате между елементите от менюто в дадено меню;</li>\n' +
' <li>се придвижвате между елементите в изскачащо меню на лентата с инструменти.</li>\n' +
'</ul>\n' +
'\n' +
'<p>Клавишите със <strong>стрелки</strong> се придвижват в рамките на фокусирания раздел на ПИ.</p>\n' +
'\n' +
'<p>За да затворите отворено меню, подменю или изскачащо меню, натиснете клавиша <strong>Esc</strong>.</p>\n' +
'\n' +
'<p>Ако текущият фокус е върху „горната част“ на конкретен раздел на ПИ, натискането на клавиша <strong>Esc</strong> също излиза\n' +
' напълно от навигацията с клавиатурата.</p>\n' +
'\n' +
'<h1>Изпълнение на елемент от менюто или бутон от лентата с инструменти</h1>\n' +
'\n' +
'<p>Когато желаният елемент от менюто или бутон от лентата с инструменти е маркиран, натиснете <strong>Return</strong>, <strong>Enter</strong>\n' +
' или <strong>клавиша за интервал</strong>, за да изпълните елемента.</p>\n' +
'\n' +
'<h1>Навигиране в диалогови прозорци без раздели</h1>\n' +
'\n' +
'<p>В диалоговите прозорци без раздели първият интерактивен компонент се фокусира, когато се отвори диалоговият прозорец.</p>\n' +
'\n' +
'<p>Навигирайте между интерактивните компоненти на диалоговия прозорец, като натиснете <strong>Tab</strong> или <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<h1>Навигиране в диалогови прозорци с раздели</h1>\n' +
'\n' +
'<p>В диалоговите прозорци с раздели първият бутон в менюто с раздели се фокусира, когато се отвори диалоговият прозорец.</p>\n' +
'\n' +
'<p>Навигирайте между интерактивните компоненти на този диалогов раздел, като натиснете <strong>Tab</strong> или\n' +
' <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<p>Превключете към друг диалогов раздел, като фокусирате върху менюто с раздели и след това натиснете съответния клавиш със <strong>стрелка</strong>,\n' +
' за да преминете през наличните раздели.</p>\n');

View File

@@ -0,0 +1,93 @@
tinymce.Resource.add('tinymce.html-i18n.help-keynav.ca',
'<h1>Inici de la navegació amb el teclat</h1>\n' +
'\n' +
'<dl>\n' +
' <dt>Enfocar la barra de menús</dt>\n' +
' <dd>Windows o Linux: Alt+F9</dd>\n' +
' <dd>macOS: &#x2325;F9</dd>\n' +
" <dt>Enfocar la barra d'eines</dt>\n" +
' <dd>Windows o Linux: Alt+F10</dd>\n' +
' <dd>macOS: &#x2325;F10</dd>\n' +
' <dt>Enfocar el peu de pàgina</dt>\n' +
' <dd>Windows o Linux: Alt+F11</dd>\n' +
' <dd>macOS: &#x2325;F11</dd>\n' +
' <dt>Enfocar la notificació</dt>\n' +
' <dd>Windows o Linux: Alt+F12</dd>\n' +
' <dd>macOS: &#x2325;F12</dd>\n' +
" <dt>Enfocar una barra d'eines contextual</dt>\n" +
' <dd>Windows, Linux o macOS: Ctrl+F9</dd>\n' +
'</dl>\n' +
'\n' +
"<p>La navegació començarà en el primer element de la interfície d'usuari, que es ressaltarà o subratllarà per al primer element a\n" +
" la ruta de l'element de peu de pàgina.</p>\n" +
'\n' +
"<h1>Navegació entre seccions de la interfície d'usuari</h1>\n" +
'\n' +
"<p>Per desplaçar-vos des d'una secció de la interfície d'usuari a la següent, premeu la tecla <strong>Tab</strong>.</p>\n" +
'\n' +
"<p>Per desplaçar-vos des d'una secció de la interfície d'usuari a l'anterior, premeu les tecles <strong>Maj+Tab</strong>.</p>\n" +
'\n' +
"<p>L'ordre en prémer la tecla <strong>Tab</strong> d'aquestes secciones de la interfície d'usuari és:</p>\n" +
'\n' +
'<ol>\n' +
' <li>Barra de menús</li>\n' +
" <li>Cada grup de la barra d'eines</li>\n" +
' <li>Barra lateral</li>\n' +
" <li>Ruta de l'element del peu de pàgina</li>\n" +
' <li>Botó de commutació de recompte de paraules al peu de pàgina</li>\n' +
' <li>Enllaç de marca del peu de pàgina</li>\n' +
" <li>Control de canvi de mida de l'editor al peu de pàgina</li>\n" +
'</ol>\n' +
'\n' +
"<p>Si no hi ha una secció de la interfície d'usuari, s'ometrà.</p>\n" +
'\n' +
'<p>Si el peu de pàgina té el focus de navegació del teclat i no hi ha cap barra lateral visible, en prémer <strong>Maj+Tab</strong>\n' +
" el focus es mou al primer grup de la barra d'eines, no l'últim.</p>\n" +
'\n' +
"<h1>Navegació dins de les seccions de la interfície d'usuari</h1>\n" +
'\n' +
"<p>Per desplaçar-vos des d'un element de la interfície d'usuari al següent, premeu la tecla de <strong>Fletxa</strong> adequada.</p>\n" +
'\n' +
'<p>Les tecles de fletxa <strong>Esquerra</strong> i <strong>Dreta</strong></p>\n' +
'\n' +
'<ul>\n' +
' <li>us permeten desplaçar-vos entre menús de la barra de menús.</li>\n' +
' <li>obren un submenú en un menú.</li>\n' +
" <li>us permeten desplaçar-vos entre botons d'un grup de la barra d'eines.</li>\n" +
" <li>us permeten desplaçar-vos entre elements de la ruta d'elements del peu de pàgina.</li>\n" +
'</ul>\n' +
'\n' +
'<p>Les tecles de fletxa <strong>Avall</strong> i <strong>Amunt</strong></p>\n' +
'\n' +
'<ul>\n' +
" <li>us permeten desplaçar-vos entre elements de menú d'un menú.</li>\n" +
" <li>us permeten desplaçar-vos entre elements d'un menú emergent de la barra d'eines.</li>\n" +
'</ul>\n' +
'\n' +
"<p>Les tecles de <strong>Fletxa</strong> us permeten desplaçar-vos dins de la secció de la interfície d'usuari que té el focus.</p>\n" +
'\n' +
'<p>Per tancar un menú, un submenú o un menú emergent oberts, premeu la tecla <strong>Esc</strong>.</p>\n' +
'\n' +
"<p>Si el focus actual es troba a la part superior d'una secció específica de la interfície d'usuari, en prémer la tecla <strong>Esc</strong> també es tanca\n" +
' completament la navegació amb el teclat.</p>\n' +
'\n' +
"<h1>Execució d'un element de menú o d'un botó de la barra d'eines</h1>\n" +
'\n' +
"<p>Quan l'element del menú o el botó de la barra d'eines que desitgeu estigui ressaltat, premeu <strong>Retorn</strong>, <strong>Intro</strong>\n" +
" o la <strong>barra d'espai</strong> per executar l'element.</p>\n" +
'\n' +
'<h1>Navegació per quadres de diàleg sense pestanyes</h1>\n' +
'\n' +
"<p>En els quadres de diàleg sense pestanyes, el primer component interactiu pren el focus quan s'obre el quadre diàleg.</p>\n" +
'\n' +
'<p>Premeu la tecla <strong>Tab</strong> o les tecles <strong>Maj+Tab</strong> per desplaçar-vos entre components interactius del quadre de diàleg.</p>\n' +
'\n' +
'<h1>Navegació per quadres de diàleg amb pestanyes</h1>\n' +
'\n' +
"<p>En els quadres de diàleg amb pestanyes, el primer botó del menú de la pestanya pren el focus quan s'obre el quadre diàleg.</p>\n" +
'\n' +
"<p>Per desplaçar-vos entre components interactius d'aquest quadre de diàleg, premeu la tecla <strong>Tab</strong> o\n" +
' les tecles <strong>Maj+Tab</strong>.</p>\n' +
'\n' +
"<p>Canvieu a la pestanya d'un altre quadre de diàleg, tot enfocant el menú de la pestanya, i després premeu la tecla <strong>Fletxa</strong> adequada\n" +
' per canviar entre les pestanyes disponibles.</p>\n');

View File

@@ -0,0 +1,93 @@
tinymce.Resource.add('tinymce.html-i18n.help-keynav.cs',
'<h1>Začínáme navigovat pomocí klávesnice</h1>\n' +
'\n' +
'<dl>\n' +
' <dt>Přejít na řádek nabídek</dt>\n' +
' <dd>Windows nebo Linux: Alt+F9</dd>\n' +
' <dd>macOS: &#x2325;F9</dd>\n' +
' <dt>Přejít na panel nástrojů</dt>\n' +
' <dd>Windows nebo Linux: Alt+F10</dd>\n' +
' <dd>macOS: &#x2325;F10</dd>\n' +
' <dt>Přejít na zápatí</dt>\n' +
' <dd>Windows nebo Linux: Alt+F11</dd>\n' +
' <dd>macOS: &#x2325;F11</dd>\n' +
' <dt>Přejít na oznámení</dt>\n' +
' <dd>Windows nebo Linux: Alt+F12</dd>\n' +
' <dd>macOS: &#x2325;F12</dd>\n' +
' <dt>Přejít na kontextový panel nástrojů</dt>\n' +
' <dd>Windows, Linux nebo macOS: Ctrl+F9</dd>\n' +
'</dl>\n' +
'\n' +
'<p>Navigace začne u první položky uživatelského rozhraní, která bude zvýrazněna nebo v případě první položky\n' +
' cesty k prvku zápatí podtržena.</p>\n' +
'\n' +
'<h1>Navigace mezi oddíly uživatelského rozhraní</h1>\n' +
'\n' +
'<p>Stisknutím klávesy <strong>Tab</strong> se posunete z jednoho oddílu uživatelského rozhraní na další.</p>\n' +
'\n' +
'<p>Stisknutím kláves <strong>Shift+Tab</strong> se posunete z jednoho oddílu uživatelského rozhraní na předchozí.</p>\n' +
'\n' +
'<p>Pořadí přepínání mezi oddíly uživatelského rozhraní pomocí klávesy <strong>Tab</strong>:</p>\n' +
'\n' +
'<ol>\n' +
' <li>Řádek nabídek</li>\n' +
' <li>Každá skupina panelu nástrojů</li>\n' +
' <li>Boční panel</li>\n' +
' <li>Cesta k prvku v zápatí.</li>\n' +
' <li>Tlačítko přepínače počtu slov v zápatí</li>\n' +
' <li>Odkaz na informace o značce v zápatí</li>\n' +
' <li>Úchyt pro změnu velikosti editoru v zápatí</li>\n' +
'</ol>\n' +
'\n' +
'<p>Pokud nějaký oddíl uživatelského rozhraní není přítomen, je přeskočen.</p>\n' +
'\n' +
'<p>Pokud je zápatí vybrané pro navigaci pomocí klávesnice a není zobrazen žádný boční panel, stisknutím kláves <strong>Shift+Tab</strong>\n' +
' přejdete na první skupinu panelu nástrojů, nikoli na poslední.</p>\n' +
'\n' +
'<h1>Navigace v rámci oddílů uživatelského rozhraní</h1>\n' +
'\n' +
'<p>Chcete-li se přesunout z jednoho prvku uživatelského rozhraní na další, stiskněte příslušnou klávesu s <strong>šipkou</strong>.</p>\n' +
'\n' +
'<p>Klávesy s šipkou <strong>vlevo</strong> a <strong>vpravo</strong></p>\n' +
'\n' +
'<ul>\n' +
' <li>umožňují přesun mezi nabídkami na řádku nabídek;</li>\n' +
' <li>otevírají podnabídku nabídky;</li>\n' +
' <li>umožňují přesun mezi tlačítky ve skupině panelu nástrojů;</li>\n' +
' <li>umožňují přesun mezi položkami cesty prvku v zápatí.</li>\n' +
'</ul>\n' +
'\n' +
'<p>Klávesy se šipkou <strong>dolů</strong> a <strong>nahoru</strong></p>\n' +
'\n' +
'<ul>\n' +
' <li>umožňují přesun mezi položkami nabídky;</li>\n' +
' <li>umožňují přesun mezi položkami místní nabídky panelu nástrojů.</li>\n' +
'</ul>\n' +
'\n' +
'<p><strong>Šipky</strong> provádí přepínání v rámci vybraného oddílu uživatelského rozhraní.</p>\n' +
'\n' +
'<p>Chcete-li zavřít otevřenou nabídku, podnabídku nebo místní nabídku, stiskněte klávesu <strong>Esc</strong>.</p>\n' +
'\n' +
'<p>Pokud je aktuálně vybrána horní část oddílu uživatelského rozhraní, stisknutím klávesy <strong>Esc</strong> zcela ukončíte také\n' +
' navigaci pomocí klávesnice.</p>\n' +
'\n' +
'<h1>Provedení příkazu položky nabídky nebo tlačítka panelu nástrojů</h1>\n' +
'\n' +
'<p>Pokud je zvýrazněna požadovaná položka nabídky nebo tlačítko panelu nástrojů, stisknutím klávesy <strong>Return</strong>, <strong>Enter</strong>\n' +
' nebo <strong>mezerníku</strong> provedete příslušný příkaz.</p>\n' +
'\n' +
'<h1>Navigace v dialogových oknech bez záložek</h1>\n' +
'\n' +
'<p>Při otevření dialogových oken bez záložek přejdete na první interaktivní komponentu.</p>\n' +
'\n' +
'<p>Přecházet mezi interaktivními komponentami dialogového okna můžete stisknutím klávesy <strong>Tab</strong> nebo kombinace <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<h1>Navigace v dialogových oknech se záložkami</h1>\n' +
'\n' +
'<p>Při otevření dialogových oken se záložkami přejdete na první tlačítko v nabídce záložek.</p>\n' +
'\n' +
'<p>Přecházet mezi interaktivními komponentami této záložky dialogového okna můžete stisknutím klávesy <strong>Tab</strong> nebo\n' +
' kombinace <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<p>Chcete-li přepnout na další záložku dialogového okna, přejděte na nabídku záložek a poté můžete stisknutím požadované <strong>šipky</strong>\n' +
' přepínat mezi dostupnými záložkami.</p>\n');

View File

@@ -0,0 +1,93 @@
tinymce.Resource.add('tinymce.html-i18n.help-keynav.da',
'<h1>Start tastaturnavigation</h1>\n' +
'\n' +
'<dl>\n' +
' <dt>Fokuser på menulinjen</dt>\n' +
' <dd>Windows eller Linux: Alt+F9</dd>\n' +
' <dd>macOS: &#x2325;F9</dd>\n' +
' <dt>Fokuser på værktøjslinjen</dt>\n' +
' <dd>Windows eller Linux: Alt+F10</dd>\n' +
' <dd>macOS: &#x2325;F10</dd>\n' +
' <dt>Fokuser på sidefoden</dt>\n' +
' <dd>Windows eller Linux: Alt+F11</dd>\n' +
' <dd>macOS: &#x2325;F11</dd>\n' +
' <dt>Fokuser på meddelelsen</dt>\n' +
' <dd>Windows eller Linux: Alt+F12</dd>\n' +
' <dd>macOS: &#x2325;F12</dd>\n' +
' <dt>Fokuser på kontekstuel værktøjslinje</dt>\n' +
' <dd>Windows, Linux eller macOS: Ctrl+F9</dd>\n' +
'</dl>\n' +
'\n' +
'<p>Navigationen starter ved det første UI-element, som fremhæves eller understreges hvad angår det første element i\n' +
' sidefodens sti til elementet.</p>\n' +
'\n' +
'<h1>Naviger mellem UI-sektioner</h1>\n' +
'\n' +
'<p>Gå fra én UI-sektion til den næste ved at trykke på <strong>Tab</strong>.</p>\n' +
'\n' +
'<p>Gå fra én UI-sektion til den forrige ved at trykke på <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<p><strong>Tab</strong>-rækkefølgen af disse UI-sektioner er:</p>\n' +
'\n' +
'<ol>\n' +
' <li>Menulinje</li>\n' +
' <li>Hver værktøjsgruppe</li>\n' +
' <li>Sidepanel</li>\n' +
' <li>Sti til elementet i sidefoden</li>\n' +
' <li>Til/fra-knap for ordoptælling i sidefoden</li>\n' +
' <li>Brandinglink i sidefoden</li>\n' +
' <li>Tilpasningshåndtag for editor i sidefoden</li>\n' +
'</ol>\n' +
'\n' +
'<p>Hvis en UI-sektion ikke er til stede, springes den over.</p>\n' +
'\n' +
'<p>Hvis sidefoden har fokus til tastaturnavigation, og der ikke er noget synligt sidepanel, kan der trykkes på <strong>Shift+Tab</strong>\n' +
' for at flytte fokus til den første værktøjsgruppe, ikke den sidste.</p>\n' +
'\n' +
'<h1>Naviger inden for UI-sektioner</h1>\n' +
'\n' +
'<p>Gå fra ét UI-element til det næste ved at trykke på den relevante <strong>piletast</strong>.</p>\n' +
'\n' +
'<p><strong>Venstre</strong> og <strong>højre</strong> piletast</p>\n' +
'\n' +
'<ul>\n' +
' <li>flytter mellem menuerne i menulinjen.</li>\n' +
' <li>åbner en undermenu i en menu.</li>\n' +
' <li>flytter mellem knapperne i en værktøjsgruppe.</li>\n' +
' <li>flytter mellem elementer i sidefodens sti til elementet.</li>\n' +
'</ul>\n' +
'\n' +
'<p>Pil <strong>ned</strong> og <strong>op</strong></p>\n' +
'\n' +
'<ul>\n' +
' <li>flytter mellem menupunkterne i en menu.</li>\n' +
' <li>flytter mellem punkterne i en genvejsmenu i værktøjslinjen.</li>\n' +
'</ul>\n' +
'\n' +
'<p><strong>Piletasterne</strong> kører rundt inden for UI-sektionen, der fokuseres på.</p>\n' +
'\n' +
'<p>For at lukke en åben menu, en åben undermenu eller en åben genvejsmenu trykkes der på <strong>Esc</strong>-tasten.</p>\n' +
'\n' +
"<p>Hvis det aktuelle fokus er i 'toppen' af en bestemt UI-sektion, vil tryk på <strong>Esc</strong>-tasten også afslutte\n" +
' tastaturnavigationen helt.</p>\n' +
'\n' +
'<h1>Udfør et menupunkt eller en værktøjslinjeknap</h1>\n' +
'\n' +
'<p>Når det ønskede menupunkt eller den ønskede værktøjslinjeknap er fremhævet, trykkes der på <strong>Retur</strong>, <strong>Enter</strong>\n' +
' eller <strong>mellemrumstasten</strong> for at udføre elementet.</p>\n' +
'\n' +
'<h1>Naviger i ikke-faneopdelte dialogbokse</h1>\n' +
'\n' +
'<p>I ikke-faneopdelte dialogbokse får den første interaktive komponent fokus, når dialogboksen åbnes.</p>\n' +
'\n' +
'<p>Naviger mellem interaktive dialogbokskomponenter ved at trykke på <strong>Tab</strong> eller <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<h1>Naviger i faneopdelte dialogbokse</h1>\n' +
'\n' +
'<p>I faneopdelte dialogbokse får den første knap i fanemenuen fokus, når dialogboksen åbnes.</p>\n' +
'\n' +
'<p>Naviger mellem interaktive komponenter i denne dialogboksfane ved at trykke på <strong>Tab</strong> eller\n' +
' <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<p>Skift til en anden dialogboksfane ved at fokusere på fanemenuen og derefter trykke på den relevante <strong>piletast</strong>\n' +
' for at køre igennem de tilgængelige faner.</p>\n');

View File

@@ -0,0 +1,93 @@
tinymce.Resource.add('tinymce.html-i18n.help-keynav.de',
'<h1>Grundlagen der Tastaturnavigation</h1>\n' +
'\n' +
'<dl>\n' +
' <dt>Fokus auf Menüleiste</dt>\n' +
' <dd>Windows oder Linux: ALT+F9</dd>\n' +
' <dd>macOS: &#x2325;F9</dd>\n' +
' <dt>Fokus auf Symbolleiste</dt>\n' +
' <dd>Windows oder Linux: ALT+F10</dd>\n' +
' <dd>macOS: &#x2325;F10</dd>\n' +
' <dt>Fokus auf Fußzeile</dt>\n' +
' <dd>Windows oder Linux: ALT+F11</dd>\n' +
' <dd>macOS: &#x2325;F11</dd>\n' +
' <dt>Benachrichtigung fokussieren</dt>\n' +
' <dd>Windows oder Linux: ALT+F12</dd>\n' +
' <dd>macOS: &#x2325;F12</dd>\n' +
' <dt>Fokus auf kontextbezogene Symbolleiste</dt>\n' +
' <dd>Windows, Linux oder macOS: STRG+F9</dd>\n' +
'</dl>\n' +
'\n' +
'<p>Die Navigation beginnt beim ersten Benutzeroberflächenelement, welches hervorgehoben ist. Falls sich das erste Element im Pfad der Fußzeile befindet,\n' +
' ist es unterstrichen.</p>\n' +
'\n' +
'<h1>Zwischen Abschnitten der Benutzeroberfläche navigieren</h1>\n' +
'\n' +
'<p>Um von einem Abschnitt der Benutzeroberfläche zum nächsten zu wechseln, drücken Sie <strong>TAB</strong>.</p>\n' +
'\n' +
'<p>Um von einem Abschnitt der Benutzeroberfläche zum vorherigen zu wechseln, drücken Sie <strong>UMSCHALT+TAB</strong>.</p>\n' +
'\n' +
'<p>Die Abschnitte der Benutzeroberfläche haben folgende <strong>TAB</strong>-Reihenfolge:</p>\n' +
'\n' +
'<ol>\n' +
' <li>Menüleiste</li>\n' +
' <li>Einzelne Gruppen der Symbolleiste</li>\n' +
' <li>Randleiste</li>\n' +
' <li>Elementpfad in der Fußzeile</li>\n' +
' <li>Umschaltfläche „Wörter zählen“ in der Fußzeile</li>\n' +
' <li>Branding-Link in der Fußzeile</li>\n' +
' <li>Editor-Ziehpunkt zur Größenänderung in der Fußzeile</li>\n' +
'</ol>\n' +
'\n' +
'<p>Falls ein Abschnitt der Benutzeroberflächen nicht vorhanden ist, wird er übersprungen.</p>\n' +
'\n' +
'<p>Wenn in der Fußzeile die Tastaturnavigation fokussiert ist und keine Randleiste angezeigt wird, wechselt der Fokus durch Drücken von <strong>UMSCHALT+TAB</strong>\n' +
' zur ersten Gruppe der Symbolleiste, nicht zur letzten.</p>\n' +
'\n' +
'<h1>Innerhalb von Abschnitten der Benutzeroberfläche navigieren</h1>\n' +
'\n' +
'<p>Um von einem Element der Benutzeroberfläche zum nächsten zu wechseln, drücken Sie die entsprechende <strong>Pfeiltaste</strong>.</p>\n' +
'\n' +
'<p>Die Pfeiltasten <strong>Links</strong> und <strong>Rechts</strong></p>\n' +
'\n' +
'<ul>\n' +
' <li>wechseln zwischen Menüs in der Menüleiste.</li>\n' +
' <li>öffnen das Untermenü eines Menüs.</li>\n' +
' <li>wechseln zwischen Schaltflächen in einer Gruppe der Symbolleiste.</li>\n' +
' <li>wechseln zwischen Elementen im Elementpfad der Fußzeile.</li>\n' +
'</ul>\n' +
'\n' +
'<p>Die Pfeiltasten <strong>Abwärts</strong> und <strong>Aufwärts</strong></p>\n' +
'\n' +
'<ul>\n' +
' <li>wechseln zwischen Menüelementen in einem Menü.</li>\n' +
' <li>wechseln zwischen Elementen in einem Popupmenü der Symbolleiste.</li>\n' +
'</ul>\n' +
'\n' +
'<p>Die <strong>Pfeiltasten</strong> rotieren innerhalb des fokussierten Abschnitts der Benutzeroberfläche.</p>\n' +
'\n' +
'<p>Um ein geöffnetes Menü, ein geöffnetes Untermenü oder ein geöffnetes Popupmenü zu schließen, drücken Sie die <strong>ESC</strong>-Taste.</p>\n' +
'\n' +
'<p>Wenn sich der aktuelle Fokus ganz oben in einem bestimmten Abschnitt der Benutzeroberfläche befindet, wird durch Drücken der <strong>ESC</strong>-Taste auch\n' +
' die Tastaturnavigation beendet.</p>\n' +
'\n' +
'<h1>Ein Menüelement oder eine Symbolleistenschaltfläche ausführen</h1>\n' +
'\n' +
'<p>Wenn das gewünschte Menüelement oder die gewünschte Symbolleistenschaltfläche hervorgehoben ist, drücken Sie <strong>Zurück</strong>, <strong>Eingabe</strong>\n' +
' oder die <strong>Leertaste</strong>, um das Element auszuführen.</p>\n' +
'\n' +
'<h1>In Dialogfeldern ohne Registerkarten navigieren</h1>\n' +
'\n' +
'<p>In Dialogfeldern ohne Registerkarten ist beim Öffnen eines Dialogfelds die erste interaktive Komponente fokussiert.</p>\n' +
'\n' +
'<p>Navigieren Sie zwischen den interaktiven Komponenten eines Dialogfelds, indem Sie <strong>TAB</strong> oder <strong>UMSCHALT+TAB</strong> drücken.</p>\n' +
'\n' +
'<h1>In Dialogfeldern mit Registerkarten navigieren</h1>\n' +
'\n' +
'<p>In Dialogfeldern mit Registerkarten ist beim Öffnen eines Dialogfelds die erste Schaltfläche eines Registerkartenmenüs fokussiert.</p>\n' +
'\n' +
'<p>Navigieren Sie zwischen den interaktiven Komponenten auf dieser Registerkarte des Dialogfelds, indem Sie <strong>TAB</strong> oder\n' +
' <strong>UMSCHALT+TAB</strong> drücken.</p>\n' +
'\n' +
'<p>Wechseln Sie zu einer anderen Registerkarte des Dialogfelds, indem Sie den Fokus auf das Registerkartenmenü legen und dann die entsprechende <strong>Pfeiltaste</strong>\n' +
' drücken, um durch die verfügbaren Registerkarten zu rotieren.</p>\n');

View File

@@ -0,0 +1,93 @@
tinymce.Resource.add('tinymce.html-i18n.help-keynav.el',
'<h1>Έναρξη πλοήγησης μέσω πληκτρολογίου</h1>\n' +
'\n' +
'<dl>\n' +
' <dt>Εστίαση στη γραμμή μενού</dt>\n' +
' <dd>Windows ή Linux: Alt+F9</dd>\n' +
' <dd>macOS: &#x2325;F9</dd>\n' +
' <dt>Εστίαση στη γραμμή εργαλείων</dt>\n' +
' <dd>Windows ή Linux: Alt+F10</dd>\n' +
' <dd>macOS: &#x2325;F10</dd>\n' +
' <dt>Εστίαση στο υποσέλιδο</dt>\n' +
' <dd>Windows ή Linux: Alt+F11</dd>\n' +
' <dd>macOS: &#x2325;F11</dd>\n' +
' <dt>Εστίαση στην ειδοποίηση</dt>\n' +
' <dd>Windows ή Linux: Alt+F12</dd>\n' +
' <dd>macOS: &#x2325;F12</dd>\n' +
' <dt>Εστίαση σε γραμμή εργαλείων βάσει περιεχομένου</dt>\n' +
' <dd>Windows, Linux ή macOS: Ctrl+F9</dd>\n' +
'</dl>\n' +
'\n' +
'<p>Η πλοήγηση θα ξεκινήσει από το πρώτο στοιχείο περιβάλλοντος χρήστη, που θα επισημαίνεται ή θα είναι υπογραμμισμένο,\n' +
' όπως στην περίπτωση της διαδρομής του στοιχείου Υποσέλιδου.</p>\n' +
'\n' +
'<h1>Πλοήγηση μεταξύ ενοτήτων του περιβάλλοντος χρήστη</h1>\n' +
'\n' +
'<p>Για να μετακινηθείτε από μια ενότητα περιβάλλοντος χρήστη στην επόμενη, πιέστε το πλήκτρο <strong>Tab</strong>.</p>\n' +
'\n' +
'<p>Για να μετακινηθείτε από μια ενότητα περιβάλλοντος χρήστη στην προηγούμενη, πιέστε τα πλήκτρα <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<p>Η σειρά <strong>Tab</strong> αυτών των ενοτήτων περιβάλλοντος χρήστη είναι η εξής:</p>\n' +
'\n' +
'<ol>\n' +
' <li>Γραμμή μενού</li>\n' +
' <li>Κάθε ομάδα γραμμής εργαλείων</li>\n' +
' <li>Πλαϊνή γραμμή</li>\n' +
' <li>Διαδρομή στοιχείου στο υποσέλιδο</li>\n' +
' <li>Κουμπί εναλλαγής μέτρησης λέξεων στο υποσέλιδο</li>\n' +
' <li>Σύνδεσμος επωνυμίας στο υποσέλιδο</li>\n' +
' <li>Λαβή αλλαγής μεγέθους προγράμματος επεξεργασίας στο υποσέλιδο</li>\n' +
'</ol>\n' +
'\n' +
'<p>Εάν δεν εμφανίζεται ενότητα περιβάλλοντος χρήστη, παραλείπεται.</p>\n' +
'\n' +
'<p>Εάν η εστίαση πλοήγησης βρίσκεται στο πληκτρολόγιο και δεν υπάρχει εμφανής πλαϊνή γραμμή, εάν πιέσετε <strong>Shift+Tab</strong>\n' +
' η εστίαση μετακινείται στην πρώτη ομάδα γραμμής εργαλείων, όχι στην τελευταία.</p>\n' +
'\n' +
'<h1>Πλοήγηση εντός των ενοτήτων του περιβάλλοντος χρήστη</h1>\n' +
'\n' +
'<p>Για να μετακινηθείτε από ένα στοιχείο περιβάλλοντος χρήστη στο επόμενο, πιέστε το αντίστοιχο πλήκτρο <strong>βέλους</strong>.</p>\n' +
'\n' +
'<p>Με τα πλήκτρα <strong>αριστερού</strong> και <strong>δεξιού</strong> βέλους</p>\n' +
'\n' +
'<ul>\n' +
' <li>γίνεται μετακίνηση μεταξύ των μενού στη γραμμή μενού.</li>\n' +
' <li>ανοίγει ένα υπομενού σε ένα μενού.</li>\n' +
' <li>γίνεται μετακίνηση μεταξύ κουμπιών σε μια ομάδα γραμμής εργαλείων.</li>\n' +
' <li>γίνεται μετακίνηση μεταξύ στοιχείων στη διαδρομή στοιχείου στο υποσέλιδο.</li>\n' +
'</ul>\n' +
'\n' +
'<p>Με τα πλήκτρα <strong>επάνω</strong> και <strong>κάτω</strong> βέλους</p>\n' +
'\n' +
'<ul>\n' +
' <li>γίνεται μετακίνηση μεταξύ των στοιχείων μενού σε ένα μενού.</li>\n' +
' <li>γίνεται μετακίνηση μεταξύ των στοιχείων μενού σε ένα αναδυόμενο μενού γραμμής εργαλείων.</li>\n' +
'</ul>\n' +
'\n' +
'<p>Με τα πλήκτρα <strong>βέλους</strong> γίνεται κυκλική μετακίνηση εντός της εστιασμένης ενότητας περιβάλλοντος χρήστη.</p>\n' +
'\n' +
'<p>Για να κλείσετε ένα ανοιχτό μενού, ένα ανοιχτό υπομενού ή ένα ανοιχτό αναδυόμενο μενού, πιέστε το πλήκτρο <strong>Esc</strong>.</p>\n' +
'\n' +
'<p>Εάν η τρέχουσα εστίαση βρίσκεται στην κορυφή μιας ενότητας περιβάλλοντος χρήστη, πιέζοντας το πλήκτρο <strong>Esc</strong>,\n' +
' γίνεται επίσης πλήρης έξοδος από την πλοήγηση μέσω πληκτρολογίου.</p>\n' +
'\n' +
'<h1>Εκτέλεση ενός στοιχείου μενού ή κουμπιού γραμμής εργαλείων</h1>\n' +
'\n' +
'<p>Όταν το επιθυμητό στοιχείο μενού ή κουμπί γραμμής εργαλείων είναι επισημασμένο, πιέστε τα πλήκτρα <strong>Return</strong>, <strong>Enter</strong>,\n' +
' ή το <strong>πλήκτρο διαστήματος</strong> για να εκτελέσετε το στοιχείο.</p>\n' +
'\n' +
'<h1>Πλοήγηση σε παράθυρα διαλόγου χωρίς καρτέλες</h1>\n' +
'\n' +
'<p>Σε παράθυρα διαλόγου χωρίς καρτέλες, το πρώτο αλληλεπιδραστικό στοιχείο λαμβάνει την εστίαση όταν ανοίγει το παράθυρο διαλόγου.</p>\n' +
'\n' +
'<p>Μπορείτε να πλοηγηθείτε μεταξύ των αλληλεπιδραστικών στοιχείων παραθύρων διαλόγων πιέζοντας τα πλήκτρα <strong>Tab</strong> ή <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<h1>Πλοήγηση σε παράθυρα διαλόγου με καρτέλες</h1>\n' +
'\n' +
'<p>Σε παράθυρα διαλόγου με καρτέλες, το πρώτο κουμπί στο μενού καρτέλας λαμβάνει την εστίαση όταν ανοίγει το παράθυρο διαλόγου.</p>\n' +
'\n' +
'<p>Μπορείτε να πλοηγηθείτε μεταξύ των αλληλεπιδραστικών στοιχείων αυτής της καρτέλα διαλόγου πιέζοντας τα πλήκτρα <strong>Tab</strong> ή\n' +
' <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<p>Μπορείτε να κάνετε εναλλαγή σε άλλη καρτέλα του παραθύρου διαλόγου, μεταφέροντας την εστίαση στο μενού καρτέλας και πιέζοντας το κατάλληλο πλήκτρο <strong>βέλους</strong>\n' +
' για να μετακινηθείτε κυκλικά στις διαθέσιμες καρτέλες.</p>\n');

View File

@@ -0,0 +1,93 @@
tinymce.Resource.add('tinymce.html-i18n.help-keynav.en',
'<h1>Begin keyboard navigation</h1>\n' +
'\n' +
'<dl>\n' +
' <dt>Focus the Menu bar</dt>\n' +
' <dd>Windows or Linux: Alt+F9</dd>\n' +
' <dd>macOS: &#x2325;F9</dd>\n' +
' <dt>Focus the Toolbar</dt>\n' +
' <dd>Windows or Linux: Alt+F10</dd>\n' +
' <dd>macOS: &#x2325;F10</dd>\n' +
' <dt>Focus the footer</dt>\n' +
' <dd>Windows or Linux: Alt+F11</dd>\n' +
' <dd>macOS: &#x2325;F11</dd>\n' +
' <dt>Focus the notification</dt>\n' +
' <dd>Windows or Linux: Alt+F12</dd>\n' +
' <dd>macOS: &#x2325;F12</dd>\n' +
' <dt>Focus a contextual toolbar</dt>\n' +
' <dd>Windows, Linux or macOS: Ctrl+F9</dd>\n' +
'</dl>\n' +
'\n' +
'<p>Navigation will start at the first UI item, which will be highlighted, or underlined in the case of the first item in\n' +
' the Footer element path.</p>\n' +
'\n' +
'<h1>Navigate between UI sections</h1>\n' +
'\n' +
'<p>To move from one UI section to the next, press <strong>Tab</strong>.</p>\n' +
'\n' +
'<p>To move from one UI section to the previous, press <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<p>The <strong>Tab</strong> order of these UI sections is:</p>\n' +
'\n' +
'<ol>\n' +
' <li>Menu bar</li>\n' +
' <li>Each toolbar group</li>\n' +
' <li>Sidebar</li>\n' +
' <li>Element path in the footer</li>\n' +
' <li>Word count toggle button in the footer</li>\n' +
' <li>Branding link in the footer</li>\n' +
' <li>Editor resize handle in the footer</li>\n' +
'</ol>\n' +
'\n' +
'<p>If a UI section is not present, it is skipped.</p>\n' +
'\n' +
'<p>If the footer has keyboard navigation focus, and there is no visible sidebar, pressing <strong>Shift+Tab</strong>\n' +
' moves focus to the first toolbar group, not the last.</p>\n' +
'\n' +
'<h1>Navigate within UI sections</h1>\n' +
'\n' +
'<p>To move from one UI element to the next, press the appropriate <strong>Arrow</strong> key.</p>\n' +
'\n' +
'<p>The <strong>Left</strong> and <strong>Right</strong> arrow keys</p>\n' +
'\n' +
'<ul>\n' +
' <li>move between menus in the menu bar.</li>\n' +
' <li>open a sub-menu in a menu.</li>\n' +
' <li>move between buttons in a toolbar group.</li>\n' +
' <li>move between items in the footers element path.</li>\n' +
'</ul>\n' +
'\n' +
'<p>The <strong>Down</strong> and <strong>Up</strong> arrow keys</p>\n' +
'\n' +
'<ul>\n' +
' <li>move between menu items in a menu.</li>\n' +
' <li>move between items in a toolbar pop-up menu.</li>\n' +
'</ul>\n' +
'\n' +
'<p><strong>Arrow</strong> keys cycle within the focused UI section.</p>\n' +
'\n' +
'<p>To close an open menu, an open sub-menu, or an open pop-up menu, press the <strong>Esc</strong> key.</p>\n' +
'\n' +
'<p>If the current focus is at the top of a particular UI section, pressing the <strong>Esc</strong> key also exits\n' +
' keyboard navigation entirely.</p>\n' +
'\n' +
'<h1>Execute a menu item or toolbar button</h1>\n' +
'\n' +
'<p>When the desired menu item or toolbar button is highlighted, press <strong>Return</strong>, <strong>Enter</strong>,\n' +
' or the <strong>Space bar</strong> to execute the item.</p>\n' +
'\n' +
'<h1>Navigate non-tabbed dialogs</h1>\n' +
'\n' +
'<p>In non-tabbed dialogs, the first interactive component takes focus when the dialog opens.</p>\n' +
'\n' +
'<p>Navigate between interactive dialog components by pressing <strong>Tab</strong> or <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<h1>Navigate tabbed dialogs</h1>\n' +
'\n' +
'<p>In tabbed dialogs, the first button in the tab menu takes focus when the dialog opens.</p>\n' +
'\n' +
'<p>Navigate between interactive components of this dialog tab by pressing <strong>Tab</strong> or\n' +
' <strong>Shift+Tab</strong>.</p>\n' +
'\n' +
'<p>Switch to another dialog tab by giving the tab menu focus and then pressing the appropriate <strong>Arrow</strong>\n' +
' key to cycle through the available tabs.</p>\n');

View File

@@ -0,0 +1,93 @@
tinymce.Resource.add('tinymce.html-i18n.help-keynav.es',
'<h1>Iniciar la navegación con el teclado</h1>\n' +
'\n' +
'<dl>\n' +
' <dt>Enfocar la barra de menús</dt>\n' +
' <dd>Windows o Linux: Alt+F9</dd>\n' +
' <dd>macOS: &#x2325;F9</dd>\n' +
' <dt>Enfocar la barra de herramientas</dt>\n' +
' <dd>Windows o Linux: Alt+F10</dd>\n' +
' <dd>macOS: &#x2325;F10</dd>\n' +
' <dt>Enfocar el pie de página</dt>\n' +
' <dd>Windows o Linux: Alt+F11</dd>\n' +
' <dd>macOS: &#x2325;F11</dd>\n' +
' <dt>Enfocar la notificación</dt>\n' +
' <dd>Windows o Linux: Alt+F12</dd>\n' +
' <dd>macOS: &#x2325;F12</dd>\n' +
' <dt>Enfocar una barra de herramientas contextual</dt>\n' +
' <dd>Windows, Linux o macOS: Ctrl+F9</dd>\n' +
'</dl>\n' +
'\n' +
'<p>La navegación comenzará por el primer elemento de la interfaz de usuario (IU), de tal manera que se resaltará, o bien se subrayará si se trata del primer elemento de\n' +
' la ruta de elemento del pie de página.</p>\n' +
'\n' +
'<h1>Navegar entre las secciones de la IU</h1>\n' +
'\n' +
'<p>Para pasar de una sección de la IU a la siguiente, pulse la tecla <strong>Tab</strong>.</p>\n' +
'\n' +
'<p>Para pasar de una sección de la IU a la anterior, pulse <strong>Mayús+Tab</strong>.</p>\n' +
'\n' +
'<p>El orden de <strong>tabulación</strong> de estas secciones de la IU es:</p>\n' +
'\n' +
'<ol>\n' +
' <li>Barra de menús</li>\n' +
' <li>Cada grupo de barra de herramientas</li>\n' +
' <li>Barra lateral</li>\n' +
' <li>Ruta del elemento en el pie de página</li>\n' +
' <li>Botón de alternancia de recuento de palabras en el pie de página</li>\n' +
' <li>Enlace de personalización de marca en el pie de página</li>\n' +
' <li>Controlador de cambio de tamaño en el pie de página</li>\n' +
'</ol>\n' +
'\n' +
'<p>Si una sección de la IU no está presente, esta se omite.</p>\n' +
'\n' +
'<p>Si el pie de página tiene un enfoque de navegación con el teclado y no hay ninguna barra lateral visible, al pulsar <strong>Mayús+Tab</strong>,\n' +
' el enfoque se moverá al primer grupo de barra de herramientas, en lugar de al último.</p>\n' +
'\n' +
'<h1>Navegar dentro de las secciones de la IU</h1>\n' +
'\n' +
'<p>Para pasar de un elemento de la IU al siguiente, pulse la tecla de <strong>flecha</strong> correspondiente.</p>\n' +
'\n' +
'<p>Las teclas de flecha <strong>izquierda</strong> y <strong>derecha</strong> permiten</p>\n' +
'\n' +
'<ul>\n' +
' <li>desplazarse entre los menús de la barra de menús.</li>\n' +
' <li>abrir el submenú de un menú.</li>\n' +
' <li>desplazarse entre los botones de un grupo de barra de herramientas.</li>\n' +
' <li>desplazarse entre los elementos de la ruta de elemento del pie de página.</li>\n' +
'</ul>\n' +
'\n' +
'<p>Las teclas de flecha <strong>abajo</strong> y <strong>arriba</strong> permiten</p>\n' +
'\n' +
'<ul>\n' +
' <li>desplazarse entre los elementos de menú de un menú.</li>\n' +
' <li>desplazarse entre los elementos de un menú emergente de una barra de herramientas.</li>\n' +
'</ul>\n' +
'\n' +
'<p>Las teclas de <strong>flecha</strong> van cambiando dentro de la sección de la IU enfocada.</p>\n' +
'\n' +
'<p>Para cerrar un menú, un submenú o un menú emergente que estén abiertos, pulse la tecla <strong>Esc</strong>.</p>\n' +
'\n' +
'<p>Si el enfoque actual se encuentra en la parte superior de una sección de la IU determinada, al pulsar la tecla <strong>Esc</strong> saldrá\n' +
' de la navegación con el teclado por completo.</p>\n' +
'\n' +
'<h1>Ejecutar un elemento de menú o un botón de barra de herramientas</h1>\n' +
'\n' +
'<p>Si el elemento de menú o el botón de barra de herramientas deseado está resaltado, pulse la tecla <strong>Retorno</strong> o <strong>Entrar</strong>,\n' +
' o la <strong>barra espaciadora</strong> para ejecutar el elemento.</p>\n' +
'\n' +
'<h1>Navegar por cuadros de diálogo sin pestañas</h1>\n' +
'\n' +
'<p>En los cuadros de diálogo sin pestañas, el primer componente interactivo se enfoca al abrirse el cuadro de diálogo.</p>\n' +
'\n' +
'<p>Para navegar entre los componentes interactivos del cuadro de diálogo, pulse las teclas <strong>Tab</strong> o <strong>Mayús+Tab</strong>.</p>\n' +
'\n' +
'<h1>Navegar por cuadros de diálogo con pestañas</h1>\n' +
'\n' +
'<p>En los cuadros de diálogo con pestañas, el primer botón del menú de pestaña se enfoca al abrirse el cuadro de diálogo.</p>\n' +
'\n' +
'<p>Para navegar entre componentes interactivos de esta pestaña del cuadro de diálogo, pulse las teclas <strong>Tab</strong> o\n' +
' <strong>Mayús+Tab</strong>.</p>\n' +
'\n' +
'<p>Si desea cambiar a otra pestaña del cuadro de diálogo, enfoque el menú de pestañas y, a continuación, pulse la tecla de <strong>flecha</strong>\n' +
' correspondiente para moverse por las pestañas disponibles.</p>\n');

View File

@@ -0,0 +1,93 @@
tinymce.Resource.add('tinymce.html-i18n.help-keynav.eu',
'<h1>Hasi teklatuaren nabigazioa</h1>\n' +
'\n' +
'<dl>\n' +
' <dt>Fokuratu menu-barra</dt>\n' +
' <dd>Windows edo Linux: Alt+F9</dd>\n' +
' <dd>macOS: &#x2325;F9</dd>\n' +
' <dt>Fokuratu tresna-barra</dt>\n' +
' <dd>Windows edo Linux: Alt+F10</dd>\n' +
' <dd>macOS: &#x2325;F10</dd>\n' +
' <dt>Fokuratu orri-oina</dt>\n' +
' <dd>Windows edo Linux: Alt+F11</dd>\n' +
' <dd>macOS: &#x2325;F11</dd>\n' +
' <dt>Fokuratu jakinarazpena</dt>\n' +
' <dd>Windows edo Linux: Alt+F12</dd>\n' +
' <dd>macOS: &#x2325;F12</dd>\n' +
' <dt>Fokuratu testuinguruaren tresna-barra</dt>\n' +
' <dd>Windows, Linux edo macOS: Ktrl+F9</dd>\n' +
'</dl>\n' +
'\n' +
'<p>Nabigazioa EIko lehen elementuan hasiko da: elementu hori nabarmendu egingo da, edo azpimarratu lehen elementua bada\n' +
' orri-oineko elementuaren bidea.</p>\n' +
'\n' +
'<h1>Nabigatu EIko atalen artean</h1>\n' +
'\n' +
'<p>EIko atal batetik hurrengora mugitzeko, sakatu <strong>Tabuladorea</strong>.</p>\n' +
'\n' +
'<p>EIko atal batetik aurrekora mugitzeko, sakatu <strong>Maius+Tabuladorea</strong>.</p>\n' +
'\n' +
'<p>EIko atal hauen <strong>Tabuladorea</strong> da:</p>\n' +
'\n' +
'<ol>\n' +
' <li>Menu-barra</li>\n' +
' <li>Tresna-barraren talde bakoitza</li>\n' +
' <li>Alboko barra</li>\n' +
' <li>Orri-oineko elementuaren bidea</li>\n' +
' <li>Orri-oneko urrats-kontaketa txandakatzeko botoia</li>\n' +
' <li>Orri-oineko marken esteka</li>\n' +
' <li>Orri-oineko editorearen tamaina aldatzeko heldulekua</li>\n' +
'</ol>\n' +
'\n' +
'<p>EIko atal bat ez badago, saltatu egin da.</p>\n' +
'\n' +
'<p>Orri-oinak teklatuaren nabigazioa fokuratuta badago, eta alboko barra ikusgai ez badago, <strong>Maius+Tabuladorea</strong> sakatuz gero,\n' +
' fokua tresna-barrako lehen taldera eramaten da, ez azkenera.</p>\n' +
'\n' +
'<h1>Nabigatu EIko atalen barruan</h1>\n' +
'\n' +
'<p>EIko elementu batetik hurrengora mugitzeko, sakatu dagokion <strong>Gezia</strong> tekla.</p>\n' +
'\n' +
'<p><strong>Ezkerrera</strong> eta <strong>Eskuinera</strong> gezi-teklak</p>\n' +
'\n' +
'<ul>\n' +
' <li>menu-barrako menuen artean mugitzen da.</li>\n' +
' <li>ireki azpimenu bat menuan.</li>\n' +
' <li>mugitu botoi batetik bestera tresna-barren talde batean.</li>\n' +
' <li>mugitu orri-oineko elementuaren bideko elementu batetik bestera.</li>\n' +
'</ul>\n' +
'\n' +
'<p><strong>Gora</strong> eta <strong>Behera</strong> gezi-teklak</p>\n' +
'\n' +
'<ul>\n' +
' <li>mugitu menu bateko menu-elementuen artean.</li>\n' +
' <li>mugitu tresna-barrako menu gainerakor bateko menu-elementuen artean.</li>\n' +
'</ul>\n' +
'\n' +
'<p><strong>Gezia</strong> teklen zikloa nabarmendutako EI atalen barruan.</p>\n' +
'\n' +
'<p>Irekitako menu bat ixteko, ireki azpimenua, edo ireki menu gainerakorra, sakatu <strong>Ihes</strong> tekla.</p>\n' +
'\n' +
'<p>Une horretan fokuratzea EIko atal jakin baten "goialdean" badago, <strong>Ihes</strong> tekla sakatuz gero\n' +
' teklatuaren nabigaziotik irtengo zara.</p>\n' +
'\n' +
'<h1>Exekutatu menuko elementu bat edo tresna-barrako botoi bat</h1>\n' +
'\n' +
'<p>Nahi den menuaren elementua edo tresna-barraren botoia nabarmenduta dagoenean, sakatu <strong>Itzuli</strong>, <strong>Sartu</strong>\n' +
' edo <strong>Zuriune-barra</strong> elementua exekutatzeko.</p>\n' +
'\n' +
'<h1>Nabigatu fitxarik gabeko elkarrizketak</h1>\n' +
'\n' +
'<p>Fitxarik gabeko elkarrizketetan, lehen osagai interaktiboa fokuratzen da elkarrizketa irekitzen denean.</p>\n' +
'\n' +
'<p>Nabigatu elkarrizketa interaktiboko osagai batetik bestera <strong>Tabuladorea</strong> edo <strong>Maius+Tabuladorea</strong> sakatuta.</p>\n' +
'\n' +
'<h1>Nabigatu fitxadun elkarrizketak</h1>\n' +
'\n' +
'<p>Fitxadun elkarrizketetan, fitxa-menuko lehen botoia fokuratzen da elkarrizketa irekitzen denean.</p>\n' +
'\n' +
'<p>Nabigatu elkarrizketa-fitxa honen interaktiboko osagai batetik bestera <strong>Tabuladorea</strong> edo\n' +
' <strong>Maius+Tabuladorea</strong> sakatuta.</p>\n' +
'\n' +
'<p>Aldatu beste elkarrizketa-fitxa batera fitxa-menua fokuratu eta dagokion <strong>Gezia</strong>\n' +
' tekla sakatzeko, erabilgarri dauden fitxa batetik bestera txandakatzeko.</p>\n');

View File

@@ -0,0 +1,93 @@
tinymce.Resource.add('tinymce.html-i18n.help-keynav.fa',
'<h1>شروع پیمایش صفحه‌کلید</h1>\n' +
'\n' +
'<dl>\n' +
' <dt>تمرکز بر نوار منو</dt>\n' +
' <dd>Windows یا Linux:: Alt+F9</dd>\n' +
' <dd>macOS: &#x2325;F9</dd>\n' +
' <dt>تمرکز بر نوار ابزار</dt>\n' +
' <dd>Windows یا Linux: Alt+F10</dd>\n' +
' <dd>macOS: &#x2325;F10</dd>\n' +
' <dt>تمرکز بر پانویس</dt>\n' +
' <dd>Windows یا Linux: Alt+F11</dd>\n' +
' <dd>macOS: &#x2325;F11</dd>\n' +
' <dt>تمرکز اعلان</dt>\n' +
' <dd>ویندوز یا لینوکس: Alt+F12</dd>\n' +
' <dd>macOS: &#x2325;F12</dd>\n' +
' <dt>تمرکز بر نوار ابزار بافتاری</dt>\n' +
' <dd>Windows ،Linux یا macOS: Ctrl+F9</dd>\n' +
'</dl>\n' +
'\n' +
'<p>پیمایش در اولین مورد رابط کاربری شروع می‌شود و درخصوص اولین مورد در\n' +
' مسیر عنصر پانویس، برجسته یا زیرخط‌دار می‌شود.</p>\n' +
'\n' +
'<h1>پیمایش بین بخش‌های رابط کاربری</h1>\n' +
'\n' +
'<p>برای جابجایی از یک بخش رابط کاربری به بخش بعدی، <strong>Tab</strong> را فشار دهید.</p>\n' +
'\n' +
'<p>برای جابجایی از یک بخش رابط کاربری به بخش قبلی، <strong>Shift+Tab</strong> را فشار دهید.</p>\n' +
'\n' +
'<p>ترتیب <strong>Tab</strong> این بخش‌های رابط کاربری عبارتند از:</p>\n' +
'\n' +
'<ol>\n' +
' <li>نوار منو</li>\n' +
' <li>هر گروه نوار ابزار</li>\n' +
' <li>نوار کناری</li>\n' +
' <li>مسیر عنصر در پانویس</li>\n' +
' <li>دکمه تغییر وضعیت تعداد کلمات در پانویس</li>\n' +
' <li>پیوند نمانام‌سازی در پانویس</li>\n' +
' <li>دسته تغییر اندازه ویرایشگر در پانویس</li>\n' +
'</ol>\n' +
'\n' +
'<p>اگر بخشی از رابط کاربری موجود نباشد، رد می‌شود.</p>\n' +
'\n' +
'<p>اگر پانویس دارای تمرکز بر پیمایش صفحه‌کلید باشد،‌ و نوار کناری قابل‌مشاهده وجود ندارد، فشردن <strong>Shift+Tab</strong>\n' +
' تمرکز را به گروه نوار ابزار اول می‌برد، نه آخر.</p>\n' +
'\n' +
'<h1>پیمایش در بخش‌های رابط کاربری</h1>\n' +
'\n' +
'<p>برای جابجایی از یک عنصر رابط کاربری به بعدی، کلید <strong>جهت‌نمای</strong> مناسب را فشار دهید.</p>\n' +
'\n' +
'<p>کلیدهای جهت‌نمای <strong>چپ</strong> و <strong>راست</strong></p>\n' +
'\n' +
'<ul>\n' +
' <li>جابجایی بین منوها در نوار منو.</li>\n' +
' <li>باز کردن منوی فرعی در یک منو.</li>\n' +
' <li>جابجایی بین دکمه‌ها در یک گروه نوار ابزار.</li>\n' +
' <li>جابجایی بین موارد در مسیر عنصر پانویس.</li>\n' +
'</ul>\n' +
'\n' +
'<p>کلیدهای جهت‌نمای <strong>پایین</strong> و <strong>بالا</strong></p>\n' +
'\n' +
'<ul>\n' +
' <li>جابجایی بین موارد منو در یک منو.</li>\n' +
' <li>جابجایی بین موارد در یک منوی بازشوی نوار ابزار.</li>\n' +
'</ul>\n' +
'\n' +
'<p>کلیدهای<strong>جهت‌نما</strong> در بخش رابط کاربری متمرکز می‌چرخند.</p>\n' +
'\n' +
'<p>برای بستن یک منوی باز، یک منوی فرعی باز، یا یک منوی بازشوی باز، کلید <strong>Esc</strong> را فشار دهید.</p>\n' +
'\n' +
'<p>اگر تمرکز فعلی در «بالای» یک بخش رابط کاربری خاص است، فشردن کلید <strong>Esc</strong> نیز موجب\n' +
' خروج کامل از پیمایش صفحه‌کلید می‌شود.</p>\n' +
'\n' +
'<h1>اجرای یک مورد منو یا دکمه نوار ابزار</h1>\n' +
'\n' +
'<p>وقتی مورد منو یا دکمه نوار ابزار مورد نظر هایلایت شد، دکمه <strong>بازگشت</strong>، <strong>Enter</strong>،\n' +
' یا <strong>نوار Space</strong> را فشار دهید تا مورد را اجرا کنید.</p>\n' +
'\n' +
'<h1>پیمایش در کادرهای گفتگوی بدون زبانه</h1>\n' +
'\n' +
'<p>در کادرهای گفتگوی بدون زبانه، وقتی کادر گفتگو باز می‌شود، اولین جزء تعاملی متمرکز می‌شود.</p>\n' +
'\n' +
'<p>با فشردن <strong>Tab</strong> یا <strong>Shift+Tab</strong>، بین اجزای کادر گفتگوی تعاملی پیمایش کنید.</p>\n' +
'\n' +
'<h1>پیمایش کادرهای گفتگوی زبانه‌دار</h1>\n' +
'\n' +
'<p>در کادرهای گفتگوی زبانه‌دار، وقتی کادر گفتگو باز می‌شود، اولین دکمه در منوی زبانه متمرکز می‌شود.</p>\n' +
'\n' +
'<p>با فشردن <strong>Tab</strong> یا\n' +
' <strong>Shift+Tab</strong>، بین اجزای تعاملی این زبانه کادر گفتگو پیمایش کنید.</p>\n' +
'\n' +
'<p>با دادن تمرکز به منوی زبانه و سپس فشار دادن کلید <strong>جهت‌نمای</strong>\n' +
' مناسب برای چرخش میان زبانه‌های موجود، به زبانه کادر گفتگوی دیگری بروید.</p>\n');

View File

@@ -0,0 +1,93 @@
tinymce.Resource.add('tinymce.html-i18n.help-keynav.fi',
'<h1>Näppäimistönavigoinnin aloittaminen</h1>\n' +
'\n' +
'<dl>\n' +
' <dt>Siirrä kohdistus valikkopalkkiin</dt>\n' +
' <dd>Windows tai Linux: Alt+F9</dd>\n' +
' <dd>macOS: &#x2325;F9</dd>\n' +
' <dt>Siirrä kohdistus työkalupalkkiin</dt>\n' +
' <dd>Windows tai Linux: Alt+F10</dd>\n' +
' <dd>macOS: &#x2325;F10</dd>\n' +
' <dt>Siirrä kohdistus alatunnisteeseen</dt>\n' +
' <dd>Windows tai Linux: Alt+F11</dd>\n' +
' <dd>macOS: &#x2325;F11</dd>\n' +
' <dt>Keskitä ilmoitukseen</dt>\n' +
' <dd>Windows ja Linux: Alt + F12</dd>\n' +
' <dd>macOS: &#x2325;F12</dd>\n' +
' <dt>Siirrä kohdistus kontekstuaaliseen työkalupalkkiin</dt>\n' +
' <dd>Windows, Linux tai macOS: Ctrl+F9</dd>\n' +
'</dl>\n' +
'\n' +
'<p>Navigointi aloitetaan ensimmäisestä käyttöliittymän kohteesta, joka joko korostetaan tai alleviivataan, jos\n' +
' kyseessä on Alatunniste-elementin polun ensimmäinen kohde.</p>\n' +
'\n' +
'<h1>Käyttöliittymän eri osien välillä navigointi</h1>\n' +
'\n' +
'<p>Paina <strong>sarkainnäppäintä</strong> siirtyäksesi käyttöliittymän osasta seuraavaan.</p>\n' +
'\n' +
'<p>Jos haluat siirtyä edelliseen käyttöliittymän osaan, paina <strong>Shift+sarkainnäppäin</strong>.</p>\n' +
'\n' +
'<p><strong>Sarkainnäppäin</strong> siirtää sinua näissä käyttöliittymän osissa tässä järjestyksessä:</p>\n' +
'\n' +
'<ol>\n' +
' <li>Valikkopalkki</li>\n' +
' <li>Työkalupalkin ryhmät</li>\n' +
' <li>Sivupalkki</li>\n' +
' <li>Elementin polku alatunnisteessa</li>\n' +
' <li>Sanalaskurin vaihtopainike alatunnisteessa</li>\n' +
' <li>Brändäyslinkki alatunnisteessa</li>\n' +
' <li>Editorin koon muuttamisen kahva alatunnisteessa</li>\n' +
'</ol>\n' +
'\n' +
'<p>Jos jotakin käyttöliittymän osaa ei ole, se ohitetaan.</p>\n' +
'\n' +
'<p>Jos kohdistus on siirretty alatunnisteeseen näppäimistönavigoinnilla eikä sivupalkkia ole näkyvissä, <strong>Shift+sarkainnäppäin</strong>\n' +
' siirtää kohdistuksen työkalupalkin ensimmäiseen ryhmään, eikä viimeiseen.</p>\n' +
'\n' +
'<h1>Käyttöliittymän eri osien sisällä navigointi</h1>\n' +
'\n' +
'<p>Paina <strong>nuolinäppäimiä</strong> siirtyäksesi käyttöliittymäelementistä seuraavaan.</p>\n' +
'\n' +
'<p><strong>Vasen</strong>- ja <strong>Oikea</strong>-nuolinäppäimet</p>\n' +
'\n' +
'<ul>\n' +
' <li>siirtävät sinua valikkopalkin valikoiden välillä.</li>\n' +
' <li>avaavat valikon alavalikon.</li>\n' +
' <li>siirtävät sinua työkalupalkin ryhmän painikkeiden välillä.</li>\n' +
' <li>siirtävät sinua kohteiden välillä alatunnisteen elementin polussa.</li>\n' +
'</ul>\n' +
'\n' +
'<p><strong>Alas</strong>- ja <strong>Ylös</strong>-nuolinäppäimet</p>\n' +
'\n' +
'<ul>\n' +
' <li>siirtävät sinua valikon valikkokohteiden välillä.</li>\n' +
' <li>siirtävät sinua työkalupalkin ponnahdusvalikon kohteiden välillä.</li>\n' +
'</ul>\n' +
'\n' +
'<p><strong>Nuolinäppäimet</strong> siirtävät sinua käyttöliittymän korostetun osan sisällä syklissä.</p>\n' +
'\n' +
'<p>Paina <strong>Esc</strong>-näppäintä sulkeaksesi avoimen valikon, avataksesi alavalikon tai avataksesi ponnahdusvalikon.</p>\n' +
'\n' +
'<p>Jos kohdistus on käyttöliittymän tietyn osion ylälaidassa, <strong>Esc</strong>-näppäimen painaminen\n' +
' poistuu myös näppäimistönavigoinnista kokonaan.</p>\n' +
'\n' +
'<h1>Suorita valikkokohde tai työkalupalkin painike</h1>\n' +
'\n' +
'<p>Kun haluamasi valikkokohde tai työkalupalkin painike on korostettuna, paina <strong>Return</strong>-, <strong>Enter</strong>-\n' +
' tai <strong>välilyöntinäppäintä</strong> suorittaaksesi kohteen.</p>\n' +
'\n' +
'<h1>Välilehdittömissä valintaikkunoissa navigointi</h1>\n' +
'\n' +
'<p>Kun välilehdetön valintaikkuna avautuu, kohdistus siirtyy sen ensimmäiseen interaktiiviseen komponenttiin.</p>\n' +
'\n' +
'<p>Voit siirtyä valintaikkunan interaktiivisten komponenttien välillä painamalla <strong>sarkainnäppäintä</strong> tai <strong>Shift+sarkainnäppäin</strong>.</p>\n' +
'\n' +
'<h1>Välilehdellisissä valintaikkunoissa navigointi</h1>\n' +
'\n' +
'<p>Kun välilehdellinen valintaikkuna avautuu, kohdistus siirtyy välilehtivalikon ensimmäiseen painikkeeseen.</p>\n' +
'\n' +
'<p>Voit siirtyä valintaikkunan välilehden interaktiivisen komponenttien välillä painamalla <strong>sarkainnäppäintä</strong> tai\n' +
' <strong>Shift+sarkainnäppäin</strong>.</p>\n' +
'\n' +
'<p>Voit siirtyä valintaikkunan toiseen välilehteen siirtämällä kohdistuksen välilehtivalikkoon ja painamalla sopivaa <strong>nuolinäppäintä</strong>\n' +
' siirtyäksesi käytettävissä olevien välilehtien välillä syklissä.</p>\n');

View File

@@ -0,0 +1,93 @@
tinymce.Resource.add('tinymce.html-i18n.help-keynav.fr-FR',
'<h1>Débuter la navigation au clavier</h1>\n' +
'\n' +
'<dl>\n' +
' <dt>Cibler la barre du menu</dt>\n' +
' <dd>Windows ou Linux : Alt+F9</dd>\n' +
' <dd>macOS : &#x2325;F9</dd>\n' +
" <dt>Cibler la barre d'outils</dt>\n" +
' <dd>Windows ou Linux : Alt+F10</dd>\n' +
' <dd>macOS : &#x2325;F10</dd>\n' +
' <dt>Cibler le pied de page</dt>\n' +
' <dd>Windows ou Linux : Alt+F11</dd>\n' +
' <dd>macOS : &#x2325;F11</dd>\n' +
' <dt>Cibler la notification</dt>\n' +
' <dd>Windows ou Linux : Alt+F12</dd>\n' +
' <dd>macOS : &#x2325;F12</dd>\n' +
" <dt>Cibler une barre d'outils contextuelle</dt>\n" +
' <dd>Windows, Linux ou macOS : Ctrl+F9</dd>\n' +
'</dl>\n' +
'\n' +
"<p>La navigation débutera sur le premier élément de l'interface utilisateur, qui sera mis en surbrillance ou bien souligné dans le cas du premier élément du\n" +
" chemin d'éléments du pied de page.</p>\n" +
'\n' +
"<h1>Naviguer entre les sections de l'interface utilisateur</h1>\n" +
'\n' +
"<p>Pour passer d'une section de l'interface utilisateur à la suivante, appuyez sur <strong>Tabulation</strong>.</p>\n" +
'\n' +
"<p>Pour passer d'une section de l'interface utilisateur à la précédente, appuyez sur <strong>Maj+Tabulation</strong>.</p>\n" +
'\n' +
"<p>L'ordre de <strong>Tabulation</strong> de ces sections de l'interface utilisateur est le suivant :</p>\n" +
'\n' +
'<ol>\n' +
' <li>Barre du menu</li>\n' +
" <li>Chaque groupe de barres d'outils</li>\n" +
' <li>Barre latérale</li>\n' +
" <li>Chemin d'éléments du pied de page</li>\n" +
" <li>Bouton d'activation du compteur de mots dans le pied de page</li>\n" +
' <li>Lien de marque dans le pied de page</li>\n' +
" <li>Poignée de redimensionnement de l'éditeur dans le pied de page</li>\n" +
'</ol>\n' +
'\n' +
"<p>Si une section de l'interface utilisateur n'est pas présente, elle sera ignorée.</p>\n" +
'\n' +
"<p>Si le pied de page comporte un ciblage par navigation au clavier et qu'il n'y a aucune barre latérale visible, appuyer sur <strong>Maj+Tabulation</strong>\n" +
" déplace le ciblage vers le premier groupe de barres d'outils et non le dernier.</p>\n" +
'\n' +
"<h1>Naviguer au sein des sections de l'interface utilisateur</h1>\n" +
'\n' +
"<p>Pour passer d'un élément de l'interface utilisateur au suivant, appuyez sur la <strong>Flèche</strong> appropriée.</p>\n" +
'\n' +
'<p>Les touches fléchées <strong>Gauche</strong> et <strong>Droite</strong></p>\n' +
'\n' +
'<ul>\n' +
' <li>se déplacent entre les menus de la barre des menus.</li>\n' +
" <li>ouvrent un sous-menu au sein d'un menu.</li>\n" +
" <li>se déplacent entre les boutons d'un groupe de barres d'outils.</li>\n" +
" <li>se déplacent entre les éléments du chemin d'éléments du pied de page.</li>\n" +
'</ul>\n' +
'\n' +
'<p>Les touches fléchées <strong>Bas</strong> et <strong>Haut</strong></p>\n' +
'\n' +
'<ul>\n' +
" <li>se déplacent entre les éléments de menu au sein d'un menu.</li>\n" +
" <li>se déplacent entre les éléments au sein d'un menu contextuel de barre d'outils.</li>\n" +
'</ul>\n' +
'\n' +
"<p>Les <strong>Flèches</strong> parcourent la section de l'interface utilisateur ciblée.</p>\n" +
'\n' +
'<p>Pour fermer un menu ouvert, un sous-menu ouvert ou un menu contextuel ouvert, appuyez sur <strong>Echap</strong>.</p>\n' +
'\n' +
"<p>Si l'actuel ciblage se trouve en « haut » d'une section spécifique de l'interface utilisateur, appuyer sur <strong>Echap</strong> permet également de quitter\n" +
' entièrement la navigation au clavier.</p>\n' +
'\n' +
"<h1>Exécuter un élément de menu ou un bouton de barre d'outils</h1>\n" +
'\n' +
"<p>Lorsque l'élément de menu ou le bouton de barre d'outils désiré est mis en surbrillance, appuyez sur la touche <strong>Retour arrière</strong>, <strong>Entrée</strong>\n" +
" ou la <strong>Barre d'espace</strong> pour exécuter l'élément.</p>\n" +
'\n' +
'<h1>Naviguer au sein de dialogues sans onglets</h1>\n' +
'\n' +
"<p>Dans les dialogues sans onglets, le premier composant interactif est ciblé lorsque le dialogue s'ouvre.</p>\n" +
'\n' +
'<p>Naviguez entre les composants du dialogue interactif en appuyant sur <strong>Tabulation</strong> ou <strong>Maj+Tabulation</strong>.</p>\n' +
'\n' +
'<h1>Naviguer au sein de dialogues avec onglets</h1>\n' +
'\n' +
"<p>Dans les dialogues avec onglets, le premier bouton du menu de l'onglet est ciblé lorsque le dialogue s'ouvre.</p>\n" +
'\n' +
'<p>Naviguez entre les composants interactifs de cet onglet de dialogue en appuyant sur <strong>Tabulation</strong> ou\n' +
' <strong>Maj+Tabulation</strong>.</p>\n' +
'\n' +
"<p>Passez à un autre onglet de dialogue en ciblant le menu de l'onglet et en appuyant sur la <strong>Flèche</strong>\n" +
' appropriée pour parcourir les onglets disponibles.</p>\n');

View File

@@ -0,0 +1,93 @@
tinymce.Resource.add('tinymce.html-i18n.help-keynav.fr_FR',
'<h1>Débuter la navigation au clavier</h1>\n' +
'\n' +
'<dl>\n' +
' <dt>Cibler la barre du menu</dt>\n' +
' <dd>Windows ou Linux : Alt+F9</dd>\n' +
' <dd>macOS : &#x2325;F9</dd>\n' +
" <dt>Cibler la barre d'outils</dt>\n" +
' <dd>Windows ou Linux : Alt+F10</dd>\n' +
' <dd>macOS : &#x2325;F10</dd>\n' +
' <dt>Cibler le pied de page</dt>\n' +
' <dd>Windows ou Linux : Alt+F11</dd>\n' +
' <dd>macOS : &#x2325;F11</dd>\n' +
' <dt>Cibler la notification</dt>\n' +
' <dd>Windows ou Linux : Alt+F12</dd>\n' +
' <dd>macOS : &#x2325;F12</dd>\n' +
" <dt>Cibler une barre d'outils contextuelle</dt>\n" +
' <dd>Windows, Linux ou macOS : Ctrl+F9</dd>\n' +
'</dl>\n' +
'\n' +
"<p>La navigation débutera sur le premier élément de l'interface utilisateur, qui sera mis en surbrillance ou bien souligné dans le cas du premier élément du\n" +
" chemin d'éléments du pied de page.</p>\n" +
'\n' +
"<h1>Naviguer entre les sections de l'interface utilisateur</h1>\n" +
'\n' +
"<p>Pour passer d'une section de l'interface utilisateur à la suivante, appuyez sur <strong>Tabulation</strong>.</p>\n" +
'\n' +
"<p>Pour passer d'une section de l'interface utilisateur à la précédente, appuyez sur <strong>Maj+Tabulation</strong>.</p>\n" +
'\n' +
"<p>L'ordre de <strong>Tabulation</strong> de ces sections de l'interface utilisateur est le suivant :</p>\n" +
'\n' +
'<ol>\n' +
' <li>Barre du menu</li>\n' +
" <li>Chaque groupe de barres d'outils</li>\n" +
' <li>Barre latérale</li>\n' +
" <li>Chemin d'éléments du pied de page</li>\n" +
" <li>Bouton d'activation du compteur de mots dans le pied de page</li>\n" +
' <li>Lien de marque dans le pied de page</li>\n' +
" <li>Poignée de redimensionnement de l'éditeur dans le pied de page</li>\n" +
'</ol>\n' +
'\n' +
"<p>Si une section de l'interface utilisateur n'est pas présente, elle sera ignorée.</p>\n" +
'\n' +
"<p>Si le pied de page comporte un ciblage par navigation au clavier et qu'il n'y a aucune barre latérale visible, appuyer sur <strong>Maj+Tabulation</strong>\n" +
" déplace le ciblage vers le premier groupe de barres d'outils et non le dernier.</p>\n" +
'\n' +
"<h1>Naviguer au sein des sections de l'interface utilisateur</h1>\n" +
'\n' +
"<p>Pour passer d'un élément de l'interface utilisateur au suivant, appuyez sur la <strong>Flèche</strong> appropriée.</p>\n" +
'\n' +
'<p>Les touches fléchées <strong>Gauche</strong> et <strong>Droite</strong></p>\n' +
'\n' +
'<ul>\n' +
' <li>se déplacent entre les menus de la barre des menus.</li>\n' +
" <li>ouvrent un sous-menu au sein d'un menu.</li>\n" +
" <li>se déplacent entre les boutons d'un groupe de barres d'outils.</li>\n" +
" <li>se déplacent entre les éléments du chemin d'éléments du pied de page.</li>\n" +
'</ul>\n' +
'\n' +
'<p>Les touches fléchées <strong>Bas</strong> et <strong>Haut</strong></p>\n' +
'\n' +
'<ul>\n' +
" <li>se déplacent entre les éléments de menu au sein d'un menu.</li>\n" +
" <li>se déplacent entre les éléments au sein d'un menu contextuel de barre d'outils.</li>\n" +
'</ul>\n' +
'\n' +
"<p>Les <strong>Flèches</strong> parcourent la section de l'interface utilisateur ciblée.</p>\n" +
'\n' +
'<p>Pour fermer un menu ouvert, un sous-menu ouvert ou un menu contextuel ouvert, appuyez sur <strong>Echap</strong>.</p>\n' +
'\n' +
"<p>Si l'actuel ciblage se trouve en « haut » d'une section spécifique de l'interface utilisateur, appuyer sur <strong>Echap</strong> permet également de quitter\n" +
' entièrement la navigation au clavier.</p>\n' +
'\n' +
"<h1>Exécuter un élément de menu ou un bouton de barre d'outils</h1>\n" +
'\n' +
"<p>Lorsque l'élément de menu ou le bouton de barre d'outils désiré est mis en surbrillance, appuyez sur la touche <strong>Retour arrière</strong>, <strong>Entrée</strong>\n" +
" ou la <strong>Barre d'espace</strong> pour exécuter l'élément.</p>\n" +
'\n' +
'<h1>Naviguer au sein de dialogues sans onglets</h1>\n' +
'\n' +
"<p>Dans les dialogues sans onglets, le premier composant interactif est ciblé lorsque le dialogue s'ouvre.</p>\n" +
'\n' +
'<p>Naviguez entre les composants du dialogue interactif en appuyant sur <strong>Tabulation</strong> ou <strong>Maj+Tabulation</strong>.</p>\n' +
'\n' +
'<h1>Naviguer au sein de dialogues avec onglets</h1>\n' +
'\n' +
"<p>Dans les dialogues avec onglets, le premier bouton du menu de l'onglet est ciblé lorsque le dialogue s'ouvre.</p>\n" +
'\n' +
'<p>Naviguez entre les composants interactifs de cet onglet de dialogue en appuyant sur <strong>Tabulation</strong> ou\n' +
' <strong>Maj+Tabulation</strong>.</p>\n' +
'\n' +
"<p>Passez à un autre onglet de dialogue en ciblant le menu de l'onglet et en appuyant sur la <strong>Flèche</strong>\n" +
' appropriée pour parcourir les onglets disponibles.</p>\n');

Some files were not shown because too many files have changed in this diff Show More