Compare commits
18
Commits
v0.2.2
..
22ab25045c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22ab25045c
|
||
|
|
2230259e4a
|
||
|
|
57f3a910f6
|
||
|
|
9076a9488e
|
||
|
|
53c78c30e1
|
||
|
|
b94bf56e77
|
||
|
|
dcc4e26235
|
||
|
|
abbceaad51
|
||
|
|
81a86da21c
|
||
|
|
36b975a1ff
|
||
|
|
f92ef51b76
|
||
|
|
8e86f2db31
|
||
|
|
6d607570af
|
||
|
|
aa5a0ec836
|
||
|
|
3a04f99d31
|
||
|
|
8e2bbb3240
|
||
|
|
8b86a476ad
|
||
|
|
278f5626c2
|
No files matched your search
@@ -0,0 +1,30 @@
|
||||
# Version control
|
||||
.git
|
||||
.gitignore
|
||||
|
||||
# Dependencies
|
||||
node_modules
|
||||
bun.lockb
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
.env.*
|
||||
|
||||
# Development files
|
||||
*.log
|
||||
.vscode
|
||||
.idea
|
||||
*.md
|
||||
|
||||
# Build artifacts
|
||||
dist
|
||||
build
|
||||
|
||||
# Docker
|
||||
Dockerfile
|
||||
docker-compose.yml
|
||||
.dockerignore
|
||||
|
||||
# System files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
-142
@@ -1,142 +0,0 @@
|
||||
---
|
||||
kind: secret
|
||||
name: docker_username
|
||||
get:
|
||||
path: odit-registry-builder
|
||||
name: username
|
||||
|
||||
---
|
||||
kind: secret
|
||||
name: docker_password
|
||||
get:
|
||||
path: odit-registry-builder
|
||||
name: password
|
||||
|
||||
---
|
||||
kind: secret
|
||||
name: git_ssh
|
||||
get:
|
||||
path: odit-git-bot
|
||||
name: sshkey
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: kubernetes
|
||||
name: tests:node
|
||||
clone:
|
||||
disable: true
|
||||
steps:
|
||||
- name: checkout pr
|
||||
image: alpine/git
|
||||
commands:
|
||||
- git clone $DRONE_REMOTE_URL .
|
||||
- git checkout $DRONE_SOURCE_BRANCH
|
||||
- name: run tests
|
||||
image: registry.odit.services/hub/library/node:19.0.1-alpine3.16
|
||||
commands:
|
||||
- yarn
|
||||
- yarn test:ci
|
||||
trigger:
|
||||
event:
|
||||
- pull_request
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: kubernetes
|
||||
name: build:dev
|
||||
clone:
|
||||
disable: true
|
||||
|
||||
steps:
|
||||
- name: clone
|
||||
image: alpine/git
|
||||
commands:
|
||||
- git clone $DRONE_REMOTE_URL .
|
||||
- git checkout dev
|
||||
- name: build dev
|
||||
image: registry.odit.services/library/drone-kaniko
|
||||
settings:
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
build_args:
|
||||
- NPM_REGISTRY_DOMAIN:
|
||||
from_secret: npmjs_domain
|
||||
- NPM_REGISTRY_TOKEN:
|
||||
from_secret: npmjs_token
|
||||
repo: lfk/mailer
|
||||
tags:
|
||||
- dev
|
||||
cache: true
|
||||
registry: registry.odit.services
|
||||
trigger:
|
||||
branch:
|
||||
- dev
|
||||
event:
|
||||
- push
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: kubernetes
|
||||
name: build:latest
|
||||
clone:
|
||||
disable: true
|
||||
|
||||
steps:
|
||||
- name: clone
|
||||
image: alpine/git
|
||||
commands:
|
||||
- git clone $DRONE_REMOTE_URL .
|
||||
- git checkout dev
|
||||
- git merge main
|
||||
- git checkout main
|
||||
- name: build latest
|
||||
image: registry.odit.services/library/drone-kaniko
|
||||
settings:
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
build_args:
|
||||
- NPM_REGISTRY_DOMAIN:
|
||||
from_secret: npmjs_domain
|
||||
- NPM_REGISTRY_TOKEN:
|
||||
from_secret: npmjs_token
|
||||
repo: lfk/mailer
|
||||
tags:
|
||||
- latest
|
||||
cache: true
|
||||
registry: registry.odit.services
|
||||
trigger:
|
||||
branch:
|
||||
- main
|
||||
event:
|
||||
- push
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: kubernetes
|
||||
name: build:tags
|
||||
|
||||
steps:
|
||||
- name: build $DRONE_TAG
|
||||
image: registry.odit.services/library/drone-kaniko
|
||||
settings:
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
build_args:
|
||||
- NPM_REGISTRY_DOMAIN:
|
||||
from_secret: npmjs_domain
|
||||
- NPM_REGISTRY_TOKEN:
|
||||
from_secret: npmjs_token
|
||||
repo: lfk/mailer
|
||||
tags:
|
||||
- "${DRONE_TAG}"
|
||||
cache: true
|
||||
registry: registry.odit.services
|
||||
trigger:
|
||||
event:
|
||||
- tag
|
||||
@@ -0,0 +1,11 @@
|
||||
SMTP_HOST=localhost
|
||||
SMTP_PORT=587
|
||||
SMTP_USER="project.1"
|
||||
SMTP_PASS="secret.1"
|
||||
EMAIL_FROM="noreply@lauf-fuer-kaya.de"
|
||||
EMAIL_REPLYTO="info@lauf-fuer-kaya.de"
|
||||
REDIS_URL=redis://localhost:6379
|
||||
FRONTEND_URL="https://run.lauf-fuer-kaya.de"
|
||||
AUTHKEY=""
|
||||
EVENT_DATE="23.05.2025"
|
||||
EVENT_NAME="Lauf für Kaya! 2025"
|
||||
+1
-140
@@ -1,141 +1,2 @@
|
||||
# ---> VisualStudioCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!/.vscode/*.yml
|
||||
*.code-workspace
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# ---> Node
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
node_modules
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
build
|
||||
|
||||
*.sqlite
|
||||
*.sqlite-jurnal
|
||||
/docs
|
||||
lib
|
||||
/oss-attribution
|
||||
*.tmp
|
||||
pnpm-lock.yaml
|
||||
Vendored
-11
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"2gua.rainbow-brackets",
|
||||
"christian-kohler.npm-intellisense",
|
||||
"remimarsal.prettier-now",
|
||||
"lokalise.i18n-ally",
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"antfu.i18n-ally"
|
||||
]
|
||||
}
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
languageIds:
|
||||
- javascript
|
||||
- html
|
||||
- typescript
|
||||
- plaintext
|
||||
keyMatchReg:
|
||||
- '\{\{__ "([a-zA-Z0-9_-]+)"\}\}'
|
||||
monopoly: false
|
||||
refactorTemplates:
|
||||
- '{{__ "$1"}}'
|
||||
Vendored
-31
@@ -1,31 +0,0 @@
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"typescript.format.enable": true,
|
||||
"typescript.preferences.quoteStyle": "single",
|
||||
"[json]": {
|
||||
"editor.defaultFormatter": "vscode.json-language-features"
|
||||
},
|
||||
"[html]": {
|
||||
"editor.defaultFormatter": "vscode.json-language-features",
|
||||
"editor.formatOnSave": false
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "vscode.typescript-language-features",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.organizeImports": true,
|
||||
// "source.fixAll": true
|
||||
}
|
||||
},
|
||||
"javascript.preferences.quoteStyle": "single",
|
||||
"javascript.preferences.importModuleSpecifierEnding": "minimal",
|
||||
"typescript.preferences.importModuleSpecifierEnding": "minimal",
|
||||
"typescript.preferences.includePackageJsonAutoImports": "on",
|
||||
"i18n-ally.localesPaths": "src/locales",
|
||||
"i18n-ally.keystyle": "nested",
|
||||
"i18n-ally.extract.keygenStrategy":"slug",
|
||||
"i18n-ally.enabledFrameworks": [
|
||||
"custom"
|
||||
],
|
||||
"i18n-ally.sourceLanguage": "en"
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
steps:
|
||||
- name: build latest
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
repo: registry.odit.services/lfk/mailer
|
||||
tags:
|
||||
- latest
|
||||
registry: registry.odit.services
|
||||
platforms: linux/amd64,linux/arm64
|
||||
cache_from: registry.odit.services/lfk/mailer:dev
|
||||
username:
|
||||
from_secret: odit-registry-builder-username
|
||||
password:
|
||||
from_secret: odit-registry-builder-password
|
||||
when:
|
||||
branch: main
|
||||
- name: build dev
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
repo: registry.odit.services/lfk/mailer
|
||||
tags:
|
||||
- dev
|
||||
registry: registry.odit.services
|
||||
platforms: linux/amd64,linux/arm64
|
||||
cache_from: registry.odit.services/lfk/mailer:dev
|
||||
username:
|
||||
from_secret: odit-registry-builder-username
|
||||
password:
|
||||
from_secret: odit-registry-builder-password
|
||||
when:
|
||||
branch: dev
|
||||
when:
|
||||
event: push
|
||||
@@ -0,0 +1,17 @@
|
||||
steps:
|
||||
- name: build tag
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
repo: registry.odit.services/lfk/mailer
|
||||
tags:
|
||||
- "${CI_COMMIT_TAG}"
|
||||
registry: registry.odit.services
|
||||
platforms: linux/amd64,linux/arm64
|
||||
cache_from: registry.odit.services/lfk/mailer:dev
|
||||
username:
|
||||
from_secret: odit-registry-builder-username
|
||||
password:
|
||||
from_secret: odit-registry-builder-password
|
||||
when:
|
||||
event:
|
||||
- tag
|
||||
@@ -2,9 +2,16 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
||||
|
||||
#### [v0.2.3](https://git.odit.services/lfk/mailer/compare/v0.2.2...v0.2.3)
|
||||
|
||||
- Fixed missing closing tag [`8e2bbb3`](https://git.odit.services/lfk/mailer/commit/8e2bbb324091c0ba28ccd24fc189b2e7ddab8ce3)
|
||||
|
||||
#### [v0.2.2](https://git.odit.services/lfk/mailer/compare/v0.2.1...v0.2.2)
|
||||
|
||||
> 3 February 2023
|
||||
|
||||
- update runner-welcome mail template [`#15`](https://git.odit.services/lfk/mailer/issues/15)
|
||||
- 🚀Bumped version to v0.2.2 [`a616570`](https://git.odit.services/lfk/mailer/commit/a6165708a6a529bf219f28be74e2de71e64a2be5)
|
||||
- Merge pull request 'cleaned up mail texts for lfk 2023' (#16) from feature/simpler-mail-texts into main [`e7ad878`](https://git.odit.services/lfk/mailer/commit/e7ad878fb93773d1dec35d3b8b9c4f7b4b773221)
|
||||
- cleaned up mail texts for lfk 2023 [`1eb1a0a`](https://git.odit.services/lfk/mailer/commit/1eb1a0ad7e11b8f25b2b8d0efea991cab444c6ee)
|
||||
|
||||
|
||||
+20
-15
@@ -1,16 +1,21 @@
|
||||
# Typescript Build
|
||||
FROM registry.odit.services/hub/library/node:19.0.1-alpine3.16
|
||||
FROM oven/bun:1.1.36-slim
|
||||
# FROM oven/bun:1.0.25
|
||||
|
||||
WORKDIR /app
|
||||
COPY package.json ./
|
||||
RUN npm i -g pnpm
|
||||
RUN pnpm i
|
||||
COPY tsconfig.json ./
|
||||
COPY src ./src
|
||||
RUN pnpm run build
|
||||
# final image
|
||||
FROM registry.odit.services/hub/library/node:19.0.1-alpine3.16
|
||||
COPY package.json ./
|
||||
RUN npm i -g pnpm
|
||||
RUN pnpm i --prod
|
||||
COPY --from=0 /app/dist dist
|
||||
ENTRYPOINT ["node", "dist/app.js"]
|
||||
|
||||
# Copy package files
|
||||
|
||||
# Install dependencies
|
||||
COPY package.json .
|
||||
RUN bun i
|
||||
# COPY package.json bun.lockb ./
|
||||
# RUN bun install --frozen-lockfile
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Expose the application port
|
||||
EXPOSE 3000
|
||||
|
||||
# Start the application
|
||||
CMD ["bun", "run", "start"]
|
||||
@@ -1,74 +1,102 @@
|
||||
# @lfk/mailer
|
||||
[](https://ci.odit.services/lfk/mailer)
|
||||
# 📧 Email Microservice
|
||||
|
||||
Handles mail generation and sending (pw reset, welcome mail, etc)
|
||||
A modern email microservice built with Hono and TypeScript, supporting multiple languages and HTML/Text email templates.
|
||||
|
||||
## Dev Setup 🛠
|
||||
> Local dev setup
|
||||
## ✨ Features
|
||||
|
||||
1. Rename the .env.example file to .env (you can adjust app port and other settings, if needed) or generate a example env with `yarn && yarn test:generate_env`.
|
||||
2. Install Dependencies
|
||||
```bash
|
||||
yarn
|
||||
```
|
||||
3. Start the server
|
||||
```bash
|
||||
yarn dev
|
||||
```
|
||||
- 🌐 Multi-language support (English & German)
|
||||
- 📝 HTML and Text email templates
|
||||
- 📚 OpenAPI/Swagger documentation
|
||||
- ⚡ High-performance with Bun runtime
|
||||
- 🔄 Queue-based email processing
|
||||
- 🎨 Handlebars templating
|
||||
|
||||
## Templates
|
||||
> The mailer uses html and plaintext templates to generate various mails.
|
||||
> The templates are stored in src/templates by default.
|
||||
## 🚀 Quick Start
|
||||
|
||||
We provide a set of default templates that we use for the ["Lauf für Kaya!" charity run](https://lauf-fuer-kaya.de).
|
||||
We use handlebars for templateing utilizing i18next for translation - the i18n string format in the templates is : `{{__ "string"}}`
|
||||
You can provide your own templates by replacing the ones we provided before compiling the project or by simply mounting your custom templates into the docker container.
|
||||
```bash
|
||||
# Install dependencies
|
||||
bun install
|
||||
|
||||
The server currently needs the following templates to work:
|
||||
* pw-reset.html
|
||||
* pw-reset.txt
|
||||
* test.html
|
||||
* test.txt
|
||||
* welcome_runner.html
|
||||
* welcome_runner.txt
|
||||
# Start development server
|
||||
bun dev
|
||||
```
|
||||
|
||||
| Name | Type | Default | Description
|
||||
| - | - | - | -
|
||||
| APP_PORT | Number | 4010 | The port the backend server listens on. Is optional.
|
||||
| NODE_ENV | String | dev | The apps env - influences debug info.
|
||||
| API_KEY | String(min length: 64) | Random generated string | The api key you want to use for auth (query-param `key`), has to be at least 64 chars long.
|
||||
| API_URL | String(url) | "http://localhost:8080" | The URL ponting to the base (root) of the lfk runner system.
|
||||
| MAIL_SERVER | String(FQDN) | None | The mailserver (smtp) used to send mails via nodemailer.
|
||||
| MAIL_PORT | Number | 25 | The mailserver's port (smtp).
|
||||
| MAIL_USER | String | None | The username used to authenticate against the mailserver.
|
||||
| MAIL_PASSWORD | String | None | The password used to authenticate against the mailserver.
|
||||
| MAIL_FROM | String | None | The mail address that mails get sent from.
|
||||
| PRIVACY_URL | String | "/privacy" | The url path that get's attached to the app url to link to the privacy page.
|
||||
| IMPRINT_URL | String | "/imprint" | The url path that get's attached to the app url to link to the imprint page.
|
||||
| COPYRIGHT_OWNER | String | "LfK!" | Text that gets inserted as the "copyright by" owner in the mails.
|
||||
| EVENT_NAME | String | "Testing 4 Kaya" | The event's name - used to generate the mail text.
|
||||
| CONTACT_MAIL | String(email) | MAIL_FROM | Contact mail address listed at the bottom of some mail templates.
|
||||
## 📖 API Documentation
|
||||
|
||||
## Recommended Editor
|
||||
Swagger UI is available at: `/swagger`
|
||||
|
||||
[Visual Studio Code](https://code.visualstudio.com/)
|
||||
## 🔍 Example API Calls
|
||||
|
||||
### Recommended Extensions
|
||||
### Send Welcome Email
|
||||
|
||||
* will be automatically recommended via ./vscode/extensions.json
|
||||
* we also provide a config for i18n-ally in the .vscode folder
|
||||
```bash
|
||||
curl -X POST http://localhost:3000/api/v1/email \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"to": "user@example.com",
|
||||
"templateName": "welcome",
|
||||
"language": "en",
|
||||
"data": {
|
||||
"name": "John Doe",
|
||||
"barcode_content": "0123456789",
|
||||
"link": "https://portal.lauf-fuer-kaya.de/"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
## Staging
|
||||
### Branches & Tags
|
||||
* vX.Y.Z: Release tags created from the main branch
|
||||
* The version numbers follow the semver standard
|
||||
* A new release tag automaticly triggers the release ci pipeline
|
||||
* main: Protected "release" branch
|
||||
* The latest tag of the docker image get's build from this
|
||||
* New releases get created as tags from this
|
||||
* dev: Current dev branch for merging the different feature branches and bugfixes
|
||||
* The dev tag of the docker image get's build from this
|
||||
* Only push minor changes to this branch!
|
||||
* To merge a feature branch into this please create a pull request
|
||||
* feature/xyz: Feature branches - nameing scheme: `feature/issueid-title`
|
||||
* bugfix/xyz: Branches for bugfixes - nameing scheme:`bugfix/issueid-title`
|
||||
### Send Password Reset Email
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:3000/api/v1/email \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"to": "user@example.com",
|
||||
"templateName": "password-reset",
|
||||
"language": "de",
|
||||
"data": {
|
||||
"token": "123465789"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Check Queue Status
|
||||
|
||||
```bash
|
||||
curl http://localhost:3000/api/v1/email/status
|
||||
```
|
||||
|
||||
## 📝 Environment Variables
|
||||
|
||||
```env
|
||||
SMTP_HOST=localhost
|
||||
SMTP_PORT=587
|
||||
SMTP_USER="project.1"
|
||||
SMTP_PASS="secret.1"
|
||||
EMAIL_FROM="noreply@lauf-fuer-kaya.de"
|
||||
EMAIL_REPLYTO="info@lauf-fuer-kaya.de"
|
||||
REDIS_URL=redis://localhost:6379
|
||||
FRONTEND_URL="https://run.lauf-fuer-kaya.de"
|
||||
AUTHKEY=""
|
||||
EVENT_DATE="23.05.2025"
|
||||
EVENT_NAME="Lauf für Kaya! 2025"
|
||||
```
|
||||
|
||||
## 🛠️ Development
|
||||
|
||||
The project uses:
|
||||
- 🏃♂️ Bun for runtime and package management
|
||||
- 🌐 Hono for the web framework
|
||||
- 📚 Zod for validation
|
||||
- 📧 Nodemailer for email sending
|
||||
- 📑 Handlebars for templating
|
||||
- 📊 BullMQ for queue management
|
||||
|
||||
## 📦 Available Templates
|
||||
|
||||
### Welcome Email
|
||||
- Languages: 🇬🇧 English, 🇩🇪 German
|
||||
- Variables: `name`, `link`, `barcode_content`
|
||||
|
||||
### Password Reset
|
||||
- Languages: 🇬🇧 English, 🇩🇪 German
|
||||
- Variables: `token`
|
||||
+29
-5
@@ -1,9 +1,33 @@
|
||||
version: "3"
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
mailer:
|
||||
app:
|
||||
build: .
|
||||
ports:
|
||||
- 4010:4010
|
||||
- "3000:3000"
|
||||
environment:
|
||||
APP_PORT: 4010
|
||||
NODE_ENV: production
|
||||
- NODE_ENV=production
|
||||
- REDIS_URL=redis://redis:6379
|
||||
- SMTP_HOST=localhost
|
||||
- SMTP_PORT=587
|
||||
- SMTP_USER="project.1"
|
||||
- SMTP_PASS="secret.1"
|
||||
- EMAIL_FROM="noreply@lauf-fuer-kaya.de"
|
||||
- EMAIL_REPLYTO="info@lauf-fuer-kaya.de"
|
||||
- FRONTEND_URL="https://run.lauf-fuer-kaya.de"
|
||||
- AUTHKEY=""
|
||||
- EVENT_DATE="23.05.2025"
|
||||
- EVENT_NAME="Lauf für Kaya! 2025"
|
||||
depends_on:
|
||||
- redis
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
command: redis-server --appendonly yes
|
||||
|
||||
volumes:
|
||||
redis_data:
|
||||
@@ -1,4 +0,0 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
};
|
||||
-841
@@ -1,841 +0,0 @@
|
||||
# @odit/class-validator-jsonschema
|
||||
**Author**: Aleksi Pekkala <aleksipekkala@gmail.com>
|
||||
**Repo**: git@github.com:epiphone/class-validator-jsonschema.git
|
||||
**License**: MIT
|
||||
**Description**: Convert class-validator-decorated classes into JSON schema
|
||||
## License Text
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Aleksi Pekkala
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
# class-transformer
|
||||
**Author**: [object Object]
|
||||
**Repo**: https://github.com/typestack/class-transformer.git
|
||||
**License**: MIT
|
||||
**Description**: Proper decorator-based transformation / serialization / deserialization of plain javascript objects to class constructors
|
||||
## License Text
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2015-2020 Umed Khudoiberdiev
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
# class-validator
|
||||
**Author**: TypeStack contributors
|
||||
**Repo**: https://github.com/typestack/class-validator.git
|
||||
**License**: MIT
|
||||
**Description**: Decorator-based property validation for classes.
|
||||
## License Text
|
||||
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2015-2020 TypeStack
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
# consola
|
||||
**Author**: undefined
|
||||
**Repo**: nuxt/consola
|
||||
**License**: MIT
|
||||
**Description**: Elegant Console Logger for Node.js and Browser
|
||||
## License Text
|
||||
|
||||
|
||||
# cors
|
||||
**Author**: Troy Goode <troygoode@gmail.com> (https://github.com/troygoode/)
|
||||
**Repo**: expressjs/cors
|
||||
**License**: MIT
|
||||
**Description**: Node.js CORS middleware
|
||||
## License Text
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2013 Troy Goode <troygoode@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
# dotenv
|
||||
**Author**: undefined
|
||||
**Repo**: git://github.com/motdotla/dotenv.git
|
||||
**License**: BSD-2-Clause
|
||||
**Description**: Loads environment variables from .env file
|
||||
## License Text
|
||||
Copyright (c) 2015, Scott Motte
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
# express
|
||||
**Author**: TJ Holowaychuk <tj@vision-media.ca>
|
||||
**Repo**: expressjs/express
|
||||
**License**: MIT
|
||||
**Description**: Fast, unopinionated, minimalist web framework
|
||||
## License Text
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2009-2014 TJ Holowaychuk <tj@vision-media.ca>
|
||||
Copyright (c) 2013-2014 Roman Shtylman <shtylman+expressjs@gmail.com>
|
||||
Copyright (c) 2014-2015 Douglas Christopher Wilson <doug@somethingdoug.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
# handlebars
|
||||
**Author**: Yehuda Katz
|
||||
**Repo**: https://github.com/wycats/handlebars.js.git
|
||||
**License**: MIT
|
||||
**Description**: Handlebars provides the power necessary to let you build semantic templates effectively with no frustration
|
||||
## License Text
|
||||
Copyright (C) 2011-2019 by Yehuda Katz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
# i18next
|
||||
**Author**: Jan Mühlemann <jan.muehlemann@gmail.com> (https://github.com/jamuhl)
|
||||
**Repo**: https://github.com/i18next/i18next.git
|
||||
**License**: MIT
|
||||
**Description**: i18next internationalization framework
|
||||
## License Text
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 i18next
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
# i18next-fs-backend
|
||||
**Author**: undefined
|
||||
**Repo**: git@github.com:i18next/i18next-fs-backend.git
|
||||
**License**: undefined
|
||||
**Description**: i18next-fs-backend is a backend layer for i18next using in Node.js and for Deno to load translations from the filesystem.
|
||||
## License Text
|
||||
|
||||
|
||||
# nodemailer
|
||||
**Author**: Andris Reinman
|
||||
**Repo**: https://github.com/nodemailer/nodemailer.git
|
||||
**License**: MIT
|
||||
**Description**: Easy as cake e-mail sending from your Node.js applications
|
||||
## License Text
|
||||
Copyright (c) 2011-2019 Andris Reinman
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
# reflect-metadata
|
||||
**Author**: [object Object]
|
||||
**Repo**: https://github.com/rbuckton/reflect-metadata.git
|
||||
**License**: Apache-2.0
|
||||
**Description**: Polyfill for Metadata Reflection API
|
||||
## License Text
|
||||
Apache License
|
||||
|
||||
Version 2.0, January 2004
|
||||
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
|
||||
You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
|
||||
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||
|
||||
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
# routing-controllers
|
||||
**Author**: [object Object]
|
||||
**Repo**: https://github.com/typestack/routing-controllers.git
|
||||
**License**: MIT
|
||||
**Description**: Create structured, declarative and beautifully organized class-based controllers with heavy decorators usage for Express / Koa using TypeScript.
|
||||
## License Text
|
||||
|
||||
|
||||
# routing-controllers-openapi
|
||||
**Author**: Aleksi Pekkala <aleksipekkala@gmail.com>
|
||||
**Repo**: git@github.com:epiphone/routing-controllers-openapi
|
||||
**License**: MIT
|
||||
**Description**: Runtime OpenAPI v3 spec generation for routing-controllers
|
||||
## License Text
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Aleksi Pekkala
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
# @odit/license-exporter
|
||||
**Author**: ODIT.Services
|
||||
**Repo**: https://git.odit.services/odit/license-exporter
|
||||
**License**: MIT
|
||||
**Description**: A simple license crawler for crediting open source work
|
||||
## License Text
|
||||
MIT License Copyright (c) 2020 ODIT.Services (info@odit.services)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
# @types/express
|
||||
**Author**: undefined
|
||||
**Repo**: https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
**License**: MIT
|
||||
**Description**: TypeScript definitions for Express
|
||||
## License Text
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
|
||||
|
||||
# @types/jest
|
||||
**Author**: undefined
|
||||
**Repo**: https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
**License**: MIT
|
||||
**Description**: TypeScript definitions for Jest
|
||||
## License Text
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
|
||||
|
||||
# @types/node
|
||||
**Author**: undefined
|
||||
**Repo**: https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
**License**: MIT
|
||||
**Description**: TypeScript definitions for Node.js
|
||||
## License Text
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
|
||||
|
||||
# @types/nodemailer
|
||||
**Author**: undefined
|
||||
**Repo**: https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
**License**: MIT
|
||||
**Description**: TypeScript definitions for Nodemailer
|
||||
## License Text
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
|
||||
|
||||
# auto-changelog
|
||||
**Author**: Pete Cook <pete@cookpete.com> (https://github.com/cookpete)
|
||||
**Repo**: https://github.com/CookPete/auto-changelog.git
|
||||
**License**: MIT
|
||||
**Description**: Command line tool for generating a changelog from git tags and commit history
|
||||
## License Text
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2017 Pete Cook https://cookpete.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
# axios
|
||||
**Author**: Matt Zabriskie
|
||||
**Repo**: https://github.com/axios/axios.git
|
||||
**License**: MIT
|
||||
**Description**: Promise based HTTP client for the browser and node.js
|
||||
## License Text
|
||||
Copyright (c) 2014-present Matt Zabriskie
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
# cp-cli
|
||||
**Author**: undefined
|
||||
**Repo**: git+https://github.com/screendriver/cp-cli.git
|
||||
**License**: MIT
|
||||
**Description**: A 'cp' CLI util for Node.js
|
||||
## License Text
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Christian Rackerseder
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
# jest
|
||||
**Author**: undefined
|
||||
**Repo**: https://github.com/facebook/jest
|
||||
**License**: MIT
|
||||
**Description**: Delightful JavaScript Testing.
|
||||
## License Text
|
||||
MIT License
|
||||
|
||||
Copyright (c) Facebook, Inc. and its affiliates.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
# nodemon
|
||||
**Author**: [object Object]
|
||||
**Repo**: https://github.com/remy/nodemon.git
|
||||
**License**: MIT
|
||||
**Description**: Simple monitor script for use during development of a node.js app.
|
||||
## License Text
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2010 - present, Remy Sharp, https://remysharp.com <remy@remysharp.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
# release-it
|
||||
**Author**: [object Object]
|
||||
**Repo**: https://github.com/release-it/release-it.git
|
||||
**License**: MIT
|
||||
**Description**: Generic CLI tool to automate versioning and package publishing related tasks.
|
||||
## License Text
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Lars Kappert
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
# rimraf
|
||||
**Author**: Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)
|
||||
**Repo**: git://github.com/isaacs/rimraf.git
|
||||
**License**: ISC
|
||||
**Description**: A deep deletion module for node (like `rm -rf`)
|
||||
## License Text
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
# start-server-and-test
|
||||
**Author**: Gleb Bahmutov <gleb.bahmutov@gmail.com>
|
||||
**Repo**: https://github.com/bahmutov/start-server-and-test.git
|
||||
**License**: MIT
|
||||
**Description**: Starts server, waits for URL, then runs test command; when the tests end, shuts down server
|
||||
## License Text
|
||||
|
||||
|
||||
# ts-jest
|
||||
**Author**: Kulshekhar Kabra <kulshekhar@users.noreply.github.com> (https://github.com/kulshekhar)
|
||||
**Repo**: git+https://github.com/kulshekhar/ts-jest.git
|
||||
**License**: MIT
|
||||
**Description**: A preprocessor with source maps support to help use TypeScript with Jest
|
||||
## License Text
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016-2018
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
# ts-node
|
||||
**Author**: [object Object]
|
||||
**Repo**: git://github.com/TypeStrong/ts-node.git
|
||||
**License**: MIT
|
||||
**Description**: TypeScript execution environment and REPL for node.js, with source map support
|
||||
## License Text
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
# typescript
|
||||
**Author**: Microsoft Corp.
|
||||
**Repo**: https://github.com/Microsoft/TypeScript.git
|
||||
**License**: Apache-2.0
|
||||
**Description**: TypeScript is a language for application scale JavaScript development
|
||||
## License Text
|
||||
Apache License
|
||||
|
||||
Version 2.0, January 2004
|
||||
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
|
||||
You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
|
||||
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||
|
||||
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
+26
-97
@@ -1,99 +1,28 @@
|
||||
{
|
||||
"name": "@odit/lfk-mailer",
|
||||
"version": "0.2.2",
|
||||
"description": "The document mailer for the LfK! runner system. This generates and sends mails (password reset, welcome, ...)",
|
||||
"main": "src/app.ts",
|
||||
"scripts": {
|
||||
"dev": "nodemon src/app.ts",
|
||||
"build": "rimraf ./dist && tsc && cp-cli ./src/templates ./dist/templates && cp-cli ./src/locales ./dist/locales",
|
||||
"licenses:export": "license-exporter --markdown",
|
||||
"changelog:export": "auto-changelog --commit-limit false -p -u --hide-credit",
|
||||
"release": "release-it --only-version",
|
||||
"translations:sort": "node ./scripts/sort_translations.js",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watchAll",
|
||||
"test:generate_env": "ts-node ./scripts/create_testenv.ts",
|
||||
"test:ci": "npm run test:generate_env && npm run test:ci:run",
|
||||
"test:ci:run": "start-server-and-test dev http://localhost:4010/docs/openapi.json test"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@git.odit.services:lfk/mailer.git"
|
||||
},
|
||||
"keywords": [
|
||||
"odit",
|
||||
"lfk",
|
||||
"mail",
|
||||
"node"
|
||||
],
|
||||
"author": {
|
||||
"name": "ODIT.Services",
|
||||
"email": "info@odit.services",
|
||||
"url": "https://odit.services"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Philipp Dormann",
|
||||
"email": "philipp@philippdormann.de",
|
||||
"url": "https://philippdormann.de"
|
||||
},
|
||||
{
|
||||
"name": "Nicolai Ort",
|
||||
"email": "info@nicolai-ort.com",
|
||||
"url": "https://nicolai-ort.com"
|
||||
}
|
||||
],
|
||||
"license": "CC-BY-NC-SA-4.0",
|
||||
"dependencies": {
|
||||
"@odit/class-validator-jsonschema": "2.1.1",
|
||||
"class-transformer": "0.3.1",
|
||||
"class-validator": "0.13.1",
|
||||
"consola": "2.15.3",
|
||||
"cors": "2.8.5",
|
||||
"dotenv": "8.2.0",
|
||||
"express": "4.17.1",
|
||||
"handlebars": "4.7.6",
|
||||
"i18next": "19.8.7",
|
||||
"i18next-fs-backend": "1.0.8",
|
||||
"nodemailer": "6.5.0",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"routing-controllers": "0.9.0-alpha.6",
|
||||
"routing-controllers-openapi": "2.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@odit/license-exporter": "0.0.10",
|
||||
"@types/express": "4.17.11",
|
||||
"@types/jest": "26.0.20",
|
||||
"@types/node": "14.14.22",
|
||||
"@types/nodemailer": "6.4.0",
|
||||
"auto-changelog": "^2.4.0",
|
||||
"axios": "0.21.1",
|
||||
"cp-cli": "2.0.0",
|
||||
"jest": "26.6.3",
|
||||
"nodemon": "2.0.7",
|
||||
"release-it": "14.2.2",
|
||||
"rimraf": "3.0.2",
|
||||
"start-server-and-test": "1.12.0",
|
||||
"ts-jest": "26.5.2",
|
||||
"ts-node": "9.1.1",
|
||||
"typescript": "4.1.3"
|
||||
},
|
||||
"release-it": {
|
||||
"git": {
|
||||
"commit": true,
|
||||
"requireCleanWorkingDir": false,
|
||||
"commitMessage": "🚀Bumped version to v${version}",
|
||||
"requireBranch": "dev",
|
||||
"push": true,
|
||||
"tag": true,
|
||||
"tagName": "v${version}",
|
||||
"tagAnnotation": "v${version}"
|
||||
},
|
||||
"npm": {
|
||||
"publish": false
|
||||
},
|
||||
"hooks": {
|
||||
"after:bump": "npm run changelog:export && npm run licenses:export && git add CHANGELOG.md && git add licenses.md"
|
||||
}
|
||||
}
|
||||
"name": "@odit/lfk-mailer",
|
||||
"version": "1.0.2",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "bun --watch src/index.ts",
|
||||
"start": "bun src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hono/node-server": "1.13.7",
|
||||
"@hono/swagger-ui": "0.5.0",
|
||||
"@hono/zod-openapi": "0.18.3",
|
||||
"@hono/zod-validator": "0.4.1",
|
||||
"bullmq": "5.34.0",
|
||||
"bwip-js": "4.5.1",
|
||||
"handlebars": "4.7.8",
|
||||
"hono": "4.6.13",
|
||||
"ioredis": "5.4.1",
|
||||
"nodemailer": "6.9.16",
|
||||
"zod": "3.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "22.10.2",
|
||||
"@types/nodemailer": "6.4.17",
|
||||
"bun-types": "1.1.38"
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
import consola from "consola";
|
||||
import fs from "fs";
|
||||
import nodemailer from "nodemailer";
|
||||
|
||||
|
||||
nodemailer.createTestAccount((err, account) => {
|
||||
if (err) {
|
||||
console.error('Failed to create a testing account. ' + err.message);
|
||||
return process.exit(1);
|
||||
}
|
||||
let apikey = '';
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
const charactersLength = characters.length;
|
||||
for (var i = 0; i < 64; i++) {
|
||||
apikey += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
const env = `
|
||||
NODE_ENV=dev
|
||||
MAIL_SERVER=${account.smtp.host}
|
||||
MAIL_PORT=${account.smtp.port}
|
||||
MAIL_USER=${account.user}
|
||||
MAIL_PASSWORD=${account.pass}
|
||||
MAIL_FROM=${account.user}
|
||||
API_KEY=${apikey}
|
||||
`
|
||||
|
||||
try {
|
||||
fs.writeFileSync("./.env", env, { encoding: "utf-8" });
|
||||
consola.success("Exported ci env to .env");
|
||||
} catch (error) {
|
||||
consola.error("Couldn't export the ci env");
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
const fs = require('fs');
|
||||
// get all language files
|
||||
const files = fs.readdirSync('./src/locales/');
|
||||
files.forEach((f) => {
|
||||
// read file as object
|
||||
const unordered = JSON.parse(fs.readFileSync(`src/locales/${f}`));
|
||||
// order object by keys alpabetically A-Z
|
||||
const ordered = Object.keys(unordered).sort().reduce((obj, key) => {
|
||||
obj[key] = unordered[key];
|
||||
return obj;
|
||||
}, {});
|
||||
// format output as json for commit diff compatibility
|
||||
const out = JSON.stringify(ordered, 0, 4);
|
||||
// write output file
|
||||
fs.writeFileSync(`src/locales/${f}`, out);
|
||||
});
|
||||
-198
@@ -1,198 +0,0 @@
|
||||
import fs from "fs";
|
||||
import Handlebars from 'handlebars';
|
||||
import i18next from "i18next";
|
||||
import Backend from 'i18next-fs-backend';
|
||||
import nodemailer from 'nodemailer';
|
||||
import { MailOptions } from 'nodemailer/lib/json-transport';
|
||||
import Mail from 'nodemailer/lib/mailer';
|
||||
import path from 'path';
|
||||
import { config } from './config';
|
||||
import { MailServerConfigError } from './errors/MailErrors';
|
||||
|
||||
|
||||
/**
|
||||
* This class is responsible for all mail sending.
|
||||
* This uses the html and plaintext templates from src/templates.
|
||||
*/
|
||||
export class Mailer {
|
||||
private transport: Mail;
|
||||
private static interpolations = { copyright_owner: config.copyright_owner, event_name: config.event_name, contact_mail: config.contact_mail }
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
* Initializes i18n(ext), Handlebars and puppeteer.
|
||||
*/
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
* Initializes i18n(ext), Handlebars and puppeteer.
|
||||
*/
|
||||
public async init() {
|
||||
await i18next
|
||||
.use(Backend)
|
||||
.init({
|
||||
fallbackLng: 'en',
|
||||
lng: 'en',
|
||||
backend: {
|
||||
loadPath: path.join(__dirname, '/locales/{{lng}}.json')
|
||||
}
|
||||
});
|
||||
await Handlebars.registerHelper('__',
|
||||
function (str) {
|
||||
return i18next.t(str, Mailer.interpolations).toString();
|
||||
}
|
||||
);
|
||||
this.transport = nodemailer.createTransport({
|
||||
host: config.mail_server,
|
||||
port: config.mail_port,
|
||||
auth: {
|
||||
user: config.mail_user,
|
||||
pass: config.mail_password
|
||||
}
|
||||
});
|
||||
|
||||
this.transport.verify(function (error, success) {
|
||||
if (error) {
|
||||
throw new MailServerConfigError();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for sending a reset mail from the reset mail template.
|
||||
* @param to_address The address the mail will be sent to. Should always get pulled from a user object.
|
||||
* @param token The requested password reset token - will be combined with the app_url to generate a password reset link.
|
||||
*/
|
||||
public async sendResetMail(to_address: string, token: string, locale: string = "en") {
|
||||
await i18next.changeLanguage(locale);
|
||||
|
||||
const replacements = {
|
||||
recipient_mail: to_address,
|
||||
copyright_owner: config.copyright_owner,
|
||||
link_imprint: `${config.app_url}/imprint`,
|
||||
link_privacy: `${config.app_url}/privacy`,
|
||||
reset_link: `${config.app_url}/reset/${(Buffer.from(token)).toString("base64")}`
|
||||
}
|
||||
|
||||
const template_html = Handlebars.compile(fs.readFileSync(__dirname + '/templates/pw-reset.html', { encoding: 'utf8' }));
|
||||
const template_txt = Handlebars.compile(fs.readFileSync(__dirname + '/templates/pw-reset.txt', { encoding: 'utf8' }));
|
||||
const body_html = template_html(replacements);
|
||||
const body_txt = template_txt(replacements);
|
||||
|
||||
const mail: MailOptions = {
|
||||
to: to_address,
|
||||
subject: i18next.t("lfk-password-reset", Mailer.interpolations).toString(),
|
||||
text: body_txt,
|
||||
html: body_html
|
||||
};
|
||||
await this.sendMail(mail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for sending a test mail from the test mail template.
|
||||
* @param to_address The address the mail will be sent to - usually the FROM address.
|
||||
*/
|
||||
public async sendTestMail(locale: string = "en") {
|
||||
await i18next.changeLanguage(locale);
|
||||
const to_address: string = config.mail_from;
|
||||
const replacements = {
|
||||
recipient_mail: to_address,
|
||||
copyright_owner: config.copyright_owner,
|
||||
link_imprint: `${config.app_url}/imprint`,
|
||||
link_privacy: `${config.app_url}/privacy`
|
||||
}
|
||||
|
||||
const template_html = Handlebars.compile(fs.readFileSync(__dirname + '/templates/test.html', { encoding: 'utf8' }));
|
||||
const template_txt = Handlebars.compile(fs.readFileSync(__dirname + '/templates/test.txt', { encoding: 'utf8' }));
|
||||
const body_html = template_html(replacements);
|
||||
const body_txt = template_txt(replacements);
|
||||
|
||||
const mail: MailOptions = {
|
||||
to: to_address,
|
||||
subject: i18next.t("test-mail", Mailer.interpolations).toString(),
|
||||
text: body_txt,
|
||||
html: body_html
|
||||
};
|
||||
await this.sendMail(mail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for sending a reset mail from the reset mail template.
|
||||
* @param to_address The address the mail will be sent to. Should always get pulled from a runner object.
|
||||
* @param token The runner's selfservice token - will be combined with the app_url to generate a selfservice profile link.
|
||||
*/
|
||||
public async sendWelcomeMail(to_address: string, token: string, locale: string = "en") {
|
||||
await i18next.changeLanguage(locale);
|
||||
token = Buffer.from(token).toString("base64");
|
||||
|
||||
const replacements = {
|
||||
recipient_mail: to_address,
|
||||
copyright_owner: config.copyright_owner,
|
||||
link_imprint: `${config.app_url}/imprint`,
|
||||
link_privacy: `${config.app_url}/privacy`,
|
||||
selfservice_link: `${config.app_url}/selfservice/profile/${token}`,
|
||||
forgot_link: `${config.app_url}/selfservice/`,
|
||||
contact_mail: config.contact_mail,
|
||||
event_name: config.event_name
|
||||
}
|
||||
|
||||
const template_html = Handlebars.compile(fs.readFileSync(__dirname + '/templates/welcome_runner.html', { encoding: 'utf8' }));
|
||||
const template_txt = Handlebars.compile(fs.readFileSync(__dirname + '/templates/welcome_runner.txt', { encoding: 'utf8' }));
|
||||
const body_html = template_html(replacements);
|
||||
const body_txt = template_txt(replacements);
|
||||
|
||||
const mail: MailOptions = {
|
||||
to: to_address,
|
||||
subject: i18next.t("event_name-registration", Mailer.interpolations).toString(),
|
||||
text: body_txt,
|
||||
html: body_html
|
||||
};
|
||||
await this.sendMail(mail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for sending a selfservice link forgotten mail from the runner_forgot template.
|
||||
* @param to_address The address the mail will be sent to. Should always get pulled from a runner object.
|
||||
* @param token The runner's selfservice token - will be combined with the app_url to generate a selfservice profile link.
|
||||
*/
|
||||
public async sendSelfserviceForgottenMail(to_address: string, token: string, locale: string = "en") {
|
||||
await i18next.changeLanguage(locale);
|
||||
token = Buffer.from(token).toString("base64");
|
||||
|
||||
const replacements = {
|
||||
recipient_mail: to_address,
|
||||
copyright_owner: config.copyright_owner,
|
||||
link_imprint: `${config.app_url}/imprint`,
|
||||
link_privacy: `${config.app_url}/privacy`,
|
||||
selfservice_link: `${config.app_url}/selfservice/profile/${token}`,
|
||||
forgot_link: `${config.app_url}/selfservice/`,
|
||||
contact_mail: config.contact_mail,
|
||||
event_name: config.event_name
|
||||
}
|
||||
|
||||
const template_html = Handlebars.compile(fs.readFileSync(__dirname + '/templates/runner_forgot.html', { encoding: 'utf8' }));
|
||||
const template_txt = Handlebars.compile(fs.readFileSync(__dirname + '/templates/runner_forgot.txt', { encoding: 'utf8' }));
|
||||
const body_html = template_html(replacements);
|
||||
const body_txt = template_txt(replacements);
|
||||
|
||||
const mail: MailOptions = {
|
||||
to: to_address,
|
||||
subject: i18next.t("your-event_name-profile", Mailer.interpolations).toString(),
|
||||
text: body_txt,
|
||||
html: body_html
|
||||
};
|
||||
await this.sendMail(mail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper function for sending a mail via this object's transporter.
|
||||
* @param mail MailOptions object containing the
|
||||
*/
|
||||
public async sendMail(mail: MailOptions) {
|
||||
mail.from = config.mail_from;
|
||||
await this.transport.sendMail(mail);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
import { MetadataArgsStorage } from 'routing-controllers';
|
||||
import { routingControllersToSpec } from 'routing-controllers-openapi';
|
||||
import { config } from './config';
|
||||
|
||||
/**
|
||||
* This function generates a the openapi spec from route metadata and type schemas.
|
||||
* @param storage MetadataArgsStorage object generated by routing-controllers.
|
||||
* @param schemas MetadataArgsStorage object generated by class-validator-jsonschema.
|
||||
*/
|
||||
export function generateSpec(storage: MetadataArgsStorage, schemas) {
|
||||
return routingControllersToSpec(
|
||||
storage,
|
||||
{},
|
||||
{
|
||||
components: {
|
||||
schemas,
|
||||
"securitySchemes": {
|
||||
"AuthToken": {
|
||||
"type": "apiKey",
|
||||
"in": "query",
|
||||
"name": "key",
|
||||
description: "A simple api key. See the README's env section for more details."
|
||||
}
|
||||
}
|
||||
},
|
||||
info: {
|
||||
description: "The the API for the LfK! mailer.",
|
||||
title: "LfK! mailer API",
|
||||
version: config.version
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
import consola from "consola";
|
||||
import "reflect-metadata";
|
||||
import { createExpressServer } from "routing-controllers";
|
||||
import { config, e as errors } from './config';
|
||||
import loaders from "./loaders/index";
|
||||
import AuthChecker from './middlewares/AuthChecker';
|
||||
import { ErrorHandler } from './middlewares/ErrorHandler';
|
||||
|
||||
const CONTROLLERS_FILE_EXTENSION = process.env.NODE_ENV === 'production' ? 'js' : 'ts';
|
||||
const app = createExpressServer({
|
||||
middlewares: [ErrorHandler],
|
||||
authorizationChecker: AuthChecker,
|
||||
development: config.development,
|
||||
cors: true,
|
||||
controllers: [`${__dirname}/controllers/*.${CONTROLLERS_FILE_EXTENSION}`],
|
||||
});
|
||||
|
||||
async function main() {
|
||||
await loaders(app);
|
||||
app.listen(config.internal_port, () => {
|
||||
consola.success(
|
||||
`⚡️[server]: Server is running at http://localhost:${config.internal_port}`
|
||||
);
|
||||
});
|
||||
}
|
||||
if (errors === 0) {
|
||||
main();
|
||||
} else {
|
||||
consola.error("error");
|
||||
// something's wrong
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
import consola from "consola";
|
||||
import { config as configDotenv } from 'dotenv';
|
||||
|
||||
configDotenv();
|
||||
export const config = {
|
||||
internal_port: parseInt(process.env.APP_PORT) || 4010,
|
||||
development: process.env.NODE_ENV === "production",
|
||||
version: process.env.VERSION || require('../package.json').version,
|
||||
api_key: getApiKey(),
|
||||
app_url: process.env.APP_URL || "http://localhost:8080",
|
||||
mail_server: process.env.MAIL_SERVER,
|
||||
mail_port: Number(process.env.MAIL_PORT) || 25,
|
||||
mail_user: process.env.MAIL_USER,
|
||||
mail_password: process.env.MAIL_PASSWORD,
|
||||
mail_from: process.env.MAIL_FROM,
|
||||
privacy_url: process.env.PRIVACY_URL || "/privacy",
|
||||
imprint_url: process.env.IMPRINT_URL || "/imprint",
|
||||
copyright_owner: process.env.COPYRIGHT_OWNER || "LfK!",
|
||||
event_name: process.env.EVENT_NAME || "Testing 4 Kaya!",
|
||||
contact_mail: process.env.CONTACT_MAIL || process.env.MAIL_FROM,
|
||||
}
|
||||
let errors = 0
|
||||
if (typeof config.internal_port !== "number") {
|
||||
errors++
|
||||
}
|
||||
if (typeof config.development !== "boolean") {
|
||||
errors++
|
||||
}
|
||||
|
||||
function getApiKey(): string {
|
||||
const key = process.env.API_KEY;
|
||||
if (!key) {
|
||||
consola.info("No API key set - generating a random one...");
|
||||
let result = '';
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
const charactersLength = characters.length;
|
||||
for (var i = 0; i < 64; i++) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
consola.info(`API KEY: ${result}`)
|
||||
return result;
|
||||
}
|
||||
if (key.length < 64) {
|
||||
consola.error(`API key is too short - minimum: 64, current: ${key.length}`)
|
||||
throw new Error("API_KEY too short.")
|
||||
}
|
||||
return key
|
||||
}
|
||||
export let e = errors
|
||||
@@ -0,0 +1,15 @@
|
||||
export const config = {
|
||||
smtp: {
|
||||
host: process.env.SMTP_HOST || 'smtp.mailtrap.io',
|
||||
port: Number(process.env.SMTP_PORT) || 2525,
|
||||
user: process.env.SMTP_USER || '',
|
||||
pass: process.env.SMTP_PASS || ''
|
||||
},
|
||||
email: {
|
||||
from: process.env.EMAIL_FROM || 'noreply@example.com',
|
||||
replyTo: process.env.EMAIL_REPLYTO || 'noreply@example.com',
|
||||
},
|
||||
redis: {
|
||||
url: process.env.REDIS_URL || 'redis://localhost:6379'
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
import { Authorized, Body, JsonController, Post, QueryParam } from 'routing-controllers';
|
||||
import { OpenAPI } from 'routing-controllers-openapi';
|
||||
import { Mailer } from '../Mailer';
|
||||
import { locales } from '../models/LocaleEnum';
|
||||
import { MailTypes } from '../models/MailTypeEnum';
|
||||
import { ResetMail } from '../models/ResetMail';
|
||||
import { SuccessResponse } from '../models/SuccessResponse';
|
||||
import { WelcomeMail } from '../models/WelcomeMail';
|
||||
|
||||
/**
|
||||
* The mail controller handels all endpoints concerning Mail sending.
|
||||
*/
|
||||
@JsonController()
|
||||
@Authorized()
|
||||
@OpenAPI({ security: [{ "AuthToken": [] }] })
|
||||
export class MailController {
|
||||
private mailer: Mailer = new Mailer();
|
||||
private initialized: boolean = false;
|
||||
|
||||
@Post('/reset')
|
||||
@OpenAPI({ description: "Sends reset mails", parameters: [{ in: "query", name: "locale", schema: { type: "string", enum: ["de", "en"] } }] })
|
||||
async sendReset(@Body({ validate: true }) mailOptions: ResetMail, @QueryParam("locale") locale: locales) {
|
||||
if (!this.initialized) {
|
||||
await this.mailer.init();
|
||||
this.initialized = true;
|
||||
}
|
||||
try {
|
||||
this.mailer.sendResetMail(mailOptions.address, mailOptions.resetKey, locale?.toString())
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
return new SuccessResponse(MailTypes.PASSWORD_RESET, locale);
|
||||
}
|
||||
|
||||
@Post('/test')
|
||||
@OpenAPI({ description: "Sends test mails", parameters: [{ in: "query", name: "locale", schema: { type: "string", enum: ["de", "en"] } }] })
|
||||
async sendTest(@QueryParam("locale") locale: locales) {
|
||||
if (!this.initialized) {
|
||||
await this.mailer.init();
|
||||
this.initialized = true;
|
||||
}
|
||||
try {
|
||||
this.mailer.sendTestMail(locale?.toString())
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
throw error;
|
||||
}
|
||||
return new SuccessResponse(MailTypes.TEST, locale);
|
||||
}
|
||||
|
||||
@Post('/registration')
|
||||
@OpenAPI({ description: "Sends registration welcome mails", parameters: [{ in: "query", name: "locale", schema: { type: "string", enum: ["de", "en"] } }] })
|
||||
async sendRegistrationWelcome(@Body({ validate: true }) mailOptions: WelcomeMail, @QueryParam("locale") locale: locales) {
|
||||
if (!this.initialized) {
|
||||
await this.mailer.init();
|
||||
this.initialized = true;
|
||||
}
|
||||
try {
|
||||
this.mailer.sendWelcomeMail(mailOptions.address, mailOptions.selfserviceToken, locale?.toString())
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
throw error;
|
||||
}
|
||||
return new SuccessResponse(MailTypes.RUNNER_WELCOME, locale);
|
||||
}
|
||||
|
||||
@Post('/registration_forgot')
|
||||
@OpenAPI({ description: "Sends selfservice link forgotten mails", parameters: [{ in: "query", name: "locale", schema: { type: "string", enum: ["de", "en"] } }] })
|
||||
async sendSelfserviceForgotten(@Body({ validate: true }) mailOptions: WelcomeMail, @QueryParam("locale") locale: locales) {
|
||||
if (!this.initialized) {
|
||||
await this.mailer.init();
|
||||
this.initialized = true;
|
||||
}
|
||||
try {
|
||||
this.mailer.sendSelfserviceForgottenMail(mailOptions.address, mailOptions.selfserviceToken, locale?.toString())
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
throw error;
|
||||
}
|
||||
return new SuccessResponse(MailTypes.RUNNER_FORGOT, locale);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { Get, JsonController } from 'routing-controllers';
|
||||
import { OpenAPI } from 'routing-controllers-openapi';
|
||||
import { config } from '../config';
|
||||
|
||||
/**
|
||||
* The statuscontroller provides simple endpoints concerning basic information about the server.
|
||||
*/
|
||||
@JsonController()
|
||||
export class StatusController {
|
||||
@Get('/version')
|
||||
@OpenAPI({ description: "A very basic endpoint that just returns the curent package version." })
|
||||
getVersion() {
|
||||
return {
|
||||
"version": config.version
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { IsString } from 'class-validator'
|
||||
|
||||
/**
|
||||
* Error to throw when a permission couldn't be found.
|
||||
*/
|
||||
export class MailServerConfigError extends Error {
|
||||
@IsString()
|
||||
name = "MailServerConfigError"
|
||||
|
||||
@IsString()
|
||||
message = "The SMTP server you provided couldn't be reached!"
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Hono } from 'hono'
|
||||
import { logger } from 'hono/logger'
|
||||
import { prettyJSON } from 'hono/pretty-json'
|
||||
import { emailRouter } from './routes/email'
|
||||
import { createSwaggerUI } from './swagger'
|
||||
|
||||
const app = new Hono()
|
||||
|
||||
app.use('*', logger())
|
||||
app.use('*', prettyJSON())
|
||||
|
||||
if ((process.env.AUTHKEY || "") === "") {
|
||||
console.warn("process.env.AUTHKEY was not provided!");
|
||||
}
|
||||
|
||||
app.route('/api/v1/email', emailRouter)
|
||||
app.get('/docs', createSwaggerUI())
|
||||
app.get('/swagger', createSwaggerUI())
|
||||
|
||||
const port = process.env.PORT || 3000
|
||||
console.log(`Server is running on port ${port}`)
|
||||
|
||||
export default {
|
||||
port,
|
||||
fetch: app.fetch
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import { Application } from "express";
|
||||
/**
|
||||
* Loader for express related configurations.
|
||||
* Configures proxy trusts, globally used middlewares and other express features.
|
||||
*/
|
||||
export default async (app: Application) => {
|
||||
app.enable('trust proxy');
|
||||
app.disable('x-powered-by');
|
||||
app.disable('x-served-by');
|
||||
return app;
|
||||
};
|
||||
@@ -1,13 +0,0 @@
|
||||
import { Application } from "express";
|
||||
import expressLoader from "./express";
|
||||
import openapiLoader from "./openapi";
|
||||
|
||||
/**
|
||||
* Index Loader that executes the other loaders in the right order.
|
||||
* This basicly exists for abstraction and a overall better dev experience.
|
||||
*/
|
||||
export default async (app: Application) => {
|
||||
await openapiLoader(app);
|
||||
await expressLoader(app);
|
||||
return app;
|
||||
};
|
||||
@@ -1,24 +0,0 @@
|
||||
import { validationMetadatasToSchemas } from "@odit/class-validator-jsonschema";
|
||||
import express, { Application } from "express";
|
||||
import path from 'path';
|
||||
import { getMetadataArgsStorage } from "routing-controllers";
|
||||
import { generateSpec } from '../apispec';
|
||||
|
||||
/**
|
||||
* Loader for everything openapi related - from creating the schema to serving it via a static route and swaggerUiExpress.
|
||||
* All auth schema related stuff also has to be configured here
|
||||
*/
|
||||
export default async (app: Application) => {
|
||||
const storage = getMetadataArgsStorage();
|
||||
const schemas = validationMetadatasToSchemas({
|
||||
refPointerPrefix: "#/components/schemas/",
|
||||
});
|
||||
|
||||
//Spec creation based on the previously created schemas
|
||||
const spec = generateSpec(storage, schemas);
|
||||
app.get(["/docs/openapi.json", "/docs/swagger.json"], (req, res) => {
|
||||
res.json(spec);
|
||||
});
|
||||
app.use('/docs', express.static(path.join(__dirname, '../static/docs'), { index: "index.html", extensions: ['html'] }));
|
||||
return app;
|
||||
};
|
||||
@@ -1,31 +0,0 @@
|
||||
{
|
||||
"a-password-reset-for-your-account-got-requested": "Ein Passwort Reset wurde für dein Konto beantragt.",
|
||||
"all-rights-reserved": "Alle Rechte vorbehalten",
|
||||
"event_name-registration": "{{event_name}} Registrierung",
|
||||
"if-you-didnt-register-yourself-you-should-contact-us-to-get-your-data-removed-from-our-systems": "Solltest du dich nicht selbst registriert haben, sende uns bitte eine Mail und wir entfernen deine Daten aus unserem System: ",
|
||||
"if-you-didnt-request-the-reset-please-ignore-this-mail": "Solltest du den Reset nicht beantragt haben kannst du diese Mail einfach ignorieren.",
|
||||
"if-you-ever-loose-the-link-you-can-request-a-new-one-by-visiting-our-website": "Auf unserer Website kannst du jederzeit einen neuen Login-Link beantragen:",
|
||||
"imprint": "Impressum",
|
||||
"lfk-mail-test": "{{copyright_owner}} - Mail test",
|
||||
"lfk-password-reset": "{{copyright_owner}} - Passwort zurücksetzen",
|
||||
"password-reset": "Passwort zurücksetzen",
|
||||
"privacy": "Datenschutz",
|
||||
"reset-password": "Passwort zurücksetzen",
|
||||
"test-mail": "Test mail",
|
||||
"thank-you-for-requesting-a-new-link-to-your-event_name-runner-profile": "Danke, dass du einen neuen Profillink für das {{event_name}} Läuferstem beantragt hast.",
|
||||
"thanks-for-registering-and-welcome-to-the-event_name": "Vielen Dank für die Registrierung beim {{event_name}}",
|
||||
"the-only-thing-you-have-to-do-now-is-to-bring-your-registration-code-with-you": "Bitte bringe deinen Registrierungscode zum Lauf am 21.04.2023 mit.",
|
||||
"this-is-a-test-mail-triggered-by-an-admin-in-the-lfk-backend": "Das ist eine Testmail, die von einem Admin im LfK! Backend erzeugt wurde.",
|
||||
"this-mail-was-sent-to-recipient_mail-because-someone-request-a-mail-test-for-this-mail-address": "Du bekommst diese Mail, weil jemand eine Testmail für deine Mail-Adresse angefragt hat.",
|
||||
"this-mail-was-sent-to-you-because-someone-request-a-password-reset-for-a-account-linked-to-the-mail-address": "Du bekommst diese E-Mail, weil jemand einen Passwort-Reset für deinen Account beantragt hat.",
|
||||
"this-mail-was-sent-to-you-because-someone-requested-a-new-link-to-access-your-profile-for-the-event_name": "Diese E-Mail wurde an dich gesendet, weil jemand einen neuen Link angefordert hat, um auf dein {{event_name}} Profil zuzugreifen.",
|
||||
"this-mail-was-sent-to-you-because-someone-used-your-mail-address-to-register-themselfes-for-the-event_name": "Du bekommst diese Mail, weil jemand deine E-Mail-Adresse verwendet hat, um sich beim {{event_name}} zu registrieren.",
|
||||
"to-prevent-spam-you-can-only-request-a-new-link-every-24hrs": "Um Spam zu vermeiden, kannst du nur alle 24 Stunden einen neuen Link anfordern.",
|
||||
"view-my-data": "Meine Daten",
|
||||
"we-successfully-processed-your-registration": "Wir haben deine Registrierung erfolgreich verarbeitet.",
|
||||
"welcome": "Willkommen",
|
||||
"you-can-view-your-registration-code-lap-times-and-much-more-by-visiting-our-selfservice": "Deinen Registrierungscode, Rundenzeiten und vieles mehr kannst du im Selfservice einsehen:",
|
||||
"your-event_name-profile": "Dein {{event_name}} Profil",
|
||||
"your-password-wont-be-changed-until-you-click-the-reset-link-below-and-set-a-new-one": "Dein Passwort wird erst zurückgesetzt, wenn du den Reset-Link öffnest und ein neues Passwort setzt.",
|
||||
"your-profile": "Dein Profil"
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
{
|
||||
"a-password-reset-for-your-account-got-requested": "A password reset for your account got requested.",
|
||||
"all-rights-reserved": "All rights reserved.",
|
||||
"event_name-registration": "{{event_name}} Registration",
|
||||
"if-you-didnt-register-yourself-you-should-contact-us-to-get-your-data-removed-from-our-systems": "If you didn't register yourself you should contact us to get your data removed from our systems:",
|
||||
"if-you-didnt-request-the-reset-please-ignore-this-mail": "If you didn't request the reset please ignore this mail.",
|
||||
"if-you-ever-loose-the-link-you-can-request-a-new-one-by-visiting-our-website": "If you ever loose the link you can request a new one by visiting our website:",
|
||||
"imprint": "Imprint",
|
||||
"lfk-mail-test": "{{copyright_owner}} - Mail test",
|
||||
"lfk-password-reset": "{{copyright_owner}} - Password reset",
|
||||
"password-reset": "Password reset",
|
||||
"privacy": "Privacy",
|
||||
"reset-password": "Reset password",
|
||||
"test-mail": "Test mail",
|
||||
"thank-you-for-requesting-a-new-link-to-your-event_name-runner-profile": "Thank you for requesting a new link to your {{event_name}} runner profile.",
|
||||
"thanks-for-registering-and-welcome-to-the-event_name": "Thanks for registering and welcome to the {{event_name}}!",
|
||||
"the-only-thing-you-have-to-do-now-is-to-bring-your-registration-code-with-you": "The only thing you have to do now is to bring your registration code with you.",
|
||||
"this-is-a-test-mail-triggered-by-an-admin-in-the-lfk-backend": "This is a test mail triggered by an admin in the LfK! backend.",
|
||||
"this-mail-was-sent-to-recipient_mail-because-someone-request-a-mail-test-for-this-mail-address": "This mail was sent to you because someone request a mail test for this mail address.",
|
||||
"this-mail-was-sent-to-you-because-someone-request-a-password-reset-for-a-account-linked-to-the-mail-address": "This mail was sent to you because someone request a password reset for a account linked to the mail address.",
|
||||
"this-mail-was-sent-to-you-because-someone-requested-a-new-link-to-access-your-profile-for-the-event_name": "This mail was sent to you, because someone requested a new link to access your profile for the {{event_name}}.",
|
||||
"this-mail-was-sent-to-you-because-someone-used-your-mail-address-to-register-themselfes-for-the-event_name": "This mail was sent to you, because someone used your mail address to register themselves for the {{event_name}}",
|
||||
"to-prevent-spam-you-can-only-request-a-new-link-every-24hrs": "To prevent spam you can only request a new link every 24hrs.",
|
||||
"view-my-data": "View my data",
|
||||
"we-successfully-processed-your-registration": "We successfully processed your registration.",
|
||||
"welcome": "Welcome",
|
||||
"you-can-view-your-registration-code-lap-times-and-much-more-by-visiting-our-selfservice": "You can view your registration code, lap times and much more by visiting our selfservice:",
|
||||
"your-event_name-profile": "Your {{event_name}} profile",
|
||||
"your-password-wont-be-changed-until-you-click-the-reset-link-below-and-set-a-new-one": "Your password won't be changed until you click the reset link below and set a new one.",
|
||||
"your-profile": "Your profile"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { Action } from "routing-controllers";
|
||||
import { config } from '../config';
|
||||
|
||||
/**
|
||||
* Handles authentication via jwt's (Bearer authorization header) for all api endpoints using the @Authorized decorator.
|
||||
* @param action Routing-Controllers action object that provides request and response objects among other stuff.
|
||||
* @param permissions The permissions that the endpoint using @Authorized requires.
|
||||
*/
|
||||
const AuthChecker = async (action: Action) => {
|
||||
const provided_token = action.request.query.key;
|
||||
return provided_token == config.api_key;
|
||||
}
|
||||
|
||||
export default AuthChecker
|
||||
@@ -1,14 +0,0 @@
|
||||
import { ExpressErrorMiddlewareInterface, Middleware } from "routing-controllers";
|
||||
|
||||
/**
|
||||
* Our Error handling middlware that returns our custom httperrors to the user.
|
||||
*/
|
||||
@Middleware({ type: "after" })
|
||||
export class ErrorHandler implements ExpressErrorMiddlewareInterface {
|
||||
public error(error: any, request: any, response: any, next: (err: any) => any) {
|
||||
if (response.headersSent) {
|
||||
return;
|
||||
}
|
||||
response.json(error);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
export enum locales {
|
||||
de = "de",
|
||||
en = "en"
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
export enum MailTypes {
|
||||
PASSWORD_RESET = "PASSWORD_RESET",
|
||||
RUNNER_FORGOT = "RUNNER_FORGOT",
|
||||
RUNNER_WELCOME = "RUNNER_WELCOME",
|
||||
TEST = "TEST"
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
|
||||
|
||||
/**
|
||||
* Simple reset mail request class for validation and easier handling.
|
||||
*/
|
||||
export class ResetMail {
|
||||
|
||||
@IsString()
|
||||
@IsEmail()
|
||||
@IsNotEmpty()
|
||||
address: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
resetKey: string;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import { IsBoolean, IsString } from 'class-validator';
|
||||
import { locales } from './LocaleEnum';
|
||||
import { MailTypes } from './MailTypeEnum';
|
||||
|
||||
/**
|
||||
* Simple success response class to make everyone happy :)
|
||||
*/
|
||||
export class SuccessResponse {
|
||||
|
||||
@IsBoolean()
|
||||
success: boolean = true;
|
||||
|
||||
@IsString()
|
||||
message: string = "Sent!"
|
||||
|
||||
@IsString()
|
||||
locale: locales;
|
||||
|
||||
@IsString()
|
||||
type: MailTypes;
|
||||
|
||||
constructor(type: MailTypes, locale?: locales) {
|
||||
this.type = type;
|
||||
this.locale = locale || locales.en;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
|
||||
|
||||
/**
|
||||
* Simple welcome mail request class for validation and easier handling.
|
||||
*/
|
||||
export class WelcomeMail {
|
||||
|
||||
@IsString()
|
||||
@IsEmail()
|
||||
@IsNotEmpty()
|
||||
address: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
selfserviceToken: string;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import { createTransport } from "nodemailer";
|
||||
import { Queue, Worker, QueueEvents } from "bullmq";
|
||||
import { config } from "../config/env";
|
||||
import Redis from "ioredis";
|
||||
|
||||
interface EmailJob {
|
||||
to: string;
|
||||
subject: string;
|
||||
html: string;
|
||||
text: string;
|
||||
}
|
||||
|
||||
export const QUEUE_NAME = "{lfkmailqueue}";
|
||||
|
||||
const connection = new Redis(config.redis.url, {
|
||||
maxRetriesPerRequest: null,
|
||||
});
|
||||
|
||||
export const emailQueue = new Queue<EmailJob>(QUEUE_NAME, {
|
||||
connection,
|
||||
defaultJobOptions: {
|
||||
attempts: 3,
|
||||
backoff: {
|
||||
type: "exponential",
|
||||
delay: 1000,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const transporter = createTransport({
|
||||
host: config.smtp.host,
|
||||
port: config.smtp.port,
|
||||
auth: {
|
||||
user: config.smtp.user,
|
||||
pass: config.smtp.pass,
|
||||
},
|
||||
});
|
||||
|
||||
const worker = new Worker<EmailJob>(
|
||||
QUEUE_NAME,
|
||||
async (job) => {
|
||||
await transporter.sendMail({
|
||||
from: config.email.from,
|
||||
replyTo: config.email.replyTo,
|
||||
to: job.data.to,
|
||||
subject: job.data.subject,
|
||||
text: job.data.text,
|
||||
html: job.data.html,
|
||||
});
|
||||
},
|
||||
{
|
||||
connection,
|
||||
concurrency: 5,
|
||||
limiter: {
|
||||
max: 250,
|
||||
duration: 1000 * 60, // 250 emails per minute
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const queueEvents = new QueueEvents(QUEUE_NAME, { connection });
|
||||
|
||||
worker.on("completed", (job) => {
|
||||
console.log(`Email job ${job.id} completed`);
|
||||
});
|
||||
|
||||
worker.on("failed", (job, error) => {
|
||||
console.error(`Email job ${job?.id} failed:`, error);
|
||||
});
|
||||
|
||||
queueEvents.on("waiting", ({ jobId }) => {
|
||||
console.log(`Job ${jobId} is waiting`);
|
||||
});
|
||||
|
||||
process.on("SIGTERM", async () => {
|
||||
await worker.close();
|
||||
await connection.quit();
|
||||
});
|
||||
@@ -0,0 +1,83 @@
|
||||
import { Hono } from 'hono'
|
||||
import { bearerAuth } from 'hono/bearer-auth'
|
||||
import { zValidator } from '@hono/zod-validator'
|
||||
import { z } from 'zod'
|
||||
import { EmailService } from '../services/email'
|
||||
import { getEmailTemplate } from '../templates'
|
||||
import { Language } from '../types'
|
||||
import { toBuffer } from 'bwip-js/node'
|
||||
|
||||
const emailRouter = new Hono()
|
||||
const emailService = new EmailService()
|
||||
|
||||
const sendEmailSchema = z.object({
|
||||
to: z.string().email(),
|
||||
templateName: z.string(),
|
||||
language: z.enum(['en', 'de']),
|
||||
data: z.record(z.any())
|
||||
})
|
||||
|
||||
async function generateBarcodeDataURL(data) {
|
||||
return `https://barcodeapi.org/api/128/${data}`
|
||||
const buffer = await toBuffer({
|
||||
bcid: 'code128',
|
||||
text: data,
|
||||
scale: 3,
|
||||
height: 10,
|
||||
includetext: true,
|
||||
textxalign: 'center',
|
||||
});
|
||||
|
||||
const base64Data = buffer.toString('base64');
|
||||
const dataURL = `data:image/png;base64,${base64Data}`;
|
||||
|
||||
return dataURL;
|
||||
}
|
||||
|
||||
emailRouter.post('/', bearerAuth({ token: process.env.AUTHKEY }), zValidator('json', sendEmailSchema), async (c) => {
|
||||
let { to, templateName, language, data } = c.req.valid('json')
|
||||
|
||||
try {
|
||||
const template = getEmailTemplate(templateName, language as Language)
|
||||
if (templateName === "welcome") {
|
||||
if (data.name && data.link && data.barcode_content) {
|
||||
const dataURL = await generateBarcodeDataURL(data.barcode_content);
|
||||
data.barcode_url = dataURL;
|
||||
} else {
|
||||
return c.json({ success: false, error: "required params 'data.name', 'data.link', 'data.barcode_content' not provided" }, 406)
|
||||
}
|
||||
}
|
||||
if (templateName === "password-reset") {
|
||||
if (data.token) {
|
||||
console.log(data);
|
||||
data.reset_link = `${process.env.FRONTEND_URL}/reset/${(Buffer.from(data.token)).toString("base64")}`
|
||||
} else {
|
||||
return c.json({ success: false, error: "'data.token' not provided" }, 406)
|
||||
}
|
||||
}
|
||||
data.event_date = process.env.EVENT_DATE
|
||||
data.event_name = process.env.EVENT_NAME
|
||||
await emailService.sendEmail({
|
||||
to,
|
||||
subject: template.subject(data),
|
||||
html: template.html(data),
|
||||
text: template.text(data)
|
||||
})
|
||||
|
||||
return c.json({ success: true })
|
||||
} catch (error) {
|
||||
return c.json({ success: false, error: (error as Error).message }, 400)
|
||||
}
|
||||
})
|
||||
|
||||
// Add queue status endpoint
|
||||
emailRouter.get('/status', bearerAuth({ token: process.env.AUTHKEY }), async (c) => {
|
||||
try {
|
||||
const status = await emailService.getQueueStatus()
|
||||
return c.json(status)
|
||||
} catch (error) {
|
||||
return c.json({ error: (error as Error).message }, 500)
|
||||
}
|
||||
})
|
||||
|
||||
export { emailRouter }
|
||||
@@ -0,0 +1,40 @@
|
||||
import { emailQueue } from '../queues/email.queue'
|
||||
import { config } from '../config/env'
|
||||
|
||||
interface EmailOptions {
|
||||
to: string
|
||||
subject: string
|
||||
html: string
|
||||
text: string
|
||||
}
|
||||
|
||||
export class EmailService {
|
||||
async sendEmail(options: EmailOptions): Promise<void> {
|
||||
const email = {
|
||||
from: config.email.from,
|
||||
...options
|
||||
}
|
||||
|
||||
// Add to queue instead of sending directly
|
||||
await emailQueue.add('send-email', email, {
|
||||
removeOnComplete: true,
|
||||
// removeOnFail: 1000
|
||||
})
|
||||
}
|
||||
|
||||
async getQueueStatus() {
|
||||
const [waiting, active, completed, failed] = await Promise.all([
|
||||
emailQueue.getWaitingCount(),
|
||||
emailQueue.getActiveCount(),
|
||||
emailQueue.getCompletedCount(),
|
||||
emailQueue.getFailedCount()
|
||||
])
|
||||
|
||||
return {
|
||||
waiting,
|
||||
active,
|
||||
completed,
|
||||
failed
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>API Docs</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg-color: #fff;
|
||||
--bg-secondary-color: #f3f3f6;
|
||||
--color-primary: #14854f;
|
||||
--color-lightGrey: #d2d6dd;
|
||||
--color-grey: #747681;
|
||||
--color-darkGrey: #3f4144;
|
||||
--color-error: #d43939;
|
||||
--color-success: #28bd14;
|
||||
--grid-maxWidth: 120rem;
|
||||
--grid-gutter: 2rem;
|
||||
--font-size: 1.6rem;
|
||||
--font-color: #333;
|
||||
--font-family-sans: -apple-system, BlinkMacSystemFont, Avenir, "Avenir Next", "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
||||
--font-family-mono: monaco, "Consolas", "Lucida Console", monospace
|
||||
}
|
||||
|
||||
html {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
font-size: 62.5%;
|
||||
line-height: 1.15;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%
|
||||
}
|
||||
|
||||
*,
|
||||
:after,
|
||||
:before {
|
||||
-webkit-box-sizing: inherit;
|
||||
box-sizing: inherit
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--bg-color);
|
||||
line-height: 1.6;
|
||||
font-size: var(--font-size);
|
||||
color: var(--font-color);
|
||||
font-family: Segoe UI, Helvetica Neue, sans-serif;
|
||||
font-family: var(--font-family-sans);
|
||||
margin: 0;
|
||||
padding: 0
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: 500;
|
||||
margin: .35em 0 .7em
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.5em
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-primary);
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
a:hover:not(.button) {
|
||||
opacity: .75
|
||||
}
|
||||
|
||||
input:not([type=checkbox]):not([type=radio]):not([type=submit]):not([type=color]):not([type=button]):not([type=reset]):not(:disabled):hover {
|
||||
border-color: var(--color-grey)
|
||||
}
|
||||
|
||||
::-webkit-input-placeholder {
|
||||
color: #bdbfc4
|
||||
}
|
||||
|
||||
::-moz-placeholder {
|
||||
color: #bdbfc4
|
||||
}
|
||||
|
||||
:-ms-input-placeholder {
|
||||
color: #bdbfc4
|
||||
}
|
||||
|
||||
::-ms-input-placeholder {
|
||||
color: #bdbfc4
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex
|
||||
}
|
||||
|
||||
.tabs a {
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
.tabs>a {
|
||||
padding: 1rem 2rem;
|
||||
-webkit-box-flex: 0;
|
||||
-ms-flex: 0 1 auto;
|
||||
flex: 0 1 auto;
|
||||
color: var(--color-darkGrey);
|
||||
border-bottom: 2px solid var(--color-lightGrey);
|
||||
text-align: center
|
||||
}
|
||||
|
||||
.tabs>a:hover {
|
||||
opacity: 1;
|
||||
border-bottom: 2px solid var(--color-darkGrey)
|
||||
}
|
||||
|
||||
.is-vertical-align {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center
|
||||
}
|
||||
|
||||
.is-center {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center
|
||||
}
|
||||
|
||||
.is-center {
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="hero">
|
||||
<div class="logo is-center is-vertical-align">
|
||||
<h3>API Docs</h3>
|
||||
</div>
|
||||
<nav class="tabs is-center">
|
||||
<a href="./redoc">ReDoc</a>
|
||||
<a href="./swaggerui">SwaggerUI</a>
|
||||
<a href="./rapidoc">RapiDoc</a>
|
||||
<a href="./openapi.json">Raw Spec (json)</a>
|
||||
</nav>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Vendored
-220
@@ -1,220 +0,0 @@
|
||||
/*!
|
||||
* RapiDoc 8.4.3 - WebComponent to View OpenAPI docs
|
||||
* License: MIT
|
||||
* Repo : https://github.com/mrin9/RapiDoc
|
||||
* Author : Mrinmoy Majumdar
|
||||
*/!function(e){var t=window.webpackHotUpdate;window.webpackHotUpdate=function(e,n){!function(e,t){if(!w[e]||!x[e])return;for(var n in x[e]=!1,t)Object.prototype.hasOwnProperty.call(t,n)&&(h[n]=t[n]);0==--g&&0===y&&A()}(e,n),t&&t(e,n)};var n,r=!0,o="b7be87fff176cf5e55c8",i={},a=[],s=[];function c(e){var t=T[e];if(!t)return C;var r=function(r){return t.hot.active?(T[r]?-1===T[r].parents.indexOf(e)&&T[r].parents.push(e):(a=[e],n=r),-1===t.children.indexOf(r)&&t.children.push(r)):(console.warn("[HMR] unexpected require("+r+") from disposed module "+e),a=[]),C(r)},o=function(e){return{configurable:!0,enumerable:!0,get:function(){return C[e]},set:function(t){C[e]=t}}};for(var i in C)Object.prototype.hasOwnProperty.call(C,i)&&"e"!==i&&"t"!==i&&Object.defineProperty(r,i,o(i));return r.e=function(e){return"ready"===p&&f("prepare"),y++,C.e(e).then(t,(function(e){throw t(),e}));function t(){y--,"prepare"===p&&(b[e]||O(e),0===y&&0===g&&A())}},r.t=function(e,t){return 1&t&&(e=r(e)),C.t(e,-2&t)},r}function l(t){var r={_acceptedDependencies:{},_declinedDependencies:{},_selfAccepted:!1,_selfDeclined:!1,_selfInvalidated:!1,_disposeHandlers:[],_main:n!==t,active:!0,accept:function(e,t){if(void 0===e)r._selfAccepted=!0;else if("function"==typeof e)r._selfAccepted=e;else if("object"==typeof e)for(var n=0;n<e.length;n++)r._acceptedDependencies[e[n]]=t||function(){};else r._acceptedDependencies[e]=t||function(){}},decline:function(e){if(void 0===e)r._selfDeclined=!0;else if("object"==typeof e)for(var t=0;t<e.length;t++)r._declinedDependencies[e[t]]=!0;else r._declinedDependencies[e]=!0},dispose:function(e){r._disposeHandlers.push(e)},addDisposeHandler:function(e){r._disposeHandlers.push(e)},removeDisposeHandler:function(e){var t=r._disposeHandlers.indexOf(e);t>=0&&r._disposeHandlers.splice(t,1)},invalidate:function(){switch(this._selfInvalidated=!0,p){case"idle":(h={})[t]=e[t],f("ready");break;case"ready":j(t);break;case"prepare":case"check":case"dispose":case"apply":(m=m||[]).push(t)}},check:S,apply:E,status:function(e){if(!e)return p;u.push(e)},addStatusHandler:function(e){u.push(e)},removeStatusHandler:function(e){var t=u.indexOf(e);t>=0&&u.splice(t,1)},data:i[t]};return n=void 0,r}var u=[],p="idle";function f(e){p=e;for(var t=0;t<u.length;t++)u[t].call(null,e)}var d,h,v,m,g=0,y=0,b={},x={},w={};function k(e){return+e+""===e?+e:e}function S(e){if("idle"!==p)throw new Error("check() is only allowed in idle status");return r=e,f("check"),(t=1e4,t=t||1e4,new Promise((function(e,n){if("undefined"==typeof XMLHttpRequest)return n(new Error("No browser support"));try{var r=new XMLHttpRequest,i=C.p+""+o+".hot-update.json";r.open("GET",i,!0),r.timeout=t,r.send(null)}catch(e){return n(e)}r.onreadystatechange=function(){if(4===r.readyState)if(0===r.status)n(new Error("Manifest request to "+i+" timed out."));else if(404===r.status)e();else if(200!==r.status&&304!==r.status)n(new Error("Manifest request to "+i+" failed."));else{try{var t=JSON.parse(r.responseText)}catch(e){return void n(e)}e(t)}}}))).then((function(e){if(!e)return f(_()?"ready":"idle"),null;x={},b={},w=e.c,v=e.h,f("prepare");var t=new Promise((function(e,t){d={resolve:e,reject:t}}));h={};return O(0),"prepare"===p&&0===y&&0===g&&A(),t}));var t}function O(e){w[e]?(x[e]=!0,g++,function(e){var t=document.createElement("script");t.charset="utf-8",t.src=C.p+""+e+"."+o+".hot-update.js",document.head.appendChild(t)}(e)):b[e]=!0}function A(){f("ready");var e=d;if(d=null,e)if(r)Promise.resolve().then((function(){return E(r)})).then((function(t){e.resolve(t)}),(function(t){e.reject(t)}));else{var t=[];for(var n in h)Object.prototype.hasOwnProperty.call(h,n)&&t.push(k(n));e.resolve(t)}}function E(t){if("ready"!==p)throw new Error("apply() is only allowed in ready status");return function t(r){var s,c,l,u,p;function d(e){for(var t=[e],n={},r=t.map((function(e){return{chain:[e],id:e}}));r.length>0;){var o=r.pop(),i=o.id,a=o.chain;if((u=T[i])&&(!u.hot._selfAccepted||u.hot._selfInvalidated)){if(u.hot._selfDeclined)return{type:"self-declined",chain:a,moduleId:i};if(u.hot._main)return{type:"unaccepted",chain:a,moduleId:i};for(var s=0;s<u.parents.length;s++){var c=u.parents[s],l=T[c];if(l){if(l.hot._declinedDependencies[i])return{type:"declined",chain:a.concat([c]),moduleId:i,parentId:c};-1===t.indexOf(c)&&(l.hot._acceptedDependencies[i]?(n[c]||(n[c]=[]),g(n[c],[i])):(delete n[c],t.push(c),r.push({chain:a.concat([c]),id:c})))}}}}return{type:"accepted",moduleId:e,outdatedModules:t,outdatedDependencies:n}}function g(e,t){for(var n=0;n<t.length;n++){var r=t[n];-1===e.indexOf(r)&&e.push(r)}}_();var y={},b=[],x={},S=function(){console.warn("[HMR] unexpected require("+A.moduleId+") to disposed module")};for(var O in h)if(Object.prototype.hasOwnProperty.call(h,O)){var A;p=k(O),A=h[O]?d(p):{type:"disposed",moduleId:O};var E=!1,j=!1,I=!1,P="";switch(A.chain&&(P="\nUpdate propagation: "+A.chain.join(" -> ")),A.type){case"self-declined":r.onDeclined&&r.onDeclined(A),r.ignoreDeclined||(E=new Error("ALine truncated
|
||||
/**
|
||||
* Prism: Lightweight, robust, elegant syntax highlighting
|
||||
*
|
||||
* @license MIT <https://opensource.org/licenses/MIT>
|
||||
* @author Lea Verou <https://lea.verou.me>
|
||||
* @namespace
|
||||
* @public
|
||||
*/e.exports&&(e.exports=n),void 0!==t&&(t.Prism=n),n.languages.markup={comment:/<!--[\s\S]*?-->/,prolog:/<\?[\s\S]+?\?>/,doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/,name:/[^\s<>'"]+/}},cdata:/<!\[CDATA\[[\s\S]*?]]>/i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},n.languages.markup.tag.inside["attr-value"].inside.entity=n.languages.markup.entity,n.languages.markup.doctype.inside["internal-subset"].inside=n.languages.markup,n.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(n.languages.markup.tag,"addInlined",{value:function(e,t){var r={};r["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:n.languages[t]},r.cdata=/^<!\[CDATA\[|\]\]>$/i;var o={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:r}};o["language-"+t]={pattern:/[\s\S]+/,inside:n.languages[t]};var i={};i[e]={pattern:RegExp(/(<__[\s\S]*?>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:o},n.languages.insertBefore("markup","cdata",i)}}),n.languages.html=n.languages.markup,n.languages.mathml=n.languages.markup,n.languages.svg=n.languages.markup,n.languages.xml=n.languages.extend("markup",{}),n.languages.ssml=n.languages.xml,n.languages.atom=n.languages.xml,n.languages.rss=n.languages.xml,function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+[\s\S]*?(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\((?!\s*\))\s*)(?:[^()]|\((?:[^()]|\([^()]*\))*\))+?(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:RegExp("[^{}\\s](?:[^{};\"']|"+t.source+")*?(?=\\s*\\{)"),string:{pattern:t,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),e.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:n.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:e.languages.css}},alias:"language-css"}},n.tag))}(n),n.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},n.languages.javascript=n.languages.extend("clike",{"class-name":[n.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|})\s*)(?:catch|finally)\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|(?:get|set)(?=\s*[\[$\w\xA0-\uFFFF])|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],number:/\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)Line truncated
|
||||
/*!
|
||||
* The buffer module from node.js, for the browser.
|
||||
*
|
||||
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
|
||||
* @license MIT
|
||||
*/
|
||||
var r=n(302),o=n(303),i=n(180);function a(){return c.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(e,t){if(a()<t)throw new RangeError("Invalid typed array length");return c.TYPED_ARRAY_SUPPORT?(e=new Uint8Array(t)).__proto__=c.prototype:(null===e&&(e=new c(t)),e.length=t),e}function c(e,t,n){if(!(c.TYPED_ARRAY_SUPPORT||this instanceof c))return new c(e,t,n);if("number"==typeof e){if("string"==typeof t)throw new Error("If encoding is specified then the first argument must be a string");return p(this,e)}return l(this,e,t,n)}function l(e,t,n,r){if("number"==typeof t)throw new TypeError('"value" argument must not be a number');return"undefined"!=typeof ArrayBuffer&&t instanceof ArrayBuffer?function(e,t,n,r){if(t.byteLength,n<0||t.byteLength<n)throw new RangeError("'offset' is out of bounds");if(t.byteLength<n+(r||0))throw new RangeError("'length' is out of bounds");t=void 0===n&&void 0===r?new Uint8Array(t):void 0===r?new Uint8Array(t,n):new Uint8Array(t,n,r);c.TYPED_ARRAY_SUPPORT?(e=t).__proto__=c.prototype:e=f(e,t);return e}(e,t,n,r):"string"==typeof t?function(e,t,n){"string"==typeof n&&""!==n||(n="utf8");if(!c.isEncoding(n))throw new TypeError('"encoding" must be a valid string encoding');var r=0|h(t,n),o=(e=s(e,r)).write(t,n);o!==r&&(e=e.slice(0,o));return e}(e,t,n):function(e,t){if(c.isBuffer(t)){var n=0|d(t.length);return 0===(e=s(e,n)).length||t.copy(e,0,0,n),e}if(t){if("undefined"!=typeof ArrayBuffer&&t.buffer instanceof ArrayBuffer||"length"in t)return"number"!=typeof t.length||(r=t.length)!=r?s(e,0):f(e,t);if("Buffer"===t.type&&i(t.data))return f(e,t.data)}var r;throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")}(e,t)}function u(e){if("number"!=typeof e)throw new TypeError('"size" argument must be a number');if(e<0)throw new RangeError('"size" argument must not be negative')}function p(e,t){if(u(t),e=s(e,t<0?0:0|d(t)),!c.TYPED_ARRAY_SUPPORT)for(var n=0;n<t;++n)e[n]=0;return e}function f(e,t){var n=t.length<0?0:0|d(t.length);e=s(e,n);for(var r=0;r<n;r+=1)e[r]=255&t[r];return e}function d(e){if(e>=a())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a().toString(16)+" bytes");return 0|e}function h(e,t){if(c.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return F(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return z(e).length;default:if(r)return F(e).length;t=(""+t).toLowerCase(),r=!0}}function v(e,t,n){var r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return T(this,t,n);case"utf8":case"utf-8":return E(this,t,n);case"ascii":return _(this,t,n);case"latin1":case"binary":return j(this,t,n);case"base64":return A(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return C(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function m(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function g(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=o?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=c.from(t,r)),c.isBuffer(t))return 0===t.length?-1:y(e,t,n,r,o);if("number"==typeof t)return t&=255,c.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):y(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function y(e,t,n,r,o){var i,a=1,s=e.length,c=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a=2,s/=2,c/=2,n/=2}function l(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(o){var u=-1;for(i=n;i<s;i++)if(l(e,i)===l(t,-1===u?0:i-u)){if(-1===u&&(u=i),i-u+1===c)return u*a}else-1!==u&&(i-=i-u),u=-1}else for(n+c>s&&(n=s-c),i=n;i>=0;i--){for(var p=!0,f=0;f<c;f++)if(l(e,i+f)!==l(t,f)){p=!1;break}if(p)return i}return-1}function b(e,t,n,r){n=Number(n)||0;var o=e.length-n;r?(r=Number(r))>o&&(r=o):r=o;var i=t.length;if(i%2!=0)throw new TypeError("Invalid hex string");r>i/2&&(r=i/2);for(var a=0;a<r;++a){var s=parseInt(t.substr(2*a,2),16);if(isNaN(s))return a;e[n+a]=s}return a}function x(e,t,n,r){return U(F(t,e.length-n),e,n,r)}function w(e,t,n,r){return U(function(e){for(var t=[],n=0;n<e.length;++n)t.push(255&e.charCodeAt(n));return t}(t),e,n,r)}function k(e,t,n,r){return w(e,t,n,r)}function S(e,t,n,r){return U(z(t),e,n,Line truncated
|
||||
/*!
|
||||
* @description Recursive object extending
|
||||
* @author Viacheslav Lotsmanov <lotsmanov89@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2018 Viacheslav Lotsmanov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
function n(e){return e instanceof t||e instanceof Date||e instanceof RegExp}function r(e){if(e instanceof t){var n=t.alloc?t.alloc(e.length):new t(e.length);return e.copy(n),n}if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp)return new RegExp(e);throw new Error("Unexpected situation")}function o(e){var t=[];return e.forEach((function(e,i){"object"==typeof e&&null!==e?Array.isArray(e)?t[i]=o(e):n(e)?t[i]=r(e):t[i]=a({},e):t[i]=e})),t}function i(e,t){return"__proto__"===t?void 0:e[t]}var a=e.exports=function(){if(arguments.length<1||"object"!=typeof arguments[0])return!1;if(arguments.length<2)return arguments[0];var e,t,s=arguments[0],c=Array.prototype.slice.call(arguments,1);return c.forEach((function(c){"object"!=typeof c||null===c||Array.isArray(c)||Object.keys(c).forEach((function(l){return t=i(s,l),(e=i(c,l))===s?void 0:"object"!=typeof e||null===e?void(s[l]=e):Array.isArray(e)?void(s[l]=o(e)):n(e)?void(s[l]=r(e)):"object"!=typeof t||null===t||Array.isArray(t)?void(s[l]=a({},e)):void(s[l]=a(t,e))}))})),s}}).call(this,n(32).Buffer)},function(e,t,n){var r=n(606);e.exports=function(e){return r(e,5)}},function(e,t,n){e.exports=n(629)},function(e,t){var n=e.exports=function(e){return new r(e)};function r(e){this.value=e}function o(e,t,n){var r=[],o=[],s=!0;return function e(p){var f=n?i(p):p,d={},h=!0,v={node:f,node_:p,path:[].concat(r),parent:o[o.length-1],parents:o,key:r.slice(-1)[0],isRoot:0===r.length,level:r.length,circular:null,update:function(e,t){v.isRoot||(v.parent.node[v.key]=e),v.node=e,t&&(h=!1)},delete:function(e){delete v.parent.node[v.key],e&&(h=!1)},remove:function(e){c(v.parent.node)?v.parent.node.splice(v.key,1):delete v.parent.node[v.key],e&&(h=!1)},keys:null,before:function(e){d.before=e},after:function(e){d.after=e},pre:function(e){d.pre=e},post:function(e){d.post=e},stop:function(){s=!1},block:function(){h=!1}};if(!s)return v;function m(){if("object"==typeof v.node&&null!==v.node){v.keys&&v.node_===v.node||(v.keys=a(v.node)),v.isLeaf=0==v.keys.length;for(var e=0;e<o.length;e++)if(o[e].node_===p){v.circular=o[e];break}}else v.isLeaf=!0,v.keys=null;v.notLeaf=!v.isLeaf,v.notRoot=!v.isRoot}m();var g=t.call(v,v.node);return void 0!==g&&v.update&&v.update(g),d.before&&d.before.call(v,v.node),h?("object"!=typeof v.node||null===v.node||v.circular||(o.push(v),m(),l(v.keys,(function(t,o){r.push(t),d.pre&&d.pre.call(v,v.node[t],t);var i=e(v.node[t]);n&&u.call(v.node,t)&&(v.node[t]=i.node),i.isLast=o==v.keys.length-1,i.isFirst=0==o,d.post&&d.post.call(v,i),r.pop()})),o.pop()),d.after&&d.after.call(v,v.node),v):v}(e).node}function i(e){if("object"==typeof e&&null!==e){var t;if(c(e))t=[];else if("[object Date]"===s(e))t=new Date(e.getTime?e.getTime():e);else if(function(e){return"[object RegExp]"===s(e)}(e))t=new RegExp(e);else if(function(e){return"[object Error]"===s(e)}(e))t={message:e.message};else if(function(e){return"[object Boolean]"===s(e)}(e))t=new Boolean(e);else if(function(e){return"[object Number]"===s(e)}(e))t=new Number(e);else if(function(e){return"[object String]"===s(e)}(e))t=new String(e);else if(Object.create&&Object.getPrototypeOf)t=Object.create(Object.getPrototypeOf(e));else if(e.constructor===Object)t={};else{var n=e.constructor&&e.constructor.prototype||e.__proto__||{},r=function(){};r.prototype=n,t=new r}return l(a(e),(function(n){t[n]=e[n]})),t}return e}r.prototype.get=function(e){for(var t=this.value,n=0;n<e.length;n++){var r=e[n];if(!t||!u.call(t,r)){t=void 0;break}t=t[r]}return t},r.prototype.has=function(e){for(var t=this.value,n=0;n<e.length;n++){var r=e[n];if(!t||!u.call(t,r))return!1;t=t[r]}return!0},r.prototype.set=function(e,t){for(var n=this.value,r=0;r<e.length-1;r++){var o=e[r];u.call(n,o)||(n[o]={}),n=n[o]}return n[e[r]]=t,t},r.prototype.map=function(e){return o(this.value,e,!0)},r.prototype.forEach=function(e){return this.value=o(this.value,e,!1),this.value},r.prototype.reduce=function(e,t){var n=1===arguments.length,r=n?this.value:t;return this.forEach((function(t){this.isRoot&&n||(r=e.call(this,r,t))})),r},r.prototype.paths=function(){var e=[];return this.forEach((function(t){e.push(this.path)})),e},r.prototype.nodes=function(){var e=[];return this.forEach((function(t){e.push(this.node)})),e},r.prototype.clone=function(){var e=[],t=[];return function n(r){for(var o=0;o<e.length;o++)if(e[o]===r)return t[o];if("object"==typeof r&&null!==r){var s=i(r);return e.push(r),t.push(s),l(a(r),(function(e){s[e]=n(r[e])})),e.pop(),t.pop(),s}return r}(this.value)};var a=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};function s(e){return Object.prototype.toString.call(e)}var c=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)},l=function(e,t){if(e.forEach)return e.forEach(t);for(var n=0;n<e.length;n++)t(e[n],n,e)};l(a(r.prototype),(function(e){n[e]=function(t){var n=[].slice.call(arguments,1),o=new r(t);return o[e].apply(o,n)}}));var u=Object.hasOwnProperty||function(e,t){return t in e}},funLine truncated
|
||||
/*!
|
||||
* cookie
|
||||
* Copyright(c) 2012-2014 Roman Shtylman
|
||||
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/t.parse=function(e,t){if("string"!=typeof e)throw new TypeError("argument str must be a string");for(var n={},o=t||{},a=e.split(i),c=o.decode||r,l=0;l<a.length;l++){var u=a[l],p=u.indexOf("=");if(!(p<0)){var f=u.substr(0,p).trim(),d=u.substr(++p,u.length).trim();'"'==d[0]&&(d=d.slice(1,-1)),null==n[f]&&(n[f]=s(d,c))}}return n},t.serialize=function(e,t,n){var r=n||{},i=r.encode||o;if("function"!=typeof i)throw new TypeError("option encode is invalid");if(!a.test(e))throw new TypeError("argument name is invalid");var s=i(t);if(s&&!a.test(s))throw new TypeError("argument val is invalid");var c=e+"="+s;if(null!=r.maxAge){var l=r.maxAge-0;if(isNaN(l)||!isFinite(l))throw new TypeError("option maxAge is invalid");c+="; Max-Age="+Math.floor(l)}if(r.domain){if(!a.test(r.domain))throw new TypeError("option domain is invalid");c+="; Domain="+r.domain}if(r.path){if(!a.test(r.path))throw new TypeError("option path is invalid");c+="; Path="+r.path}if(r.expires){if("function"!=typeof r.expires.toUTCString)throw new TypeError("option expires is invalid");c+="; Expires="+r.expires.toUTCString()}r.httpOnly&&(c+="; HttpOnly");r.secure&&(c+="; Secure");if(r.sameSite){switch("string"==typeof r.sameSite?r.sameSite.toLowerCase():r.sameSite){case!0:c+="; SameSite=Strict";break;case"lax":c+="; SameSite=Lax";break;case"strict":c+="; SameSite=Strict";break;case"none":c+="; SameSite=None";break;default:throw new TypeError("option sameSite is invalid")}}return c};var r=decodeURIComponent,o=encodeURIComponent,i=/; */,a=/^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;function s(e,t){try{return t(e)}catch(t){return e}}},function(e,t,n){"use strict";var r=n(264),o=n.n(r),i=n(46),a={insert:"head",singleton:!1},s=o()(i.default,a);if(!i.default.locals||e.hot.invalidate){var c=i.default.locals;e.hot.accept(46,function(t){i=n(46),function(e,t,n){if(!e&&t||e&&!t)return!1;var r;for(r in e)if((!n||"default"!==r)&&e[r]!==t[r])return!1;for(r in t)if(!(n&&"default"===r||e[r]))return!1;return!0}(c,i.default.locals,void 0)?(c=i.default.locals,s(i.default)):e.hot.invalidate()}.bind(this))}e.hot.dispose((function(){s()}));i.default.locals},function(e,t){!function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+[\s\S]*?(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\((?!\s*\))\s*)(?:[^()]|\((?:[^()]|\([^()]*\))*\))+?(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:RegExp("[^{}\\s](?:[^{};\"']|"+t.source+")*?(?=\\s*\\{)"),string:{pattern:t,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),e.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:n.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:e.languages.css}},alias:"language-css"}},n.tag))}(Prism)},function(e,t){!function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",o=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),i=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function a(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|]|}|\s*#))/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<value>>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<key>>/g,(function(){return"(?:"+o+"|"+i+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:a(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?)?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:a(/true|false/.source,"i"),lookbehind:!0,aliasLine truncated
|
||||
/**
|
||||
* @license
|
||||
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
|
||||
* This code may only be used under the BSD style license found at
|
||||
* http://polymer.github.io/LICENSE.txt
|
||||
* The complete set of authors may be found at
|
||||
* http://polymer.github.io/AUTHORS.txt
|
||||
* The complete set of contributors may be found at
|
||||
* http://polymer.github.io/CONTRIBUTORS.txt
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at
|
||||
* http://polymer.github.io/PATENTS.txt
|
||||
*/const a="undefined"!=typeof window&&null!=window.customElements&&void 0!==window.customElements.polyfillWrapFlushCallback,s=(e,t,n=null)=>{for(;t!==n;){const n=t.nextSibling;e.removeChild(t),t=n}},c=`{{lit-${String(Math.random()).slice(2)}}}`,l=`\x3c!--${c}--\x3e`,u=new RegExp(`${c}|${l}`);class p{constructor(e,t){this.parts=[],this.element=t;const n=[],r=[],o=document.createTreeWalker(t.content,133,null,!1);let i=0,a=-1,s=0;const{strings:l,values:{length:p}}=e;for(;s<p;){const e=o.nextNode();if(null!==e){if(a++,1===e.nodeType){if(e.hasAttributes()){const t=e.attributes,{length:n}=t;let r=0;for(let e=0;e<n;e++)f(t[e].name,"$lit$")&&r++;for(;r-- >0;){const t=l[s],n=v.exec(t)[2],r=n.toLowerCase()+"$lit$",o=e.getAttribute(r);e.removeAttribute(r);const i=o.split(u);this.parts.push({type:"attribute",index:a,name:n,strings:i}),s+=i.length-1}}"TEMPLATE"===e.tagName&&(r.push(e),o.currentNode=e.content)}else if(3===e.nodeType){const t=e.data;if(t.indexOf(c)>=0){const r=e.parentNode,o=t.split(u),i=o.length-1;for(let t=0;t<i;t++){let n,i=o[t];if(""===i)n=h();else{const e=v.exec(i);null!==e&&f(e[2],"$lit$")&&(i=i.slice(0,e.index)+e[1]+e[2].slice(0,-"$lit$".length)+e[3]),n=document.createTextNode(i)}r.insertBefore(n,e),this.parts.push({type:"node",index:++a})}""===o[i]?(r.insertBefore(h(),e),n.push(e)):e.data=o[i],s+=i}}else if(8===e.nodeType)if(e.data===c){const t=e.parentNode;null!==e.previousSibling&&a!==i||(a++,t.insertBefore(h(),e)),i=a,this.parts.push({type:"node",index:a}),null===e.nextSibling?e.data="":(n.push(e),a--),s++}else{let t=-1;for(;-1!==(t=e.data.indexOf(c,t+1));)this.parts.push({type:"node",index:-1}),s++}}else o.currentNode=r.pop()}for(const e of n)e.parentNode.removeChild(e)}}const f=(e,t)=>{const n=e.length-t.length;return n>=0&&e.slice(n)===t},d=e=>-1!==e.index,h=()=>document.createComment(""),v=/([ \x09\x0a\x0c\x0d])([^\0-\x1F\x7F-\x9F "'>=/]+)([ \x09\x0a\x0c\x0d]*=[ \x09\x0a\x0c\x0d]*(?:[^ \x09\x0a\x0c\x0d"'`<>=]*|"[^"]*|'[^']*))$/;function m(e,t){const{element:{content:n},parts:r}=e,o=document.createTreeWalker(n,133,null,!1);let i=y(r),a=r[i],s=-1,c=0;const l=[];let u=null;for(;o.nextNode();){s++;const e=o.currentNode;for(e.previousSibling===u&&(u=null),t.has(e)&&(l.push(e),null===u&&(u=e)),null!==u&&c++;void 0!==a&&a.index===s;)a.index=null!==u?-1:a.index-c,i=y(r,i),a=r[i]}l.forEach(e=>e.parentNode.removeChild(e))}const g=e=>{let t=11===e.nodeType?0:1;const n=document.createTreeWalker(e,133,null,!1);for(;n.nextNode();)t++;return t},y=(e,t=-1)=>{for(let n=t+1;n<e.length;n++){const t=e[n];if(d(t))return n}return-1};
|
||||
/**
|
||||
* @license
|
||||
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
|
||||
* This code may only be used under the BSD style license found at
|
||||
* http://polymer.github.io/LICENSE.txt
|
||||
* The complete set of authors may be found at
|
||||
* http://polymer.github.io/AUTHORS.txt
|
||||
* The complete set of contributors may be found at
|
||||
* http://polymer.github.io/CONTRIBUTORS.txt
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at
|
||||
* http://polymer.github.io/PATENTS.txt
|
||||
*/
|
||||
const b=new WeakMap,x=e=>"function"==typeof e&&b.has(e),w={},k={};
|
||||
/**
|
||||
* @license
|
||||
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
|
||||
* This code may only be used under the BSD style license found at
|
||||
* http://polymer.github.io/LICENSE.txt
|
||||
* The complete set of authors may be found at
|
||||
* http://polymer.github.io/AUTHORS.txt
|
||||
* The complete set of contributors may be found at
|
||||
* http://polymer.github.io/CONTRIBUTORS.txt
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at
|
||||
* http://polymer.github.io/PATENTS.txt
|
||||
*/
|
||||
class S{constructor(e,t,n){this.__parts=[],this.template=e,this.processor=t,this.options=n}update(e){let t=0;for(const n of this.__parts)void 0!==n&&n.setValue(e[t]),t++;for(const e of this.__parts)void 0!==e&&e.commit()}_clone(){const e=a?this.template.element.content.cloneNode(!0):document.importNode(this.template.element.content,!0),t=[],n=this.template.parts,r=document.createTreeWalker(e,133,null,!1);let o,i=0,s=0,c=r.nextNode();for(;i<n.length;)if(o=n[i],d(o)){for(;s<o.index;)s++,"TEMPLATE"===c.nodeName&&(t.push(c),r.currentNode=c.content),null===(c=r.nextNode())&&(r.currentNode=t.pop(),c=r.nextNode());if("node"===o.type){const e=this.processor.handleTextExpression(this.options);e.insertAfterNode(c.previousSibling),this.__parts.push(e)}else this.__parts.push(...this.processor.handleAttributeExpressions(c,o.name,o.strings,this.options));i++}else this.__parts.push(void 0),i++;return a&&(document.adoptNode(e),customElements.upgrade(e)),e}}
|
||||
/**
|
||||
* @license
|
||||
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
|
||||
* This code may only be used under the BSD style license found at
|
||||
* http://polymer.github.io/LICENSE.txt
|
||||
* The complete set of authors may be found at
|
||||
* http://polymer.github.io/AUTHORS.txt
|
||||
* The complete set of contributors may be found at
|
||||
* http://polymer.github.io/CONTRIBUTORS.txt
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at
|
||||
* http://polymer.github.io/PATENTS.txt
|
||||
*/const O=` ${c} `;class A{constructor(e,t,n,r){this.strings=e,this.values=t,this.type=n,this.processor=r}getHTML(){const e=this.strings.length-1;let t="",n=!1;for(let r=0;r<e;r++){const e=this.strings[r],o=e.lastIndexOf("\x3c!--");n=(o>-1||n)&&-1===e.indexOf("--\x3e",o+1);const i=v.exec(e);t+=null===i?e+(n?O:l):e.substr(0,i.index)+i[1]+i[2]+"$lit$"+i[3]+c}return t+=this.strings[e],t}getTemplateElement(){const e=document.createElement("template");return e.innerHTML=this.getHTML(),e}}
|
||||
/**
|
||||
* @license
|
||||
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
|
||||
* This code may only be used under the BSD style license found at
|
||||
* http://polymer.github.io/LICENSE.txt
|
||||
* The complete set of authors may be found at
|
||||
* http://polymer.github.io/AUTHORS.txt
|
||||
* The complete set of contributors may be found at
|
||||
* http://polymer.github.io/CONTRIBUTORS.txt
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at
|
||||
* http://polymer.github.io/PATENTS.txt
|
||||
*/
|
||||
const E=e=>null===e||!("object"==typeof e||"function"==typeof e),_=e=>Array.isArray(e)||!(!e||!e[Symbol.iterator]);class j{constructor(e,t,n){this.dirty=!0,this.element=e,this.name=t,this.strings=n,this.parts=[];for(let e=0;e<n.length-1;e++)this.parts[e]=this._createPart()}_createPart(){return new T(this)}_getValue(){const e=this.strings,t=e.length-1;let n="";for(let r=0;r<t;r++){n+=e[r];const t=this.parts[r];if(void 0!==t){const e=t.value;if(E(e)||!_(e))n+="string"==typeof e?e:String(e);else for(const t of e)n+="string"==typeof t?t:String(t)}}return n+=e[t],n}commit(){this.dirty&&(this.dirty=!1,this.element.setAttribute(this.name,this._getValue()))}}class T{constructor(e){this.value=void 0,this.committer=e}setValue(e){e===w||E(e)&&e===this.value||(this.value=e,x(e)||(this.committer.dirty=!0))}commit(){for(;x(this.value);){const e=this.value;this.value=w,e(this)}this.value!==w&&this.committer.commit()}}class C{constructor(e){this.value=void 0,this.__pendingValue=void 0,this.options=e}appendInto(e){this.startNode=e.appendChild(h()),this.endNode=e.appendChild(h())}insertAfterNode(e){this.startNode=e,this.endNode=e.nextSibling}appendIntoPart(e){e.__insert(this.startNode=h()),e.__insert(this.endNode=h())}insertAfterPart(e){e.__insert(this.startNode=h()),this.endNode=e.endNode,e.endNode=this.startNode}setValue(e){this.__pendingValue=e}commit(){if(null===this.startNode.parentNode)return;for(;x(this.__pendingValue);){const e=this.__pendingValue;this.__pendingValue=w,e(this)}const e=this.__pendingValue;e!==w&&(E(e)?e!==this.value&&this.__commitText(e):e instanceof A?this.__commitTemplateResult(e):e instanceof Node?this.__commitNode(e):_(e)?this.__commitIterable(e):e===k?(this.value=k,this.clear()):this.__commitText(e))}__insert(e){this.endNode.parentNode.insertBefore(e,this.endNode)}__commitNode(e){this.value!==e&&(this.clear(),this.__insert(e),this.value=e)}__commitText(e){const t=this.startNode.nextSibling,n="string"==typeof(e=null==e?"":e)?e:String(e);t===this.endNode.previousSibling&&3===t.nodeType?t.data=n:this.__commitNode(document.createTextNode(n)),this.value=e}__commitTemplateResult(e){const t=this.options.templateFactory(e);if(this.value instanceof S&&this.value.template===t)this.value.update(e.values);else{const n=new S(t,e.processor,this.options),r=n._clone();n.update(e.values),this.__commitNode(r),this.value=n}}__commitIterable(e){Array.isArray(this.value)||(this.value=[],this.clear());const t=this.value;let n,r=0;for(const o of e)n=t[r],void 0===n&&(n=new C(this.options),t.push(n),0===r?n.appendIntoPart(this):n.insertAfterPart(t[r-1])),n.setValue(o),n.commit(),r++;r<t.length&&(t.length=r,this.clear(n&&n.endNode))}clear(e=this.startNode){s(this.startNode.parentNode,e.nextSibling,this.endNode)}}class I{constructor(e,t,n){if(this.value=void 0,this.__pendingValue=void 0,2!==n.length||""!==n[0]||""!==n[1])throw new Error("Boolean attributes can only contain a single expression");this.element=e,this.name=t,this.strings=n}setValue(e){this.__pendingValue=e}commit(){for(;x(this.__pendingValue);){const e=this.__pendingValue;this.__pendingValue=w,e(this)}if(this.__pendingValue===w)return;const e=!!this.__pendingValue;this.value!==e&&(e?this.element.setAttribute(this.name,""):this.element.removeAttribute(this.name),this.value=e),this.__pendingValue=w}}class P extends j{constructor(e,t,n){super(e,t,n),this.single=2===n.length&&""===n[0]&&""===n[1]}_createPart(){return new R(this)}_getValue(){return this.single?this.parts[0].value:super._getValue()}commit(){this.dirty&&(this.dirty=!1,this.element[this.name]=this._getValue())}}class R extends T{}let L=!1;(()=>{try{const e={get capture(){return L=!0,!1}};window.addEventListener("test",e,e),window.removeEventListener("test",e,e)}catch(e){}})();class N{constructor(e,t,n){this.value=void 0,this.__pendingValue=void 0,this.element=e,this.eventName=t,this.eventContext=n,this.__boundHandleEvent=e=>this.handleEvent(e)}setValue(e){this.__pendingValue=e}commit(){for(;x(this.__pendingValue);){const e=this.__pendingValue;this.__pendingValue=w,e(this)}if(this.__pendingValue===w)return;const e=this.__pendingValue,t=this.value,n=null==e||null!=t&&(e.capture!==t.capture||e.once!==t.once||e.passive!==t.passive),r=null!=e&&(null==t||n);n&&this.element.removeEventListener(this.eventName,this.__boundHandleEvent,this.__options),r&&(this.__options=M(e),this.element.addEventListener(this.eventName,this.__boundHandleEvent,this.__options)),this.value=e,this.__pendingValue=w}handleEvent(e){"function"==typeof this.value?this.value.call(this.eventContext||this.element,e):this.value.handleEvent(e)}}const M=e=>e&&(L?{capture:e.capture,passive:e.passive,once:e.once}:e.capture)
|
||||
/**
|
||||
* @license
|
||||
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
|
||||
* This code may only be used under the BSD style license found at
|
||||
* http://polymer.github.io/LICENSE.txt
|
||||
* The complete set of authors may be found at
|
||||
* http://polymer.github.io/AUTHORS.txt
|
||||
* The complete set of contributors may be found at
|
||||
* http://polymer.github.io/CONTRIBUTORS.txt
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at
|
||||
* http://polymer.github.io/PATENTS.txt
|
||||
*/;function B(e){let t=D.get(e.type);void 0===t&&(t={stringsArray:new WeakMap,keyString:new Map},D.set(e.type,t));let n=t.stringsArray.get(e.strings);if(void 0!==n)return n;const r=e.strings.join(c);return n=t.keyString.get(r),void 0===n&&(n=new p(e,e.getTemplateElement()),t.keyString.set(r,n)),t.stringsArray.set(e.strings,n),n}const D=new Map,q=new WeakMap;
|
||||
/**
|
||||
* @license
|
||||
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
|
||||
* This code may only be used under the BSD style license found at
|
||||
* http://polymer.github.io/LICENSE.txt
|
||||
* The complete set of authors may be found at
|
||||
* http://polymer.github.io/AUTHORS.txt
|
||||
* The complete set of contributors may be found at
|
||||
* http://polymer.github.io/CONTRIBUTORS.txt
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at
|
||||
* http://polymer.github.io/PATENTS.txt
|
||||
*/const F=new
|
||||
/**
|
||||
* @license
|
||||
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
|
||||
* This code may only be used under the BSD style license found at
|
||||
* http://polymer.github.io/LICENSE.txt
|
||||
* The complete set of authors may be found at
|
||||
* http://polymer.github.io/AUTHORS.txt
|
||||
* The complete set of contributors may be found at
|
||||
* http://polymer.github.io/CONTRIBUTORS.txt
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at
|
||||
* http://polymer.github.io/PATENTS.txt
|
||||
*/
|
||||
class{handleAttributeExpressions(e,t,n,r){const o=t[0];if("."===o){return new P(e,t.slice(1),n).parts}if("@"===o)return[new N(e,t.slice(1),r.eventContext)];if("?"===o)return[new I(e,t.slice(1),n)];return new j(e,t,n).parts}handleTextExpression(e){return new C(e)}};
|
||||
/**
|
||||
* @license
|
||||
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
|
||||
* This code may only be used under the BSD style license found at
|
||||
* http://polymer.github.io/LICENSE.txt
|
||||
* The complete set of authors may be found at
|
||||
* http://polymer.github.io/AUTHORS.txt
|
||||
* The complete set of contributors may be found at
|
||||
* http://polymer.github.io/CONTRIBUTORS.txt
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at
|
||||
* http://polymer.github.io/PATENTS.txt
|
||||
*/"undefined"!=typeof window&&(window.litHtmlVersions||(window.litHtmlVersions=[])).push("1.2.1");const z=(e,...t)=>new A(e,t,"html",F),U=(e,t)=>`${e}--${t}`;let $=!0;void 0===window.ShadyCSS?$=!1:void 0===window.ShadyCSS.prepareTemplateDom&&(console.warn("Incompatible ShadyCSS version detected. Please update to at least @webcomponents/webcomponentsjs@2.0.2 and @webcomponents/shadycss@1.3.1."),$=!1);const H=e=>t=>{const n=U(t.type,e);let r=D.get(n);void 0===r&&(r={stringsArray:new WeakMap,keyString:new Map},D.set(n,r));let o=r.stringsArray.get(t.strings);if(void 0!==o)return o;const i=t.strings.join(c);if(o=r.keyString.get(i),void 0===o){const n=t.getTemplateElement();$&&window.ShadyCSS.prepareTemplateDom(n,e),o=new p(t,n),r.keyString.set(i,o)}return r.stringsArray.set(t.strings,o),o},W=["html","svg"],V=new Set,Y=(e,t,n)=>{V.add(e);const r=n?n.element:document.createElement("template"),o=t.querySelectorAll("style"),{length:i}=o;if(0===i)return void window.ShadyCSS.prepareTemplateStyles(r,e);const a=document.createElement("style");for(let e=0;e<i;e++){const t=o[e];t.parentNode.removeChild(t),a.textContent+=t.textContent}(e=>{W.forEach(t=>{const n=D.get(U(t,e));void 0!==n&&n.keyString.forEach(e=>{const{element:{content:t}}=e,n=new Set;Array.from(t.querySelectorAll("style")).forEach(e=>{n.add(e)}),m(e,n)})})})(e);const s=r.content;n?function(e,t,n=null){const{element:{content:r},parts:o}=e;if(null==n)return void r.appendChild(t);const i=document.createTreeWalker(r,133,null,!1);let a=y(o),s=0,c=-1;for(;i.nextNode();){c++;for(i.currentNode===n&&(s=g(t),n.parentNode.insertBefore(t,n));-1!==a&&o[a].index===c;){if(s>0){for(;-1!==a;)o[a].index+=s,a=y(o,a);return}a=y(o,a)}}}(n,a,s.firstChild):s.insertBefore(a,s.firstChild),window.ShadyCSS.prepareTemplateStyles(r,e);const c=s.querySelector("style");if(window.ShadyCSS.nativeShadow&&null!==c)t.insertBefore(c.cloneNode(!0),t.firstChild);else if(n){s.insertBefore(a,s.firstChild);const e=new Set;e.add(a),m(n,e)}};window.JSCompiler_renameProperty=(e,t)=>e;const K={toAttribute(e,t){switch(t){case Boolean:return e?"":null;case Object:case Array:return null==e?e:JSON.stringify(e)}return e},fromAttribute(e,t){switch(t){case Boolean:return null!==e;case Number:return null===e?null:Number(e);case Object:case Array:return JSON.parse(e)}return e}},G=(e,t)=>t!==e&&(t==t||e==e),J={attribute:!0,type:String,converter:K,reflect:!1,hasChanged:G};class Q extends HTMLElement{constructor(){super(),this.initialize()}static get observedAttributes(){this.finalize();const e=[];return this._classProperties.forEach((t,n)=>{const r=this._attributeNameForProperty(n,t);void 0!==r&&(this._attributeToPropertyMap.set(r,n),e.push(r))}),e}static _ensureClassProperties(){if(!this.hasOwnProperty(JSCompiler_renameProperty("_classProperties",this))){this._classProperties=new Map;const e=Object.getPrototypeOf(this)._classProperties;void 0!==e&&e.forEach((e,t)=>this._classProperties.set(t,e))}}static createProperty(e,t=J){if(this._ensureClassProperties(),this._classProperties.set(e,t),t.noAccessor||this.prototype.hasOwnProperty(e))return;const n="symbol"==typeof e?Symbol():"__"+e,r=this.getPropertyDescriptor(e,n,t);void 0!==r&&Object.defineProperty(this.prototype,e,r)}static getPropertyDescriptor(e,t,n){return{get(){return this[t]},set(r){const o=this[e];this[t]=r,this.requestUpdateInternal(e,o,n)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this._classProperties&&this._classProperties.get(e)||J}static finalize(){const e=Object.getPrototypeOf(this);if(e.hasOwnProperty("finalized")||e.finalize(),this.finalized=!0,this._ensureClassProperties(),this._attributeToPropertyMap=new Map,this.hasOwnProperty(JSCompiler_renameProperty("properties",this))){const e=this.properties,t=[...Object.getOwnPropertyNames(e),..."function"==typeof Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(e):[]];for(const n of t)this.createProperty(n,e[n])}}static _attributeNameForProperty(e,t){const n=t.attribute;return!1===n?void 0:"string"==typeof n?n:"string"==typeof e?e.toLowerCase():void 0}static _valueHasChanged(e,t,n=G){return n(e,t)}static _propertyValueFromAttribute(e,t){const n=t.type,r=t.converter||K,o="function"==typeof r?r:r.fromAttribute;return o?o(e,n):e}static _propertyValueToAttribute(e,t){if(void 0===t.reflect)return;const n=t.type,r=t.converter;return(r&&r.toAttribute||K.toAttribute)(e,n)}initialize(){this._updateState=0,this._updatePromise=new Promise(e=>this._enableUpdatingResolver=e),this._changedProperties=new Map,this._saveInstanceProperties(),this.requestUpdateInternal()}_saveInstanceProperties(){this.constructor._classProperties.forEach((e,t)=>{if(this.hasOwnProperty(t)){const e=this[t];delete this[t],this._instanceProperties||(this._instanceProperties=new Map),this._instanceProperties.set(t,e)}})}_applyInstanceProperties(){this._instanceProperties.forEach((e,t)=>this[t]=e),this._instanceProperties=void 0}connectedCallback(){this.enableUpdating()}enableUpdating(){void 0!==this._enablLine truncated
|
||||
/**
|
||||
@license
|
||||
Copyright (c) 2019 The Polymer Project Authors. All rights reserved.
|
||||
This code may only be used under the BSD style license found at
|
||||
http://polymer.github.io/LICENSE.txt The complete set of authors may be found at
|
||||
http://polymer.github.io/AUTHORS.txt The complete set of contributors may be
|
||||
found at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as
|
||||
part of the polymer project is also subject to an additional IP rights grant
|
||||
found at http://polymer.github.io/PATENTS.txt
|
||||
*/
|
||||
const Z=window.ShadowRoot&&(void 0===window.ShadyCSS||window.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,ee=Symbol();class te{constructor(e,t){if(t!==ee)throw new Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e}get styleSheet(){return void 0===this._styleSheet&&(Z?(this._styleSheet=new CSSStyleSheet,this._styleSheet.replaceSync(this.cssText)):this._styleSheet=null),this._styleSheet}toString(){return this.cssText}}const ne=e=>new te(String(e),ee),re=(e,...t)=>{const n=t.reduce((t,n,r)=>t+(e=>{if(e instanceof te)return e.cssText;if("number"==typeof e)return e;throw new Error(`Value passed to 'css' function must be a 'css' function result: ${e}. Use 'unsafeCSS' to pass non-literal values, but\n take care to ensure page security.`)})(n)+e[r+1],e[0]);return new te(n,ee)};
|
||||
/**
|
||||
* @license
|
||||
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
|
||||
* This code may only be used under the BSD style license found at
|
||||
* http://polymer.github.io/LICENSE.txt
|
||||
* The complete set of authors may be found at
|
||||
* http://polymer.github.io/AUTHORS.txt
|
||||
* The complete set of contributors may be found at
|
||||
* http://polymer.github.io/CONTRIBUTORS.txt
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at
|
||||
* http://polymer.github.io/PATENTS.txt
|
||||
*/
|
||||
(window.litElementVersions||(window.litElementVersions=[])).push("2.4.0");const oe={};class ie extends Q{static getStyles(){return this.styles}static _getUniqueStyles(){if(this.hasOwnProperty(JSCompiler_renameProperty("_styles",this)))return;const e=this.getStyles();if(Array.isArray(e)){const t=(e,n)=>e.reduceRight((e,n)=>Array.isArray(n)?t(n,e):(e.add(n),e),n),n=t(e,new Set),r=[];n.forEach(e=>r.unshift(e)),this._styles=r}else this._styles=void 0===e?[]:[e];this._styles=this._styles.map(e=>{if(e instanceof CSSStyleSheet&&!Z){const t=Array.prototype.slice.call(e.cssRules).reduce((e,t)=>e+t.cssText,"");return ne(t)}return e})}initialize(){super.initialize(),this.constructor._getUniqueStyles(),this.renderRoot=this.createRenderRoot(),window.ShadowRoot&&this.renderRoot instanceof window.ShadowRoot&&this.adoptStyles()}createRenderRoot(){return this.attachShadow({mode:"open"})}adoptStyles(){const e=this.constructor._styles;0!==e.length&&(void 0===window.ShadyCSS||window.ShadyCSS.nativeShadow?Z?this.renderRoot.adoptedStyleSheets=e.map(e=>e instanceof CSSStyleSheet?e:e.styleSheet):this._needsShimAdoptedStyleSheets=!0:window.ShadyCSS.ScopingShim.prepareAdoptedCssText(e.map(e=>e.cssText),this.localName))}connectedCallback(){super.connectedCallback(),this.hasUpdated&&void 0!==window.ShadyCSS&&window.ShadyCSS.styleElement(this)}update(e){const t=this.render();super.update(e),t!==oe&&this.constructor.render(t,this.renderRoot,{scopeName:this.localName,eventContext:this}),this._needsShimAdoptedStyleSheets&&(this._needsShimAdoptedStyleSheets=!1,this.constructor._styles.forEach(e=>{const t=document.createElement("style");t.textContent=e.cssText,this.renderRoot.appendChild(t)}))}render(){return oe}}ie.finalized=!0,ie.render=(e,t,n)=>{if(!n||"object"!=typeof n||!n.scopeName)throw new Error("The `scopeName` option is required.");const r=n.scopeName,o=q.has(t),i=$&&11===t.nodeType&&!!t.host,a=i&&!V.has(r),c=a?document.createDocumentFragment():t;if(((e,t,n)=>{let r=q.get(t);void 0===r&&(s(t,t.firstChild),q.set(t,r=new C(Object.assign({templateFactory:B},n))),r.appendInto(t)),r.setValue(e),r.commit()})(e,c,Object.assign({templateFactory:H(r)},n)),a){const e=q.get(c);q.delete(c);const n=e.value instanceof S?e.value.template:void 0;Y(r,c,n),s(t,t.firstChild),t.appendChild(c),q.set(t,e)}!o&&i&&window.ShadyCSS.styleElement(t.host)};var ae=n(3),se=n.n(ae),ce=n(28),le=n.n(ce);n(287),n(288),n(289),n(290),n(291),n(292),n(293),n(294),n(295);function ue(){const e=function(e,t){t||(t=e.slice(0));return Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}([".hover-bg:hover{background:var(--bg3)}::selection{background:var(--selection-bg);color:var(--selection-fg)}.regular-font{font-family:var(--font-regular)}.mono-font{font-family:var(--font-mono)}.title{font-size:calc(var(--font-size-small) + 18px);font-weight:400}.sub-title{font-size:20px}.req-res-title{font-family:var(--font-regular);font-size:calc(var(--font-size-small) + 4px);font-weight:700;margin-bottom:8px}.tiny-title{font-size:calc(var(--font-size-small) + 1px);font-weight:700}.regular-font-size{font-size:var(--font-size-regular)}.small-font-size{font-size:var(--font-size-small)}.upper{text-transform:uppercase}.primary-text{color:var(--primary-color)}.bold-text{font-weight:700}.gray-text{color:var(--light-fg)}.red-text{color:var(--red)}.blue-text{color:var(--blue)}.multiline{overflow:scroll;max-height:var(--resp-area-height,300px);color:var(--fg3)}.method-fg.put{color:var(--orange)}.method-fg.post{color:var(--green)}.method-fg.get{color:var(--blue)}.method-fg.delete{color:var(--red)}.method-fg.head,.method-fg.options,.method-fg.patch{color:var(--yellow)}h1{font-family:var(--font-regular);font-size:28px;padding-top:10px;letter-spacing:normal;font-weight:400}h2{font-family:var(--font-regular);font-size:24px;padding-top:10px;letter-spacing:normal;font-weight:400}h3{font-family:var(--font-regular);font-size:18px;padding-top:10px;letter-spacing:normal;font-weight:400}h4{font-family:var(--font-regular);font-size:16px;padding-top:10px;letter-spacing:normal;font-weight:400}h5{font-family:var(--font-regular);font-size:14px;padding-top:10px;letter-spacing:normal;font-weight:400}h6{font-family:var(--font-regular);font-size:14px;padding-top:10px;letter-spacing:normal;font-weight:400}h1,h2,h3,h4,h5{margin-block-end:.2em}p{margin-block-start:.5em}a{color:var(--blue);cursor:pointer}a.inactive-link{color:var(--fg);text-decoration:none;cursor:text}code,pre{margin:0;font-family:var(--font-mono);font-size:calc(var(--font-size-mono) - 1px)}.m-markdown,.m-markdown-small{display:block}.m-markdown li,.m-markdown p,.m-markdown span{font-size:var(--font-size-regular);line-height:calc(var(--font-size-regular) + 8px)}.m-markdown-small li,.m-markdown-small p,.m-markdown-small span{font-size:var(--font-size-small);line-height:calc(var(--font-size-small) + 6px)}.m-markdown-small li{line-height:calc(var(--font-size-small) + 8px)}.m-markdown p:not(:first-child){margin-block-start:24px}.m-markdoLine truncated
|
||||
/*!
|
||||
* https://github.com/Starcounter-Jack/JSON-Patch
|
||||
* (c) 2017 Joachim Wester
|
||||
* MIT license
|
||||
*/
|
||||
var hr=new WeakMap,vr=function(e){this.observers=new Map,this.obj=e},mr=function(e,t){this.callback=e,this.observer=t};function gr(e,t){t.unobserve()}function yr(e,t){var n,r=function(e){return hr.get(e)}(e);if(r){var o=function(e,t){return e.observers.get(t)}(r,t);n=o&&o.observer}else r=new vr(e),hr.set(e,r);if(n)return n;if(n={},r.value=Qn(e),t){n.callback=t,n.next=null;var i=function(){br(n)},a=function(){clearTimeout(n.next),n.next=setTimeout(i)};"undefined"!=typeof window&&(window.addEventListener("mouseup",a),window.addEventListener("keyup",a),window.addEventListener("mousedown",a),window.addEventListener("keydown",a),window.addEventListener("change",a))}return n.patches=[],n.object=e,n.unobserve=function(){br(n),clearTimeout(n.next),function(e,t){e.observers.delete(t.callback)}(r,n),"undefined"!=typeof window&&(window.removeEventListener("mouseup",a),window.removeEventListener("keyup",a),window.removeEventListener("mousedown",a),window.removeEventListener("keydown",a),window.removeEventListener("change",a))},r.observers.set(t,new mr(t,n)),n}function br(e,t){void 0===t&&(t=!1);var n=hr.get(e.object);xr(n.value,e.object,e.patches,"",t),e.patches.length&&lr(n.value,e.patches);var r=e.patches;return r.length>0&&(e.patches=[],e.callback&&e.callback(r)),r}function xr(e,t,n,r,o){if(t!==e){"function"==typeof t.toJSON&&(t=t.toJSON());for(var i=Jn(t),a=Jn(e),s=!1,c=a.length-1;c>=0;c--){var l=e[p=a[c]];if(!Gn(t,p)||void 0===t[p]&&void 0!==l&&!1===Array.isArray(t))Array.isArray(e)===Array.isArray(t)?(o&&n.push({op:"test",path:r+"/"+Zn(p),value:Qn(l)}),n.push({op:"remove",path:r+"/"+Zn(p)}),s=!0):(o&&n.push({op:"test",path:r,value:e}),n.push({op:"replace",path:r,value:t}),!0);else{var u=t[p];"object"==typeof l&&null!=l&&"object"==typeof u&&null!=u?xr(l,u,n,r+"/"+Zn(p),o):l!==u&&(!0,o&&n.push({op:"test",path:r+"/"+Zn(p),value:Qn(l)}),n.push({op:"replace",path:r+"/"+Zn(p),value:Qn(u)}))}}if(s||i.length!=a.length)for(c=0;c<i.length;c++){var p;Gn(e,p=i[c])||void 0===t[p]||n.push({op:"add",path:r+"/"+Zn(p),value:Qn(t[p])})}}}function wr(e,t,n){void 0===n&&(n=!1);var r=[];return xr(e,t,r,"",n),r}Object.assign({},r,o,{JsonPatchError:nr,deepClone:Qn,escapePathComponent:Zn,unescapePathComponent:er});var kr=n(277),Sr=n.n(kr),Or=n(278),Ar=n.n(Or),Er={add:function(e,t){return{op:"add",path:e,value:t}},replace:jr,remove:function(e){return{op:"remove",path:e}},merge:function(e,t){return{type:"mutation",op:"merge",path:e,value:t}},mergeDeep:function(e,t){return{type:"mutation",op:"mergeDeep",path:e,value:t}},context:function(e,t){return{type:"context",path:e,value:t}},getIn:function(e,t){return Ot()(t).call(t,(function(e,t){return void 0!==t&&e?e[t]:e}),e)},applyPatch:function(e,t,n){if(n=n||{},"merge"===(t=De()(De()({},t),{},{path:t.path&&_r(t.path)})).op){var r=zr(e,t.path);Fn()(r,t.value),lr(e,[jr(t.path,r)])}else if("mergeDeep"===t.op){var o=zr(e,t.path);for(var i in t.value){var a=t.value[i],s=mt()(a);if(s){var c=o[i]||[];o[i]=ot()(c).call(c,a)}else if(Nr(a)&&!s){var l=De()({},o[i]);for(var u in a){if(Object.prototype.hasOwnProperty.call(l,u)){l=Sr()(Ar()(l),a);break}Fn()(l,Vn()({},u,a[u]))}o[i]=l}else o[i]=a}}else if("add"===t.op&&""===t.path&&Nr(t.value)){var p,f=Ot()(p=at()(t.value)).call(p,(function(e,n){return e.push({op:"add",path:"/".concat(_r(n)),value:t.value[n]}),e}),[]);lr(e,f)}else if("replace"===t.op&&""===t.path){var d=t.value;n.allowMetaPatches&&t.meta&&qr(t)&&(mt()(t.value)||Nr(t.value))&&(d=De()(De()({},d),t.meta)),e=d}else if(lr(e,[t]),n.allowMetaPatches&&t.meta&&qr(t)&&(mt()(t.value)||Nr(t.value))){var h=zr(e,t.path),v=De()(De()({},h),t.meta);lr(e,[jr(t.path,v)])}return e},parentPathMatch:function(e,t){if(!mt()(t))return!1;for(var n=0,r=t.length;n<r;n+=1)if(t[n]!==e[n])return!1;return!0},flatten:Rr,fullyNormalizeArray:function(e){return Lr(Rr(Pr(e)))},normalizeArray:Pr,isPromise:function(e){return Nr(e)&&Mr(e.then)},forEachNew:function(e,t){try{return Tr(e,Ir,t)}catch(e){return e}},forEachNewPrimitive:function(e,t){try{return Tr(e,Cr,t)}catch(e){return e}},isJsonPatch:Br,isContextPatch:function(e){return Fr(e)&&"context"===e.type},isPatch:Fr,isMutation:Dr,isAdditiveMutation:qr,isGenerator:function(e){return"[object GeneratorFunction]"===Object.prototype.toString.call(e)},isFunction:Mr,isObject:Nr,isError:function(e){return e instanceof Error}};function _r(e){return mt()(e)?e.length<1?"":"/".concat(ct()(e).call(e,(function(e){return(e+"").replace(/~/g,"~0").replace(/\//g,"~1")})).join("/")):e}function jr(e,t,n){return{op:"replace",path:e,value:t,meta:n}}function Tr(e,t,n){var r;return Lr(Rr(ct()(r=Xe()(e).call(e,qr)).call(r,(function(e){return t(e.value,n,e.path)}))||[]))}function Cr(e,t,n){return n=n||[],mt()(e)?ct()(e).call(e,(function(e,r){return Cr(e,t,ot()(n).call(n,r))})):Nr(e)?ct()(r=at()(e)).call(r,(function(r){return Cr(e[r],t,ot()(n).call(n,r))})):t(e,n[n.length-1],n);var r}function Ir(e,t,n){var r=[];if((n=n||[]).length>0){var o=t(e,n[n.length-1],n);o&&(r=ot()(r).call(r,o))}if(mt()(e)){var i=cLine truncated
|
||||
/**
|
||||
* @license
|
||||
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
|
||||
* This code may only be used under the BSD style license found at
|
||||
* http://polymer.github.io/LICENSE.txt
|
||||
* The complete set of authors may be found at
|
||||
* http://polymer.github.io/AUTHORS.txt
|
||||
* The complete set of contributors may be found at
|
||||
* http://polymer.github.io/CONTRIBUTORS.txt
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at
|
||||
* http://polymer.github.io/PATENTS.txt
|
||||
*/(s,t,n),p=function(e){if(!e.components)return[];const t=[];for(const n in e.components){const r=[];for(const t in e.components[n]){const o={show:!0,id:"".concat(n.toLowerCase(),"-").concat(t.toLowerCase()).replace(Ce,"-"),name:t,component:e.components[n][t]};r.push(o)}let o=n,i=n;switch(n){case"schemas":i="Schemas",o="Schemas allows the definition of input and output data types. These types can be objects, but also primitives and arrays.";break;case"responses":i="Responses",o="Describes responses from an API Operation, including design-time, static links to operations based on the response.";break;case"parameters":i="Parameters",o="Describes operation parameters. A unique parameter is defined by a combination of a name and location.";break;case"examples":i="Examples",o="List of Examples for operations, can be requests, responses and objects examples.";break;case"requestBodies":i="Request Bodies",o="Describes common request bodies that are used across the API operations.";break;case"headers":i="Headers",o='Headers follows the structure of the Parameters but they are explicitly in "header"';break;case"securitySchemes":i="Security Schemes",o="Defines a security scheme that can be used by the operations. Supported schemes are HTTP authentication, an API key (either as a header, a cookie parameter or as a query parameter), OAuth2's common flows(implicit, password, client credentials and authorization code) as defined in RFC6749, and OpenID Connect Discovery.";break;case"links":i="Links",o="Links represent a possible design-time link for a response. The presence of a link does not guarantee the caller's ability to successfully invoke it, rather it provides a known relationship and traversal mechanism between responses and other operations.";break;case"callbacks":i="Callbacks",o="A map of possible out-of band callbacks related to the parent operation. Each value in the map is a Path Item Object that describes a set of requests that may be initiated by the API provider and the expected responses. The key value used to identify the path item object is an expression, evaluated at runtime, that identifies a URL to use for the callback operation.";break;default:i=n,o=n}const a={show:!0,name:i,description:o,subComponents:r};t.push(a)}return t||[]}(s),f=function(e){if(e&&e.info&&e.info.description){const t=se.a.lexer(e.info.description);return t.filter(e=>"heading"===e.type&&e.depth<=2)||[]}return[]}(s),d=[];s.components&&s.components.securitySchemes&&Object.entries(s.components.securitySchemes).forEach(e=>{const t={apiKeyId:e[0],...e[1]};t.value="",t.finalKeyValue="","apiKey"===e[1].type||"http"===e[1].type?(t.in=e[1].in||"header",t.name=e[1].name||"Authorization",t.user="",t.password=""):"oauth2"===e[1].type&&(t.in="header",t.name="Authorization",t.clientId="",t.clientSecret=""),d.push(t)}),r&&o&&i&&d.push({apiKeyId:"_rapidoc_api_key",description:"api-key provided in rapidoc element attributes",type:"apiKey",oAuthFlow:"",name:r,in:o,value:i,finalKeyValue:i}),d.forEach(e=>{"http"===e.type?e.typeDisplay="basic"===e.scheme?"HTTP Basic":"HTTP Bearer":"apiKey"===e.type?e.typeDisplay="API Key (".concat(e.name,")"):"oauth2"===e.type?e.typeDisplay="OAuth (".concat(e.apiKeyId,")"):e.typeDisplay=e.type});let h=[];s.servers&&Array.isArray(s.servers)?(s.servers.forEach(e=>{let t=e.url.trim();t.startsWith("http")||t.startsWith("//")||t.startsWith("{")||window.location.origin.startsWith("http")&&(e.url=window.location.origin+e.url,t=e.url),e.variables&&Object.entries(e.variables).forEach(e=>{const n=new RegExp("{".concat(e[0],"}"),"g");t=t.replace(n,e[1].default||""),e[1].value=e[1].default||""}),e.computedUrl=t}),a&&s.servers.push({url:a,computedUrl:a})):a?s.servers=[{url:a,computedUrl:a}]:window.location.origin.startsWith("http")?s.servers=[{url:window.location.origin,computedUrl:window.location.origin}]:s.servers=[{url:"http://localhost",computedUrl:"http://localhost"}],h=s.servers;return{info:s.info,infoDescriptionHeaders:f,tags:u,components:p,externalDocs:s.externalDocs,securitySchemes:d,servers:h,basePath:s.basePath}}const Oi=new WeakMap,Ai=(Ei=e=>t=>{if(!(t instanceof C))throw new Error("unsafeHTML can only be used in text bindings");const n=Oi.get(t);if(void 0!==n&&E(e)&&e===n.value&&t.value===n.fragment)return;const r=document.createElement("template");r.innerHTML=e;const o=document.importNode(r.content,!0);t.setValue(o),Oi.set(t,{value:e,fragment:o})},(...e)=>{const t=Ei(...e);return b.set(t,!0),t});var Ei;function _i(){const e=fa(["Requires"]);return _i=function(){return e},e}function ji(){const e=fa(["<b>",".</b> "]);return ji=function(){return e},e}function Ti(){const e=fa([" <div> "," Token in <b>"," ","</b> </div>"]);return Ti=function(){return e},e}function Ci(){const e=fa(["Requires"]);return Ci=function(){return e},e}function Ii(){const e=fa(["<b>",".</b> "]);return Ii=function(){return e},e}function Pi(){const e=fa([" <div> "," "," in <b>Authorization header</b> </div>"]);return Pi=function(){retur
Line truncated
|
||||
//# sourceMappingURL=rapidoc-min.js.map
|
||||
@@ -1,12 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script type="module" src="./rapidoc-min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<rapi-doc
|
||||
spec-url="/docs/openapi.json"
|
||||
> </rapi-doc>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,18 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>ReDoc</title>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<redoc spec-url='/docs/openapi.json'></redoc>
|
||||
<script src="./redoc.standalone.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,103 +0,0 @@
|
||||
/*!
|
||||
* ReDoc - OpenAPI/Swagger-generated API Reference Documentation
|
||||
* -------------------------------------------------------------
|
||||
* Version: "2.0.0-rc.48"
|
||||
* Repo: https://github.com/Redocly/redoc
|
||||
*/
|
||||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("null"),function(){try{return require("esprima")}catch(e){}}()):"function"==typeof define&&define.amd?define(["null","esprima"],t):"object"==typeof exports?exports.Redoc=t(require("null"),function(){try{return require("esprima")}catch(e){}}()):e.Redoc=t(e.null,e.esprima)}(this,(function(e,t){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=158)}([function(e,t,n){"use strict";e.exports=n(228)},function(e,t,n){"use strict";n.r(t),n.d(t,"__extends",(function(){return o})),n.d(t,"__assign",(function(){return i})),n.d(t,"__rest",(function(){return a})),n.d(t,"__decorate",(function(){return s})),n.d(t,"__param",(function(){return l})),n.d(t,"__metadata",(function(){return c})),n.d(t,"__awaiter",(function(){return u})),n.d(t,"__generator",(function(){return p})),n.d(t,"__createBinding",(function(){return f})),n.d(t,"__exportStar",(function(){return d})),n.d(t,"__values",(function(){return h})),n.d(t,"__read",(function(){return m})),n.d(t,"__spread",(function(){return g})),n.d(t,"__spreadArrays",(function(){return v})),n.d(t,"__await",(function(){return y})),n.d(t,"__asyncGenerator",(function(){return b})),n.d(t,"__asyncDelegator",(function(){return x})),n.d(t,"__asyncValues",(function(){return w})),n.d(t,"__makeTemplateObject",(function(){return _})),n.d(t,"__importStar",(function(){return O})),n.d(t,"__importDefault",(function(){return E})),n.d(t,"__classPrivateFieldGet",(function(){return S})),n.d(t,"__classPrivateFieldSet",(function(){return T}));
|
||||
/*! *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)};function o(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var i=function(){return(i=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)};function a(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o<r.length;o++)t.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]])}return n}function s(e,t,n,r){var o,i=arguments.length,a=i<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}function l(e,t){return function(n,r){t(n,r,e)}}function c(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function u(e,t,n,r){return new(n||(n=Promise))((function(o,i){function a(e){try{l(r.next(e))}catch(e){i(e)}}function s(e){try{l(r.throw(e))}catch(e){i(e)}}function l(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}l((r=r.apply(e,t||[])).next())}))}function p(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){a.label=i[1];break}if(6===i[0]&&a.label<o[1]){a.label=o[1],o=i;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(i);break}o[2]&&a.ops.pop(),a.trys.pop();continue}i=t.call(e,a)}catch(e){i=[6,e],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,s])}}}var f=Object.create?function(e,t,n,r){void 0===r&&(r=n),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]};function d(e,t){for(var n in e)"default"===n||t.hasOwnProperty(n)||f(t,e,n)}function h(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function m(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,i=n.call(e),a=[];try{for(;(void 0===t||t-- >0)&&!(r=i.next()).done;)a.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return a}function g(){for(var e=[],t=0;t<arguments.length;t++)e=e.concat(m(arguments[t]));return e}function v(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),o=0;for(t=0;t<n;t++)for(var i=arguments[t],a=0,s=i.length;a<s;a++,o++)r[o]=i[a];return r}function y(e){return this instanceof y?(this.v=e,this):new y(e)}function b(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var r,o=n.apply(e,t||[]),i=[];return r={},a("next"),a("throw"),a("return"),r[Symbol.asyncIterator]=function(){return this},r;function a(e){o[e]&&(r[e]=function(t){return new Promise((function(n,r){i.push([e,t,n,r])>1||s(e,t)}))})}function s(e,t){try{(n=o[e](t)).value instanceof y?Promise.resolve(n.value.v).then(l,c):u(i[0][2],n)}catch(e){u(i[0][3],e)}var n}function l(e){s("next",e)}function c(e){s("throw",e)}function u(e,t){e(t),i.shift(),i.length&&s(i[0][0],i[0][1])}}function x(e){var t,n;return t={},r("next"),r("throw",(function(e){throw e})),r("return"),t[Symbol.iterator]=function(){return this},t;function r(r,o){t[r]=e[r]?function(t){return(n=!n)?{value:y(e[r](t)),done:"return"===r}:o?o(t):t}:o}}function w(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e=h(e),t={},r("next"),r("throw"),r("return"),t[Symbol.asyncIterator]=function(){return this},t);function r(n){t[n]=e[n]&&function(t){return new Promise((function(r,o){(function(e,tLine truncated
|
||||
/*!
|
||||
* The buffer module from node.js, for the browser.
|
||||
*
|
||||
* @author Feross Aboukhadijeh <http://feross.org>
|
||||
* @license MIT
|
||||
*/
|
||||
var r=n(241),o=n(242),i=n(129);function a(){return l.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(e,t){if(a()<t)throw new RangeError("Invalid typed array length");return l.TYPED_ARRAY_SUPPORT?(e=new Uint8Array(t)).__proto__=l.prototype:(null===e&&(e=new l(t)),e.length=t),e}function l(e,t,n){if(!(l.TYPED_ARRAY_SUPPORT||this instanceof l))return new l(e,t,n);if("number"==typeof e){if("string"==typeof t)throw new Error("If encoding is specified then the first argument must be a string");return p(this,e)}return c(this,e,t,n)}function c(e,t,n,r){if("number"==typeof t)throw new TypeError('"value" argument must not be a number');return"undefined"!=typeof ArrayBuffer&&t instanceof ArrayBuffer?function(e,t,n,r){if(t.byteLength,n<0||t.byteLength<n)throw new RangeError("'offset' is out of bounds");if(t.byteLength<n+(r||0))throw new RangeError("'length' is out of bounds");t=void 0===n&&void 0===r?new Uint8Array(t):void 0===r?new Uint8Array(t,n):new Uint8Array(t,n,r);l.TYPED_ARRAY_SUPPORT?(e=t).__proto__=l.prototype:e=f(e,t);return e}(e,t,n,r):"string"==typeof t?function(e,t,n){"string"==typeof n&&""!==n||(n="utf8");if(!l.isEncoding(n))throw new TypeError('"encoding" must be a valid string encoding');var r=0|h(t,n),o=(e=s(e,r)).write(t,n);o!==r&&(e=e.slice(0,o));return e}(e,t,n):function(e,t){if(l.isBuffer(t)){var n=0|d(t.length);return 0===(e=s(e,n)).length||t.copy(e,0,0,n),e}if(t){if("undefined"!=typeof ArrayBuffer&&t.buffer instanceof ArrayBuffer||"length"in t)return"number"!=typeof t.length||(r=t.length)!=r?s(e,0):f(e,t);if("Buffer"===t.type&&i(t.data))return f(e,t.data)}var r;throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")}(e,t)}function u(e){if("number"!=typeof e)throw new TypeError('"size" argument must be a number');if(e<0)throw new RangeError('"size" argument must not be negative')}function p(e,t){if(u(t),e=s(e,t<0?0:0|d(t)),!l.TYPED_ARRAY_SUPPORT)for(var n=0;n<t;++n)e[n]=0;return e}function f(e,t){var n=t.length<0?0:0|d(t.length);e=s(e,n);for(var r=0;r<n;r+=1)e[r]=255&t[r];return e}function d(e){if(e>=a())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a().toString(16)+" bytes");return 0|e}function h(e,t){if(l.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return U(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return B(e).length;default:if(r)return U(e).length;t=(""+t).toLowerCase(),r=!0}}function m(e,t,n){var r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return A(this,t,n);case"utf8":case"utf-8":return S(this,t,n);case"ascii":return T(this,t,n);case"latin1":case"binary":return j(this,t,n);case"base64":return E(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return C(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function g(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function v(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=o?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=l.from(t,r)),l.isBuffer(t))return 0===t.length?-1:y(e,t,n,r,o);if("number"==typeof t)return t&=255,l.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):y(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function y(e,t,n,r,o){var i,a=1,s=e.length,l=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a=2,s/=2,l/=2,n/=2}function c(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(o){var u=-1;for(i=n;i<s;i++)if(c(e,i)===c(t,-1===u?0:i-u)){if(-1===u&&(u=i),i-u+1===l)return u*a}else-1!==u&&(i-=i-u),u=-1}else for(n+l>s&&(n=s-l),i=n;i>=0;i--){for(var p=!0,f=0;f<l;f++)if(c(e,i+f)!==c(t,f)){p=!1;break}if(p)return i}return-1}function b(e,t,n,r){n=Number(n)||0;var o=e.length-n;r?(r=Number(r))>o&&(r=o):r=o;var i=t.length;if(i%2!=0)throw new TypeError("Invalid hex string");r>i/2&&(r=i/2);for(var a=0;a<r;++a){var s=parseInt(t.substr(2*a,2),16);if(isNaN(s))return a;e[n+a]=s}return a}function x(e,t,n,r){return $(U(t,e.length-n),e,n,r)}function w(e,t,n,r){return $(function(e){for(var t=[],n=0;n<e.length;++n)t.push(255&e.charCodeAt(n));return t}(t),e,n,r)}function _(e,t,n,r){return w(e,t,n,r)}function k(e,t,n,r){return $(B(t),e,n,Line truncated
|
||||
/**
|
||||
* Prism: Lightweight, robust, elegant syntax highlighting
|
||||
*
|
||||
* @license MIT <https://opensource.org/licenses/MIT>
|
||||
* @author Lea Verou <https://lea.verou.me>
|
||||
* @namespace
|
||||
* @public
|
||||
*/e.exports&&(e.exports=n),void 0!==t&&(t.Prism=n),n.languages.markup={comment:/<!--[\s\S]*?-->/,prolog:/<\?[\s\S]+?\?>/,doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/,name:/[^\s<>'"]+/}},cdata:/<!\[CDATA\[[\s\S]*?]]>/i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},n.languages.markup.tag.inside["attr-value"].inside.entity=n.languages.markup.entity,n.languages.markup.doctype.inside["internal-subset"].inside=n.languages.markup,n.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(n.languages.markup.tag,"addInlined",{value:function(e,t){var r={};r["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:n.languages[t]},r.cdata=/^<!\[CDATA\[|\]\]>$/i;var o={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:r}};o["language-"+t]={pattern:/[\s\S]+/,inside:n.languages[t]};var i={};i[e]={pattern:RegExp(/(<__[\s\S]*?>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:o},n.languages.insertBefore("markup","cdata",i)}}),n.languages.html=n.languages.markup,n.languages.mathml=n.languages.markup,n.languages.svg=n.languages.markup,n.languages.xml=n.languages.extend("markup",{}),n.languages.ssml=n.languages.xml,n.languages.atom=n.languages.xml,n.languages.rss=n.languages.xml,function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+[\s\S]*?(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\((?!\s*\))\s*)(?:[^()]|\((?:[^()]|\([^()]*\))*\))+?(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:RegExp("[^{}\\s](?:[^{};\"']|"+t.source+")*?(?=\\s*\\{)"),string:{pattern:t,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),e.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:n.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:e.languages.css}},alias:"language-css"}},n.tag))}(n),n.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},n.languages.javascript=n.languages.extend("clike",{"class-name":[n.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|})\s*)(?:catch|finally)\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|(?:get|set)(?=\s*[\[$\w\xA0-\uFFFF])|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],number:/\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)Line truncated
|
||||
/*!***************************************************
|
||||
* mark.js v8.11.1
|
||||
* https://markjs.io/
|
||||
* Copyright (c) 2014–2018, Julian Kühnel
|
||||
* Released under the MIT license https://git.io/vwTVl
|
||||
*****************************************************/
|
||||
e.exports=function(){"use strict";var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},t=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},n=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),r=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},o=function(){function e(n){var r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:5e3;t(this,e),this.ctx=n,this.iframes=r,this.exclude=o,this.iframesTimeout=i}return n(e,[{key:"getContexts",value:function(){var e=[];return(void 0!==this.ctx&&this.ctx?NodeList.prototype.isPrototypeOf(this.ctx)?Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?this.ctx:"string"==typeof this.ctx?Array.prototype.slice.call(document.querySelectorAll(this.ctx)):[this.ctx]:[]).forEach((function(t){var n=e.filter((function(e){return e.contains(t)})).length>0;-1!==e.indexOf(t)||n||e.push(t)})),e}},{key:"getIframeContents",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){},r=void 0;try{var o=e.contentWindow;if(r=o.document,!o||!r)throw new Error("iframe inaccessible")}catch(e){n()}r&&t(r)}},{key:"isIframeBlank",value:function(e){var t="about:blank",n=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&n!==t&&n}},{key:"observeIframeLoad",value:function(e,t,n){var r=this,o=!1,i=null,a=function a(){if(!o){o=!0,clearTimeout(i);try{r.isIframeBlank(e)||(e.removeEventListener("load",a),r.getIframeContents(e,t,n))}catch(e){n()}}};e.addEventListener("load",a),i=setTimeout(a,this.iframesTimeout)}},{key:"onIframeReady",value:function(e,t,n){try{"complete"===e.contentWindow.document.readyState?this.isIframeBlank(e)?this.observeIframeLoad(e,t,n):this.getIframeContents(e,t,n):this.observeIframeLoad(e,t,n)}catch(e){n()}}},{key:"waitForIframes",value:function(e,t){var n=this,r=0;this.forEachIframe(e,(function(){return!0}),(function(e){r++,n.waitForIframes(e.querySelector("html"),(function(){--r||t()}))}),(function(e){e||t()}))}},{key:"forEachIframe",value:function(t,n,r){var o=this,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},a=t.querySelectorAll("iframe"),s=a.length,l=0;a=Array.prototype.slice.call(a);var c=function(){--s<=0&&i(l)};s||c(),a.forEach((function(t){e.matches(t,o.exclude)?c():o.onIframeReady(t,(function(e){n(t)&&(l++,r(e)),c()}),c)}))}},{key:"createIterator",value:function(e,t,n){return document.createNodeIterator(e,t,n,!1)}},{key:"createInstanceOnIframe",value:function(t){return new e(t.querySelector("html"),this.iframes)}},{key:"compareNodeIframe",value:function(e,t,n){if(e.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_PRECEDING){if(null===t)return!0;if(t.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_FOLLOWING)return!0}return!1}},{key:"getIteratorNode",value:function(e){var t=e.previousNode();return{prevNode:t,node:(null===t||e.nextNode())&&e.nextNode()}}},{key:"checkIframeFilter",value:function(e,t,n,r){var o=!1,i=!1;return r.forEach((function(e,t){e.val===n&&(o=t,i=e.handled)})),this.compareNodeIframe(e,t,n)?(!1!==o||i?!1===o||i||(r[o].handled=!0):r.push({val:n,handled:!0}),!0):(!1===o&&r.push({val:n,handled:!1}),!1)}},{key:"handleOpenIframes",value:function(e,t,n,r){var o=this;e.forEach((function(e){e.handled||o.getIframeContents(e.val,(function(e){o.createInstanceOnIframe(e).forEachNode(t,n,r)}))}))}},{key:"iterateThroughNodes",value:function(e,t,n,r,o){for(var i,a=this,s=this.createIterator(t,e,r),l=[],c=[],u=void 0,p=void 0;i=void 0,i=a.getIteratorNode(s),p=i.prevNode,u=i.node;)this.iframes&&this.forEachIframe(t,(function(e){return a.checkIframeFilter(u,p,e,l)}),(function(t){a.createInstanceOnIframe(t).forEachNode(e,(function(e){return c.push(e)}),r)})),c.push(u);c.forEach((function(e){n(e)})),this.iframes&&this.handleOpenIframes(l,e,n,r),o()}},{key:"forEachNode",value:function(e,t,n){var r=this,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},i=this.getContexts(),a=i.length;a||o(),i.forEach((function(i){var s=function(){r.iterateThroughNodes(e,i,t,n,(function(){--a<=0&&o()}))};r.iframes?r.waitForIframes(i,s):s()}))}}],[{key:"matches",value:function(e,t){var n="string"==typeof t?[t]:t,r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(r){var o=!1;return n.every((function(t){return!r.call(e,t)||(o=!0,!1)})),o}return!1}}]),e}(),i=function(){function i(e){t(this,i),this.ctx=e,thisLine truncated
|
||||
/*
|
||||
object-assign
|
||||
(c) Sindre Sorhus
|
||||
@license MIT
|
||||
*/var r=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable;function a(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var n,s,l=a(e),c=1;c<arguments.length;c++){for(var u in n=Object(arguments[c]))o.call(n,u)&&(l[u]=n[u]);if(r){s=r(n);for(var p=0;p<s.length;p++)i.call(n,s[p])&&(l[s[p]]=n[s[p]])}}return l}},function(e,t){var n={}.toString;e.exports=Array.isArray||function(e){return"[object Array]"==n.call(e)}},function(e,t,n){"use strict";var r=n(243),o=n(244),i=n(268),a=n(269),s=n(270),l=n(272);function c(e){u(this,c.defaults),u(this,e)}function u(e,t){if(p(t))for(var n=Object.keys(t),r=0;r<n.length;r++){var o=n[r],i=t[o],a=e[o];p(i)?e[o]=u(a||{},i):void 0!==i&&(e[o]=i)}return e}function p(e){return e&&"object"==typeof e&&!Array.isArray(e)&&!(e instanceof RegExp)&&!(e instanceof Date)}e.exports=c,c.defaults={parse:{json:r,yaml:o,text:i,binary:a},resolve:{file:s,http:l,external:!0},dereference:{circular:!0}}},function(e,t,n){"use strict";var r=n(245),o=n(31);e.exports={parse:function(e,t){try{return r.safeLoad(e)}catch(e){throw e instanceof Error?e:o(e,e.message)}},stringify:function(e,t,n){try{var i=("string"==typeof n?n.length:n)||2;return r.safeDump(e,{indent:i})}catch(e){throw e instanceof Error?e:o(e,e.message)}}}},function(e,t,n){"use strict";var r=n(36);e.exports=new r({include:[n(133)]})},function(e,t,n){"use strict";var r=n(36);e.exports=new r({include:[n(88)],implicit:[n(252),n(253),n(254),n(255)]})},function(e,t,n){(function(e){t.fetch=s(e.fetch)&&s(e.ReadableStream),t.writableStream=s(e.WritableStream),t.abortController=s(e.AbortController),t.blobConstructor=!1;try{new Blob([new ArrayBuffer(1)]),t.blobConstructor=!0}catch(e){}var n;function r(){if(void 0!==n)return n;if(e.XMLHttpRequest){n=new e.XMLHttpRequest;try{n.open("GET",e.XDomainRequest?"/":"https://example.com")}catch(e){n=null}}else n=null;return n}function o(e){var t=r();if(!t)return!1;try{return t.responseType=e,t.responseType===e}catch(e){}return!1}var i=void 0!==e.ArrayBuffer,a=i&&s(e.ArrayBuffer.prototype.slice);function s(e){return"function"==typeof e}t.arraybuffer=t.fetch||i&&o("arraybuffer"),t.msstream=!t.fetch&&a&&o("ms-stream"),t.mozchunkedarraybuffer=!t.fetch&&i&&o("moz-chunked-arraybuffer"),t.overrideMimeType=t.fetch||!!r()&&s(r().overrideMimeType),t.vbArray=s(e.VBArray),n=null}).call(this,n(6))},function(e,t,n){(function(e,r,o){var i=n(134),a=n(32),s=n(136),l=t.readyStates={UNSENT:0,OPENED:1,HEADERS_RECEIVED:2,LOADING:3,DONE:4},c=t.IncomingMessage=function(t,n,a,l){var c=this;if(s.Readable.call(c),c._mode=a,c.headers={},c.rawHeaders=[],c.trailers={},c.rawTrailers=[],c.on("end",(function(){e.nextTick((function(){c.emit("close")}))})),"fetch"===a){if(c._fetchResponse=n,c.url=n.url,c.statusCode=n.status,c.statusMessage=n.statusText,n.headers.forEach((function(e,t){c.headers[t.toLowerCase()]=e,c.rawHeaders.push(t,e)})),i.writableStream){var u=new WritableStream({write:function(e){return new Promise((function(t,n){c._destroyed?n():c.push(new r(e))?t():c._resumeFetch=t}))},close:function(){o.clearTimeout(l),c._destroyed||c.push(null)},abort:function(e){c._destroyed||c.emit("error",e)}});try{return void n.body.pipeTo(u).catch((function(e){o.clearTimeout(l),c._destroyed||c.emit("error",e)}))}catch(e){}}var p=n.body.getReader();!function e(){p.read().then((function(t){if(!c._destroyed){if(t.done)return o.clearTimeout(l),void c.push(null);c.push(new r(t.value)),e()}})).catch((function(e){o.clearTimeout(l),c._destroyed||c.emit("error",e)}))}()}else{if(c._xhr=t,c._pos=0,c.url=t.responseURL,c.statusCode=t.status,c.statusMessage=t.statusText,t.getAllResponseHeaders().split(/\r?\n/).forEach((function(e){var t=e.match(/^([^:]+):\s*(.*)/);if(t){var n=t[1].toLowerCase();"set-cookie"===n?(void 0===c.headers[n]&&(c.headers[n]=[]),c.headers[n].push(t[2])):void 0!==c.headers[n]?c.headers[n]+=", "+t[2]:c.headers[n]=t[2],c.rawHeaders.push(t[1],t[2])}})),c._charset="x-user-defined",!i.overrideMimeType){var f=c.rawHeaders["mime-type"];if(f){var d=f.match(/;\s*charset=([^;])(;|$)/);d&&(c._charset=d[1].toLowerCase())}c._charset||(c._charset="utf-8")}}};a(c,s.Readable),c.prototype._read=function(){var e=this._resumeFetch;e&&(this._resumeFetch=null,e())},c.prototype._onXHRProgress=function(){var e=this,t=e._xhr,n=null;switch(e._mode){case"text:vbarray":if(t.readyState!==l.DONE)break;try{n=new o.VBArray(t.responseBody).toArray()}catch(e){}if(null!==n){e.push(ne
Line truncated
|
||||
/*! @license DOMPurify | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.0.8/LICENSE */
|
||||
e.exports=function(){"use strict";var e=Object.hasOwnProperty,t=Object.setPrototypeOf,n=Object.isFrozen,r=Object.keys,o=Object.freeze,i=Object.seal,a="undefined"!=typeof Reflect&&Reflect,s=a.apply,l=a.construct;s||(s=function(e,t,n){return e.apply(t,n)}),o||(o=function(e){return e}),i||(i=function(e){return e}),l||(l=function(e,t){return new(Function.prototype.bind.apply(e,[null].concat(function(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}(t))))});var c=k(Array.prototype.forEach),u=k(Array.prototype.indexOf),p=k(Array.prototype.join),f=k(Array.prototype.pop),d=k(Array.prototype.push),h=k(Array.prototype.slice),m=k(String.prototype.toLowerCase),g=k(String.prototype.match),v=k(String.prototype.replace),y=k(String.prototype.indexOf),b=k(String.prototype.trim),x=k(RegExp.prototype.test),w=O(RegExp),_=O(TypeError);function k(e){return function(t){for(var n=arguments.length,r=Array(n>1?n-1:0),o=1;o<n;o++)r[o-1]=arguments[o];return s(e,t,r)}}function O(e){return function(){for(var t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];return l(e,n)}}function E(e,r){t&&t(e,null);for(var o=r.length;o--;){var i=r[o];if("string"==typeof i){var a=m(i);a!==i&&(n(r)||(r[o]=a),i=a)}e[i]=!0}return e}function S(t){var n={},r=void 0;for(r in t)s(e,t,[r])&&(n[r]=t[r]);return n}var T=o(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),j=o(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","audio","canvas","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","video","view","vkern"]),A=o(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),C=o(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover"]),I=o(["#text"]),P=o(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","xmlns"]),R=o(["accent-height","accumulate","additive","alignment-baseline","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttrLine truncated
|
||||
/*!
|
||||
Copyright (c) 2017 Jed Watson.
|
||||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
*/!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var i=typeof r;if("string"===i||"number"===i)e.push(r);else if(Array.isArray(r)&&r.length){var a=o.apply(null,r);a&&e.push(a)}else if("object"===i)for(var s in r)n.call(r,s)&&r[s]&&e.push(s)}}return e.join(" ")}e.exports?(o.default=o,e.exports=o):void 0===(r=function(){return o}.apply(t,[]))||(e.exports=r)}()},function(e,t,n){n(159),e.exports=n(322)},function(e,t,n){"use strict";n.r(t);n(160),n(181),n(184),n(187),n(190),n(193),n(196),n(198),n(204),n(226),n(227)},function(e,t,n){n(69),n(103),n(110),n(173),n(179),n(180);var r=n(24);e.exports=r.Promise},function(e,t,n){var r=n(3),o=n(75),i=r.WeakMap;e.exports="function"==typeof i&&/native code/.test(o(i))},function(e,t,n){"use strict";var r=n(70),o=n(102);e.exports=r?{}.toString:function(){return"[object "+o(this)+"]"}},function(e,t,n){var r=n(76),o=n(41),i=function(e){return function(t,n){var i,a,s=String(o(t)),l=r(n),c=s.length;return l<0||l>=c?e?"":void 0:(i=s.charCodeAt(l))<55296||i>56319||l+1===c||(a=s.charCodeAt(l+1))<56320||a>57343?e?s.charAt(l):i:e?s.slice(l,l+2):a-56320+(i-55296<<10)+65536}};e.exports={codeAt:i(!1),charAt:i(!0)}},function(e,t,n){var r=n(29),o=n(79),i=n(81),a=n(19);e.exports=r("Reflect","ownKeys")||function(e){var t=o.f(a(e)),n=i.f;return n?t.concat(n(e)):t}},function(e,t,n){var r=n(28),o=n(35),i=n(166),a=function(e){return function(t,n,a){var s,l=r(t),c=o(l.length),u=i(a,c);if(e&&n!=n){for(;c>u;)if((s=l[u++])!=s)return!0}else for(;c>u;u++)if((e||u in l)&&l[u]===n)return e||u||0;return!e&&-1}};e.exports={includes:a(!0),indexOf:a(!1)}},function(e,t,n){var r=n(76),o=Math.max,i=Math.min;e.exports=function(e,t){var n=r(e);return n<0?o(n+t,0):i(n,t)}},function(e,t,n){"use strict";var r=n(106).IteratorPrototype,o=n(54),i=n(39),a=n(30),s=n(43),l=function(){return this};e.exports=function(e,t,n){var c=t+" Iterator";return e.prototype=o(r,{next:i(1,n)}),a(e,c,!1,!0),s[c]=l,e}},function(e,t,n){var r=n(7);e.exports=!r((function(){function e(){}return e.prototype.constructor=null,Object.getPrototypeOf(new e)!==e.prototype}))},function(e,t,n){var r=n(15),o=n(16),i=n(19),a=n(55);e.exports=r?Object.defineProperties:function(e,t){i(e);for(var n,r=a(t),s=r.length,l=0;s>l;)o.f(e,n=r[l++],t[n]);return e}},function(e,t,n){var r=n(8);e.exports=function(e){if(!r(e)&&null!==e)throw TypeError("Can't set "+String(e)+" as a prototype");return e}},function(e,t){e.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}},function(e,t,n){"use strict";var r=n(28),o=n(111),i=n(43),a=n(33),s=n(77),l=a.set,c=a.getterFor("Array Iterator");e.exports=s(Array,"Array",(function(e,t){l(this,{type:"Array Iterator",target:r(e),index:0,kind:t})}),(function(){var e=c(this),t=e.target,n=e.kind,r=e.index++;return!t||r>=t.length?(e.target=void 0,{value:void 0,done:!0}):"keys"==n?{value:r,done:!1}:"values"==n?{value:t[r],done:!1}:{value:[r,t[r]],done:!1}}),"values"),i.Arguments=i.Array,o("keys"),o("values"),o("entries")},function(e,t,n){"use strict";var r,o,i,a,s=n(11),l=n(21),c=n(3),u=n(29),p=n(112),f=n(23),d=n(113),h=n(30),m=n(114),g=n(8),v=n(44),y=n(83),b=n(27),x=n(75),w=n(56),_=n(115),k=n(116),O=n(117).set,E=n(177),S=n(120),T=n(178),j=n(84),A=n(121),C=n(33),I=n(82),P=n(4),R=n(85),N=P("species"),L="Promise",M=C.get,D=C.set,F=C.getterFor(L),z=p,U=c.TypeError,B=c.document,$=c.process,W=u("fetch"),q=j.f,H=q,V="process"==b($),Y=!!(B&&B.createEvent&&c.dispatchEvent),G=I(L,(function(){if(!(x(z)!==String(z))){if(66===R)return!0;if(!V&&"function"!=typeof PromiseRejectionEvent)return!0}if(l&&!z.prototype.finally)return!0;if(R>=51&&/native code/.test(z))return!1;var e=z.resolve(1),t=function(e){e((function(){}),(function(){}))};return(e.constructor={})[N]=t,!(e.then((function(){}))instanceof t)})),Q=G||!_((function(e){z.all(e).catch((function(){}))})),X=function(e){var t;return!(!g(e)||"function"!=typeof(t=e.then))&&t},K=function(e,t,n){if(!t.notified){t.notified=!0;var r=t.reactions;E((function(){for(var o=t.value,i=1==t.state,a=0;r.length>a;){var s,l,c,u=r[a++],p=i?u.ok:u.fail,f=u.resolve,d=u.reject,h=u.domain;try{p?(i||(2===t.rejection&&te(e,t),t.rejection=1),!0===p?s=o:(h&&h.enter(),s=p(o),h&&(h.exit(),c=!0)),s===u.promise?d(U("Promise-chain cycle")):(l=X(s))?l.call(s,f,d):f(s)):d(o)}catch(e){h&&!c&&h.exit(),d(e)}}t.reactions=[],t.notified=!1,n&&!t.rejection&&Z(e,t)}))}},J=function(e,t,n){var r,o;Y?((r=B.createEvent("Event")).promise=t,r.reason=n,r.initEvent(e,!1,!0),c.dispatchEvent(r)):r={promise:t,reason:n},(oLine truncated
|
||||
/** @license React v16.13.1
|
||||
* react.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/var r=n(128),o="function"==typeof Symbol&&Symbol.for,i=o?Symbol.for("react.element"):60103,a=o?Symbol.for("react.portal"):60106,s=o?Symbol.for("react.fragment"):60107,l=o?Symbol.for("react.strict_mode"):60108,c=o?Symbol.for("react.profiler"):60114,u=o?Symbol.for("react.provider"):60109,p=o?Symbol.for("react.context"):60110,f=o?Symbol.for("react.forward_ref"):60112,d=o?Symbol.for("react.suspense"):60113,h=o?Symbol.for("react.memo"):60115,m=o?Symbol.for("react.lazy"):60116,g="function"==typeof Symbol&&Symbol.iterator;function v(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var y={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},b={};function x(e,t,n){this.props=e,this.context=t,this.refs=b,this.updater=n||y}function w(){}function _(e,t,n){this.props=e,this.context=t,this.refs=b,this.updater=n||y}x.prototype.isReactComponent={},x.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error(v(85));this.updater.enqueueSetState(this,e,t,"setState")},x.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},w.prototype=x.prototype;var k=_.prototype=new w;k.constructor=_,r(k,x.prototype),k.isPureReactComponent=!0;var O={current:null},E=Object.prototype.hasOwnProperty,S={key:!0,ref:!0,__self:!0,__source:!0};function T(e,t,n){var r,o={},a=null,s=null;if(null!=t)for(r in void 0!==t.ref&&(s=t.ref),void 0!==t.key&&(a=""+t.key),t)E.call(t,r)&&!S.hasOwnProperty(r)&&(o[r]=t[r]);var l=arguments.length-2;if(1===l)o.children=n;else if(1<l){for(var c=Array(l),u=0;u<l;u++)c[u]=arguments[u+2];o.children=c}if(e&&e.defaultProps)for(r in l=e.defaultProps)void 0===o[r]&&(o[r]=l[r]);return{$$typeof:i,type:e,key:a,ref:s,props:o,_owner:O.current}}function j(e){return"object"==typeof e&&null!==e&&e.$$typeof===i}var A=/\/+/g,C=[];function I(e,t,n,r){if(C.length){var o=C.pop();return o.result=e,o.keyPrefix=t,o.func=n,o.context=r,o.count=0,o}return{result:e,keyPrefix:t,func:n,context:r,count:0}}function P(e){e.result=null,e.keyPrefix=null,e.func=null,e.context=null,e.count=0,10>C.length&&C.push(e)}function R(e,t,n){return null==e?0:function e(t,n,r,o){var s=typeof t;"undefined"!==s&&"boolean"!==s||(t=null);var l=!1;if(null===t)l=!0;else switch(s){case"string":case"number":l=!0;break;case"object":switch(t.$$typeof){case i:case a:l=!0}}if(l)return r(o,t,""===n?"."+N(t,0):n),1;if(l=0,n=""===n?".":n+":",Array.isArray(t))for(var c=0;c<t.length;c++){var u=n+N(s=t[c],c);l+=e(s,u,r,o)}else if(null===t||"object"!=typeof t?u=null:u="function"==typeof(u=g&&t[g]||t["@@iterator"])?u:null,"function"==typeof u)for(t=u.call(t),c=0;!(s=t.next()).done;)l+=e(s=s.value,u=n+N(s,c++),r,o);else if("object"===s)throw r=""+t,Error(v(31,"[object Object]"===r?"object with keys {"+Object.keys(t).join(", ")+"}":r,""));return l}(e,"",t,n)}function N(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+(""+e).replace(/[=:]/g,(function(e){return t[e]}))}(e.key):t.toString(36)}function L(e,t){e.func.call(e.context,t,e.count++)}function M(e,t,n){var r=e.result,o=e.keyPrefix;e=e.func.call(e.context,t,e.count++),Array.isArray(e)?D(e,r,n,(function(e){return e})):null!=e&&(j(e)&&(e=function(e,t){return{$$typeof:i,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(e,o+(!e.key||t&&t.key===e.key?"":(""+e.key).replace(A,"$&/")+"/")+n)),r.push(e))}function D(e,t,n,r,o){var i="";null!=n&&(i=(""+n).replace(A,"$&/")+"/"),R(e,M,t=I(t,i,r,o)),P(t)}var F={current:null};function z(){var e=F.current;if(null===e)throw Error(v(321));return e}var U={ReactCurrentDispatcher:F,ReactCurrentBatchConfig:{suspense:null},ReactCurrentOwner:O,IsSomeRendererActing:{current:!1},assign:r};t.Children={map:function(e,t,n){if(null==e)return e;var r=[];return D(e,r,null,t,n),r},forEach:function(e,t,n){if(null==e)return e;R(e,L,t=I(null,null,t,n)),P(t)},count:function(e){return R(e,(function(){return null}),null)},toArray:function(e){var t=[];return D(e,t,null,(function(e){return e})),t},only:function(e){if(!j(e))throw Error(v(143));return e}},t.Component=x,t.Fragment=s,t.Profiler=c,t.PureComponent=_,t.StrictMode=l,t.Suspense=d,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=U,t.cloneElement=function(e,t,n){if(null==e)throw Error(v(267,e));var o=r({},e.props),a=e.key,s=e.ref,l=e._owner;if(null!=t){if(void 0!==t.ref&&(s=t.ref,l=O.current),void 0!==t.key&&(a=""+t.key),e.type&&e.type.defaultProps)var c=e.type.defaultProps;for(u in t)E.call(t,u)&&!S.hasOwnProperty(u)&&(o[u]=void 0===t[u]&&void 0!==c?c[u]:t[u])}var u=arguments.length-2;if(1===u)o.children=n;else if(1<u){c=Array(u);for(var p=0;p<u;p++)c[p]=arguments[p+2];o.children=c}return{$$typeof:i,tLine truncated
|
||||
/** @license React v16.13.1
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/var r=n(0),o=n(128),i=n(230);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}if(!r)throw Error(a(227));function s(e,t,n,r,o,i,a,s,l){var c=Array.prototype.slice.call(arguments,3);try{t.apply(n,c)}catch(e){this.onError(e)}}var l=!1,c=null,u=!1,p=null,f={onError:function(e){l=!0,c=e}};function d(e,t,n,r,o,i,a,u,p){l=!1,c=null,s.apply(f,arguments)}var h=null,m=null,g=null;function v(e,t,n){var r=e.type||"unknown-event";e.currentTarget=g(n),function(e,t,n,r,o,i,s,f,h){if(d.apply(this,arguments),l){if(!l)throw Error(a(198));var m=c;l=!1,c=null,u||(u=!0,p=m)}}(r,t,void 0,e),e.currentTarget=null}var y=null,b={};function x(){if(y)for(var e in b){var t=b[e],n=y.indexOf(e);if(!(-1<n))throw Error(a(96,e));if(!_[n]){if(!t.extractEvents)throw Error(a(97,e));for(var r in _[n]=t,n=t.eventTypes){var o=void 0,i=n[r],s=t,l=r;if(k.hasOwnProperty(l))throw Error(a(99,l));k[l]=i;var c=i.phasedRegistrationNames;if(c){for(o in c)c.hasOwnProperty(o)&&w(c[o],s,l);o=!0}else i.registrationName?(w(i.registrationName,s,l),o=!0):o=!1;if(!o)throw Error(a(98,r,e))}}}}function w(e,t,n){if(O[e])throw Error(a(100,e));O[e]=t,E[e]=t.eventTypes[n].dependencies}var _=[],k={},O={},E={};function S(e){var t,n=!1;for(t in e)if(e.hasOwnProperty(t)){var r=e[t];if(!b.hasOwnProperty(t)||b[t]!==r){if(b[t])throw Error(a(102,t));b[t]=r,n=!0}}n&&x()}var T=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),j=null,A=null,C=null;function I(e){if(e=m(e)){if("function"!=typeof j)throw Error(a(280));var t=e.stateNode;t&&(t=h(t),j(e.stateNode,e.type,t))}}function P(e){A?C?C.push(e):C=[e]:A=e}function R(){if(A){var e=A,t=C;if(C=A=null,I(e),t)for(e=0;e<t.length;e++)I(t[e])}}function N(e,t){return e(t)}function L(e,t,n,r,o){return e(t,n,r,o)}function M(){}var D=N,F=!1,z=!1;function U(){null===A&&null===C||(M(),R())}function B(e,t,n){if(z)return e(t,n);z=!0;try{return D(e,t,n)}finally{z=!1,U()}}var $=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,W=Object.prototype.hasOwnProperty,q={},H={};function V(e,t,n,r,o,i){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=r,this.attributeNamespace=o,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=i}var Y={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){Y[e]=new V(e,0,!1,e,null,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var t=e[0];Y[t]=new V(t,1,!1,e[1],null,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){Y[e]=new V(e,2,!1,e.toLowerCase(),null,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){Y[e]=new V(e,2,!1,e,null,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){Y[e]=new V(e,3,!1,e.toLowerCase(),null,!1)})),["checked","multiple","muted","selected"].forEach((function(e){Y[e]=new V(e,3,!0,e,null,!1)})),["capture","download"].forEach((function(e){Y[e]=new V(e,4,!1,e,null,!1)})),["cols","rows","size","span"].forEach((function(e){Y[e]=new V(e,6,!1,e,null,!1)})),["rowSpan","start"].forEach((function(e){Y[e]=new V(e,5,!1,e.toLowerCase(),null,!1)}));var G=/[\-:]([a-z])/g;function Q(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-rLine truncated
|
||||
/** @license React v0.19.1
|
||||
* scheduler.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/var r,o,i,a,s;if("undefined"==typeof window||"function"!=typeof MessageChannel){var l=null,c=null,u=function(){if(null!==l)try{var e=t.unstable_now();l(!0,e),l=null}catch(e){throw setTimeout(u,0),e}},p=Date.now();t.unstable_now=function(){return Date.now()-p},r=function(e){null!==l?setTimeout(r,0,e):(l=e,setTimeout(u,0))},o=function(e,t){c=setTimeout(e,t)},i=function(){clearTimeout(c)},a=function(){return!1},s=t.unstable_forceFrameRate=function(){}}else{var f=window.performance,d=window.Date,h=window.setTimeout,m=window.clearTimeout;if("undefined"!=typeof console){var g=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof g&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof f&&"function"==typeof f.now)t.unstable_now=function(){return f.now()};else{var v=d.now();t.unstable_now=function(){return d.now()-v}}var y=!1,b=null,x=-1,w=5,_=0;a=function(){return t.unstable_now()>=_},s=function(){},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing framerates higher than 125 fps is not unsupported"):w=0<e?Math.floor(1e3/e):5};var k=new MessageChannel,O=k.port2;k.port1.onmessage=function(){if(null!==b){var e=t.unstable_now();_=e+w;try{b(!0,e)?O.postMessage(null):(y=!1,b=null)}catch(e){throw O.postMessage(null),e}}else y=!1},r=function(e){b=e,y||(y=!0,O.postMessage(null))},o=function(e,n){x=h((function(){e(t.unstable_now())}),n)},i=function(){m(x),x=-1}}function E(e,t){var n=e.length;e.push(t);e:for(;;){var r=n-1>>>1,o=e[r];if(!(void 0!==o&&0<j(o,t)))break e;e[r]=t,e[n]=o,n=r}}function S(e){return void 0===(e=e[0])?null:e}function T(e){var t=e[0];if(void 0!==t){var n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,o=e.length;r<o;){var i=2*(r+1)-1,a=e[i],s=i+1,l=e[s];if(void 0!==a&&0>j(a,n))void 0!==l&&0>j(l,a)?(e[r]=l,e[s]=n,r=s):(e[r]=a,e[i]=n,r=i);else{if(!(void 0!==l&&0>j(l,n)))break e;e[r]=l,e[s]=n,r=s}}}return t}return null}function j(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var A=[],C=[],I=1,P=null,R=3,N=!1,L=!1,M=!1;function D(e){for(var t=S(C);null!==t;){if(null===t.callback)T(C);else{if(!(t.startTime<=e))break;T(C),t.sortIndex=t.expirationTime,E(A,t)}t=S(C)}}function F(e){if(M=!1,D(e),!L)if(null!==S(A))L=!0,r(z);else{var t=S(C);null!==t&&o(F,t.startTime-e)}}function z(e,n){L=!1,M&&(M=!1,i()),N=!0;var r=R;try{for(D(n),P=S(A);null!==P&&(!(P.expirationTime>n)||e&&!a());){var s=P.callback;if(null!==s){P.callback=null,R=P.priorityLevel;var l=s(P.expirationTime<=n);n=t.unstable_now(),"function"==typeof l?P.callback=l:P===S(A)&&T(A),D(n)}else T(A);P=S(A)}if(null!==P)var c=!0;else{var u=S(C);null!==u&&o(F,u.startTime-n),c=!1}return c}finally{P=null,R=r,N=!1}}function U(e){switch(e){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var B=s;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){L||N||(L=!0,r(z))},t.unstable_getCurrentPriorityLevel=function(){return R},t.unstable_getFirstCallbackNode=function(){return S(A)},t.unstable_next=function(e){switch(R){case 1:case 2:case 3:var t=3;break;default:t=R}var n=R;R=t;try{return e()}finally{R=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=B,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=R;R=e;try{return t()}finally{R=n}},t.unstable_scheduleCallback=function(e,n,a){var s=t.unstable_now();if("object"==typeof a&&null!==a){var l=a.delay;l="number"==typeof l&&0<l?s+l:s,a="number"==typeof a.timeout?a.timeout:U(e)}else a=U(e),l=s;return e={id:I++,callback:n,priorityLevel:e,startTime:l,expirationTime:a=l+a,sortIndex:-1},l>s?(e.sortIndex=l,E(C,e),null===S(A)&&e===S(C)&&(M?i():M=!0,o(F,l-s))):(e.sortIndex=a,E(A,e),L||N||(L=!0,r(z))),e},t.unstable_shouldYield=function(){var e=t.unstable_now();D(e);var n=S(A);return n!==P&&null!==P&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime<P.expirationTime||a()},t.unstable_wrapCallback=function(e){var t=R;return function(){var n=R;R=t;try{return e.apply(this,arguments)}finally{R=n}}}},function(e,t,n){"use strict";var r=n(233);function o(){}function i(){}i.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,i,a){if(a!==r){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;v
Line truncated
|
||||
/** @license React v16.13.0
|
||||
* react-is.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/var r="function"==typeof Symbol&&Symbol.for,o=r?Symbol.for("react.element"):60103,i=r?Symbol.for("react.portal"):60106,a=r?Symbol.for("react.fragment"):60107,s=r?Symbol.for("react.strict_mode"):60108,l=r?Symbol.for("react.profiler"):60114,c=r?Symbol.for("react.provider"):60109,u=r?Symbol.for("react.context"):60110,p=r?Symbol.for("react.async_mode"):60111,f=r?Symbol.for("react.concurrent_mode"):60111,d=r?Symbol.for("react.forward_ref"):60112,h=r?Symbol.for("react.suspense"):60113,m=r?Symbol.for("react.suspense_list"):60120,g=r?Symbol.for("react.memo"):60115,v=r?Symbol.for("react.lazy"):60116,y=r?Symbol.for("react.block"):60121,b=r?Symbol.for("react.fundamental"):60117,x=r?Symbol.for("react.responder"):60118,w=r?Symbol.for("react.scope"):60119;function _(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case o:switch(e=e.type){case p:case f:case a:case l:case s:case h:return e;default:switch(e=e&&e.$$typeof){case u:case d:case v:case g:case c:return e;default:return t}}case i:return t}}}function k(e){return _(e)===f}t.AsyncMode=p,t.ConcurrentMode=f,t.ContextConsumer=u,t.ContextProvider=c,t.Element=o,t.ForwardRef=d,t.Fragment=a,t.Lazy=v,t.Memo=g,t.Portal=i,t.Profiler=l,t.StrictMode=s,t.Suspense=h,t.isAsyncMode=function(e){return k(e)||_(e)===p},t.isConcurrentMode=k,t.isContextConsumer=function(e){return _(e)===u},t.isContextProvider=function(e){return _(e)===c},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===o},t.isForwardRef=function(e){return _(e)===d},t.isFragment=function(e){return _(e)===a},t.isLazy=function(e){return _(e)===v},t.isMemo=function(e){return _(e)===g},t.isPortal=function(e){return _(e)===i},t.isProfiler=function(e){return _(e)===l},t.isStrictMode=function(e){return _(e)===s},t.isSuspense=function(e){return _(e)===h},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===a||e===f||e===l||e===s||e===h||e===m||"object"==typeof e&&null!==e&&(e.$$typeof===v||e.$$typeof===g||e.$$typeof===c||e.$$typeof===u||e.$$typeof===d||e.$$typeof===b||e.$$typeof===x||e.$$typeof===w||e.$$typeof===y)},t.typeOf=_},function(e,t,n){"use strict";t.byteLength=function(e){var t=c(e),n=t[0],r=t[1];return 3*(n+r)/4-r},t.toByteArray=function(e){var t,n,r=c(e),a=r[0],s=r[1],l=new i(function(e,t,n){return 3*(t+n)/4-n}(0,a,s)),u=0,p=s>0?a-4:a;for(n=0;n<p;n+=4)t=o[e.charCodeAt(n)]<<18|o[e.charCodeAt(n+1)]<<12|o[e.charCodeAt(n+2)]<<6|o[e.charCodeAt(n+3)],l[u++]=t>>16&255,l[u++]=t>>8&255,l[u++]=255&t;2===s&&(t=o[e.charCodeAt(n)]<<2|o[e.charCodeAt(n+1)]>>4,l[u++]=255&t);1===s&&(t=o[e.charCodeAt(n)]<<10|o[e.charCodeAt(n+1)]<<4|o[e.charCodeAt(n+2)]>>2,l[u++]=t>>8&255,l[u++]=255&t);return l},t.fromByteArray=function(e){for(var t,n=e.length,o=n%3,i=[],a=0,s=n-o;a<s;a+=16383)i.push(u(e,a,a+16383>s?s:a+16383));1===o?(t=e[n-1],i.push(r[t>>2]+r[t<<4&63]+"==")):2===o&&(t=(e[n-2]<<8)+e[n-1],i.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"="));return i.join("")};for(var r=[],o=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,l=a.length;s<l;++s)r[s]=a[s],o[a.charCodeAt(s)]=s;function c(e){var t=e.length;if(t%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function u(e,t,n){for(var o,i,a=[],s=t;s<n;s+=3)o=(e[s]<<16&16711680)+(e[s+1]<<8&65280)+(255&e[s+2]),a.push(r[(i=o)>>18&63]+r[i>>12&63]+r[i>>6&63]+r[63&i]);return a.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},function(e,t){t.read=function(e,t,n,r,o){var i,a,s=8*o-r-1,l=(1<<s)-1,c=l>>1,u=-7,p=n?o-1:0,f=n?-1:1,d=e[t+p];for(p+=f,i=d&(1<<-u)-1,d>>=-u,u+=s;u>0;i=256*i+e[t+p],p+=f,u-=8);for(a=i&(1<<-u)-1,i>>=-u,u+=r;u>0;a=256*a+e[t+p],p+=f,u-=8);if(0===i)i=1-c;else{if(i===l)return a?NaN:1/0*(d?-1:1);a+=Math.pow(2,r),i-=c}return(d?-1:1)*a*Math.pow(2,i-r)},t.write=function(e,t,n,r,o,i){var a,s,l,c=8*i-o-1,u=(1<<c)-1,p=u>>1,f=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,d=r?0:i-1,h=r?1:-1,m=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=u):(a=Math.floor(Math.log(t)/Math.LN2),t*(l=Math.pow(2,-a))<1&&(a--,l*=2),(t+=a+p>=1?f/l:f*Math.pow(2,1-p))*l>=2&&(a++,l/=2),a+p>=u?(s=0,a=u):a+p>=1?(s=(t*l-1)*Math.pow(2,o),a+=p):(s=t*Math.pow(2,p-1)*Math.pow(2,o),a=0));o>=8;e[n+d]=255&s,d+=h,s/=256,o-=8);for(a=a<<o|s,c+=o;c>0;e[n+d]=255&a,d+=h,a/=256,c-=8);e[n+d-h]|=128*m}},function(e,t,n){"use strict";(function(t){e.exports={order:100,allowEmpty:!0,canParse:".json",parse:function(e){return new Promise((function(n,r){var o=e.data;t.isBuffer(o)&&(o=o.toString()),"string"==typeof o?0===o.trim().length?n(void 0):n(JSON.parse(o)):n(o)}))}}}).call(this,n(14).Buffer)},function(e,t,n){"use strict";(function(t){var r=n(131);e.exports={order:200,allowEmpty:!0,canParse:[".yaml",".yml",".json"],parse:function(e){return new Promise((function(n,o){var i=e.data;t.isBuffer(i)&&(i=i.toString()),n("string"==typeof i?r.parse(i):i)}))}}}).call(this,n(14).Buffer)},function(e,t,nLine truncated
|
||||
/*!
|
||||
* Stickyfill -- `position: sticky` polyfill
|
||||
* v. 1.1.1 | https://github.com/wilddeer/stickyfill
|
||||
* Copyright Oleg Korsunsky | http://wd.dizaina.net/
|
||||
*
|
||||
* MIT License
|
||||
*/
|
||||
e.exports=function(e,t){e||(e=document),t||(t=window);var n,r,o=[],i=!1,a=e.documentElement,s=function(){},l="hidden",c="visibilitychange";void 0!==e.webkitHidden&&(l="webkitHidden",c="webkitvisibilitychange"),t.getComputedStyle||d();for(var u=["","-webkit-","-moz-","-ms-"],p=document.createElement("div"),f=u.length-1;f>=0;f--){try{p.style.position=u[f]+"sticky"}catch(e){}""!=p.style.position&&d()}function d(){C=L=I=P=R=N=s}function h(e){return parseFloat(e)||0}function m(){n={top:t.pageYOffset,left:t.pageXOffset}}function g(){if(t.pageXOffset!=n.left)return m(),void I();t.pageYOffset!=n.top&&(m(),y())}function v(e){setTimeout((function(){t.pageYOffset!=n.top&&(n.top=t.pageYOffset,y())}),0)}function y(){for(var e=o.length-1;e>=0;e--)b(o[e])}function b(e){if(e.inited){var t=n.top<=e.limit.start?0:n.top>=e.limit.end?2:1;e.mode!=t&&function(e,t){var n=e.node.style;switch(t){case 0:n.position="absolute",n.left=e.offset.left+"px",n.right=e.offset.right+"px",n.top=e.offset.top+"px",n.bottom="auto",n.width="auto",n.marginLeft=0,n.marginRight=0,n.marginTop=0;break;case 1:n.position="fixed",n.left=e.box.left+"px",n.right=e.box.right+"px",n.top=e.css.top,n.bottom="auto",n.width="auto",n.marginLeft=0,n.marginRight=0,n.marginTop=0;break;case 2:n.position="absolute",n.left=e.offset.left+"px",n.right=e.offset.right+"px",n.top="auto",n.bottom=0,n.width="auto",n.marginLeft=0,n.marginRight=0}e.mode=t}(e,t)}}function x(e){isNaN(parseFloat(e.computed.top))||e.isCell||(e.inited=!0,e.clone||function(e){e.clone=document.createElement("div");var t=e.node.nextSibling||e.node,n=e.clone.style;n.height=e.height+"px",n.width=e.width+"px",n.marginTop=e.computed.marginTop,n.marginBottom=e.computed.marginBottom,n.marginLeft=e.computed.marginLeft,n.marginRight=e.computed.marginRight,n.padding=n.border=n.borderSpacing=0,n.fontSize="1em",n.position="static",n.cssFloat=e.computed.cssFloat,e.node.parentNode.insertBefore(e.clone,t)}(e),"absolute"!=e.parent.computed.position&&"relative"!=e.parent.computed.position&&(e.parent.node.style.position="relative"),b(e),e.parent.height=e.parent.node.offsetHeight,e.docOffsetTop=E(e.clone))}function w(e){var t=!0;e.clone&&function(e){e.clone.parentNode.removeChild(e.clone),e.clone=void 0}(e),function(e,t){for(key in t)t.hasOwnProperty(key)&&(e[key]=t[key])}(e.node.style,e.css);for(var n=o.length-1;n>=0;n--)if(o[n].node!==e.node&&o[n].parent.node===e.parent.node){t=!1;break}t&&(e.parent.node.style.position=e.parent.css.position),e.mode=-1}function _(){for(var e=o.length-1;e>=0;e--)x(o[e])}function k(){for(var e=o.length-1;e>=0;e--)w(o[e])}function O(e){var t=getComputedStyle(e),n=e.parentNode,r=getComputedStyle(n),o=e.style.position;e.style.position="relative";var i={top:t.top,marginTop:t.marginTop,marginBottom:t.marginBottom,marginLeft:t.marginLeft,marginRight:t.marginRight,cssFloat:t.cssFloat},s={top:h(t.top),marginBottom:h(t.marginBottom),paddingLeft:h(t.paddingLeft),paddingRight:h(t.paddingRight),borderLeftWidth:h(t.borderLeftWidth),borderRightWidth:h(t.borderRightWidth)};e.style.position=o;var l={position:e.style.position,top:e.style.top,bottom:e.style.bottom,left:e.style.left,right:e.style.right,width:e.style.width,marginTop:e.style.marginTop,marginLeft:e.style.marginLeft,marginRight:e.style.marginRight},c=S(e),u=S(n),p={node:n,css:{position:n.style.position},computed:{position:r.position},numeric:{borderLeftWidth:h(r.borderLeftWidth),borderRightWidth:h(r.borderRightWidth),borderTopWidth:h(r.borderTopWidth),borderBottomWidth:h(r.borderBottomWidth)}};return{node:e,box:{left:c.win.left,right:a.clientWidth-c.win.right},offset:{top:c.win.top-u.win.top-p.numeric.borderTopWidth,left:c.win.left-u.win.left-p.numeric.borderLeftWidth,right:-c.win.right+u.win.right-p.numeric.borderRightWidth},css:l,isCell:"table-cell"==t.display,computed:i,numeric:s,width:c.win.right-c.win.left,height:c.win.bottom-c.win.top,mode:-1,inited:!1,parent:p,limit:{start:c.doc.top-s.top,end:u.doc.top+n.offsetHeight-p.numeric.borderBottomWidth-e.offsetHeight-s.top-s.marginBottom}}}function E(e){for(var t=0;e;)t+=e.offsetTop,e=e.offsetParent;return t}function S(e){var n=e.getBoundingClientRect();return{doc:{top:n.top+t.pageYOffset,left:n.left+t.pageXOffset},win:n}}function T(){r=setInterval((function(){!function(){for(var e=o.length-1;e>=0;e--)if(o[e].inited){var t=Math.abs(E(o[e].clone)-o[e].docOffsetTop),n=Math.abs(o[e].parent.node.offsetHeight-o[e].parent.height);if(t>=2||n>=2)return!1}return!0}()&&I()}),500)}function j(){clearInterval(r)}function A(){i&&(document[l]?j():T())}function C(){i||(m(),_(),t.addEventListener("scroll",g),t.addEventListener("wheel",v),t.addEventListener("resize",I),t.addEventListener("orientationchange",I),e.addEventListener(c,A),T(),i=!0)}function I(){if(i){k();for(var e=o.length-1;e>=0;e--)o[e]=O(o[e].node);_()}}function P(){t.removeEventListener("scroll",g),t.removeEventListener("wheel",v),t.removeEventListener("resize",I),t.removeEventListener("orientationchange",I),e.removeEventListener(c,A),j(),i=!1}fuLine truncated
|
||||
/*!
|
||||
* perfect-scrollbar v1.5.0
|
||||
* Copyright 2020 Hyunje Jun, MDBootstrap and Contributors
|
||||
* Licensed under MIT
|
||||
*/
|
||||
function vi(e){return getComputedStyle(e)}function yi(e,t){for(var n in t){var r=t[n];"number"==typeof r&&(r+="px"),e.style[n]=r}return e}function bi(e){var t=document.createElement("div");return t.className=e,t}var xi="undefined"!=typeof Element&&(Element.prototype.matches||Element.prototype.webkitMatchesSelector||Element.prototype.mozMatchesSelector||Element.prototype.msMatchesSelector);function wi(e,t){if(!xi)throw new Error("No element matching method supported");return xi.call(e,t)}function _i(e){e.remove?e.remove():e.parentNode&&e.parentNode.removeChild(e)}function ki(e,t){return Array.prototype.filter.call(e.children,(function(e){return wi(e,t)}))}var Oi="ps",Ei="ps__rtl",Si={thumb:function(e){return"ps__thumb-"+e},rail:function(e){return"ps__rail-"+e},consuming:"ps__child--consume"},Ti={focus:"ps--focus",clicking:"ps--clicking",active:function(e){return"ps--active-"+e},scrolling:function(e){return"ps--scrolling-"+e}},ji={x:null,y:null};function Ai(e,t){var n=e.element.classList,r=Ti.scrolling(t);n.contains(r)?clearTimeout(ji[t]):n.add(r)}function Ci(e,t){ji[t]=setTimeout((function(){return e.isAlive&&e.element.classList.remove(Ti.scrolling(t))}),e.settings.scrollingThreshold)}var Ii=function(e){this.element=e,this.handlers={}},Pi={isEmpty:{configurable:!0}};Ii.prototype.bind=function(e,t){void 0===this.handlers[e]&&(this.handlers[e]=[]),this.handlers[e].push(t),this.element.addEventListener(e,t,!1)},Ii.prototype.unbind=function(e,t){var n=this;this.handlers[e]=this.handlers[e].filter((function(r){return!(!t||r===t)||(n.element.removeEventListener(e,r,!1),!1)}))},Ii.prototype.unbindAll=function(){for(var e in this.handlers)this.unbind(e)},Pi.isEmpty.get=function(){var e=this;return Object.keys(this.handlers).every((function(t){return 0===e.handlers[t].length}))},Object.defineProperties(Ii.prototype,Pi);var Ri=function(){this.eventElements=[]};function Ni(e){if("function"==typeof window.CustomEvent)return new CustomEvent(e);var t=document.createEvent("CustomEvent");return t.initCustomEvent(e,!1,!1,void 0),t}function Li(e,t,n,r,o){var i;if(void 0===r&&(r=!0),void 0===o&&(o=!1),"top"===t)i=["contentHeight","containerHeight","scrollTop","y","up","down"];else{if("left"!==t)throw new Error("A proper axis should be provided");i=["contentWidth","containerWidth","scrollLeft","x","left","right"]}!function(e,t,n,r,o){var i=n[0],a=n[1],s=n[2],l=n[3],c=n[4],u=n[5];void 0===r&&(r=!0);void 0===o&&(o=!1);var p=e.element;e.reach[l]=null,p[s]<1&&(e.reach[l]="start");p[s]>e[i]-e[a]-1&&(e.reach[l]="end");t&&(p.dispatchEvent(Ni("ps-scroll-"+l)),t<0?p.dispatchEvent(Ni("ps-scroll-"+c)):t>0&&p.dispatchEvent(Ni("ps-scroll-"+u)),r&&function(e,t){Ai(e,t),Ci(e,t)}(e,l));e.reach[l]&&(t||o)&&p.dispatchEvent(Ni("ps-"+l+"-reach-"+e.reach[l]))}(e,n,i,r,o)}function Mi(e){return parseInt(e,10)||0}Ri.prototype.eventElement=function(e){var t=this.eventElements.filter((function(t){return t.element===e}))[0];return t||(t=new Ii(e),this.eventElements.push(t)),t},Ri.prototype.bind=function(e,t,n){this.eventElement(e).bind(t,n)},Ri.prototype.unbind=function(e,t,n){var r=this.eventElement(e);r.unbind(t,n),r.isEmpty&&this.eventElements.splice(this.eventElements.indexOf(r),1)},Ri.prototype.unbindAll=function(){this.eventElements.forEach((function(e){return e.unbindAll()})),this.eventElements=[]},Ri.prototype.once=function(e,t,n){var r=this.eventElement(e),o=function(e){r.unbind(t,o),n(e)};r.bind(t,o)};var Di={isWebKit:"undefined"!=typeof document&&"WebkitAppearance"in document.documentElement.style,supportsTouch:"undefined"!=typeof window&&("ontouchstart"in window||"maxTouchPoints"in window.navigator&&window.navigator.maxTouchPoints>0||window.DocumentTouch&&document instanceof window.DocumentTouch),supportsIePointer:"undefined"!=typeof navigator&&navigator.msMaxTouchPoints,isChrome:"undefined"!=typeof navigator&&/Chrome/i.test(navigator&&navigator.userAgent)};function Fi(e){var t=e.element,n=Math.floor(t.scrollTop),r=t.getBoundingClientRect();e.containerWidth=Math.ceil(r.width),e.containerHeight=Math.ceil(r.height),e.contentWidth=t.scrollWidth,e.contentHeight=t.scrollHeight,t.contains(e.scrollbarXRail)||(ki(t,Si.rail("x")).forEach((function(e){return _i(e)})),t.appendChild(e.scrollbarXRail)),t.contains(e.scrollbarYRail)||(ki(t,Si.rail("y")).forEach((function(e){return _i(e)})),t.appendChild(e.scrollbarYRail)),!e.settings.suppressScrollX&&e.containerWidth+e.settings.scrollXMarginOffset<e.contentWidth?(e.scrollbarXActive=!0,e.railXWidth=e.containerWidth-e.railXMarginWidth,e.railXRatio=e.containerWidth/e.railXWidth,e.scrollbarXWidth=zi(e,Mi(e.railXWidth*e.containerWidth/e.contentWidth)),e.scrollbarXLeft=Mi((e.negativeScrollAdjustment+t.scrollLeft)*(e.railXWidth-e.scrollbarXWidth)/(e.contentWidth-e.containerWidth))):e.scrollbarXActive=!1,!e.settings.suppressScrollY&&e.containerHeight+e.settings.scrollYMarginOffset<e.contentHeight?(e.scrollbarYActive=!0,e.railYHeight=e.containerHeight-e.railYMarginHeight,e.railYRatio=e.containerHeight/e.railYHeightLine truncated
|
||||
//# sourceMappingURL=redoc.standalone.js.map
|
||||
@@ -1,3 +0,0 @@
|
||||
/*! For license information please see swagger-ui-bundle.js.LICENSE.txt */
|
||||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(function(){try{return require("esprima")}catch(e){}}()):"function"==typeof define&&define.amd?define(["esprima"],t):"object"==typeof exports?exports.SwaggerUIBundle=t(function(){try{return require("esprima")}catch(e){}}()):e.SwaggerUIBundle=t(e.esprima)}(this,(function(e){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist",n(n.s=544)}([function(e,t,n){"use strict";e.exports=n(129)},function(e,t,n){e.exports=function(){"use strict";var e=Array.prototype.slice;function t(e,t){t&&(e.prototype=Object.create(t.prototype)),e.prototype.constructor=e}function n(e){return i(e)?e:J(e)}function r(e){return s(e)?e:K(e)}function o(e){return u(e)?e:Y(e)}function a(e){return i(e)&&!c(e)?e:G(e)}function i(e){return!(!e||!e[p])}function s(e){return!(!e||!e[f])}function u(e){return!(!e||!e[h])}function c(e){return s(e)||u(e)}function l(e){return!(!e||!e[d])}t(r,n),t(o,n),t(a,n),n.isIterable=i,n.isKeyed=s,n.isIndexed=u,n.isAssociative=c,n.isOrdered=l,n.Keyed=r,n.Indexed=o,n.Set=a;var p="@@__IMMUTABLE_ITERABLE__@@",f="@@__IMMUTABLE_KEYED__@@",h="@@__IMMUTABLE_INDEXED__@@",d="@@__IMMUTABLE_ORDERED__@@",m="delete",v=5,g=1<<v,y=g-1,b={},_={value:!1},w={value:!1};function x(e){return e.value=!1,e}function E(e){e&&(e.value=!0)}function S(){}function C(e,t){t=t||0;for(var n=Math.max(0,e.length-t),r=new Array(n),o=0;o<n;o++)r[o]=e[o+t];return r}function A(e){return void 0===e.size&&(e.size=e.__iterate(O)),e.size}function k(e,t){if("number"!=typeof t){var n=t>>>0;if(""+n!==t||4294967295===n)return NaN;t=n}return t<0?A(e)+t:t}function O(){return!0}function j(e,t,n){return(0===e||void 0!==n&&e<=-n)&&(void 0===t||void 0!==n&&t>=n)}function T(e,t){return N(e,t,0)}function I(e,t){return N(e,t,t)}function N(e,t,n){return void 0===e?n:e<0?Math.max(0,t+e):void 0===t?e:Math.min(t,e)}var P=0,M=1,R=2,D="function"==typeof Symbol&&Symbol.iterator,L="@@iterator",B=D||L;function F(e){this.next=e}function U(e,t,n,r){var o=0===e?t:1===e?n:[t,n];return r?r.value=o:r={value:o,done:!1},r}function q(){return{value:void 0,done:!0}}function z(e){return!!H(e)}function V(e){return e&&"function"==typeof e.next}function W(e){var t=H(e);return t&&t.call(e)}function H(e){var t=e&&(D&&e[D]||e[L]);if("function"==typeof t)return t}function $(e){return e&&"number"==typeof e.length}function J(e){return null==e?ie():i(e)?e.toSeq():ce(e)}function K(e){return null==e?ie().toKeyedSeq():i(e)?s(e)?e.toSeq():e.fromEntrySeq():se(e)}function Y(e){return null==e?ie():i(e)?s(e)?e.entrySeq():e.toIndexedSeq():ue(e)}function G(e){return(null==e?ie():i(e)?s(e)?e.entrySeq():e:ue(e)).toSetSeq()}F.prototype.toString=function(){return"[Iterator]"},F.KEYS=P,F.VALUES=M,F.ENTRIES=R,F.prototype.inspect=F.prototype.toSource=function(){return this.toString()},F.prototype[B]=function(){return this},t(J,n),J.of=function(){return J(arguments)},J.prototype.toSeq=function(){return this},J.prototype.toString=function(){return this.__toString("Seq {","}")},J.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},J.prototype.__iterate=function(e,t){return pe(this,e,t,!0)},J.prototype.__iterator=function(e,t){return fe(this,e,t,!0)},t(K,J),K.prototype.toKeyedSeq=function(){return this},t(Y,J),Y.of=function(){return Y(arguments)},Y.prototype.toIndexedSeq=function(){return this},Y.prototype.toString=function(){return this.__toString("Seq [","]")},Y.prototype.__iterate=function(e,t){return pe(this,e,t,!1)},Y.prototype.__iterator=function(e,t){return fe(this,e,t,!1)},t(G,J),G.of=function(){return G(arguments)},G.prototype.toSetSeq=function(){return this},J.isSeq=ae,J.Keyed=K,J.Set=G,J.Indexed=Y;var Z,X,Q,ee="@@__IMMUTABLE_SEQ__@@";function te(e){this._array=e,this.size=e.length}function ne(e){var t=Object.keys(e);this._object=e,this._keys=t,this.size=t.length}function re(e){this._iterable=e,this.size=e.length||e.size}function oe(e){this._iterator=e,this._iteratorCache=[]}function ae(e){return!(!e||!e[ee])}function ie(){return Z||(Z=new te([]))}function se(e){var t=Array.isArray(Line truncated
|
||||
//# sourceMappingURL=swagger-ui-bundle.js.map
|
||||
@@ -1,3 +0,0 @@
|
||||
/*! For license information please see swagger-ui-standalone-preset.js.LICENSE.txt */
|
||||
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(function(){try{return require("esprima")}catch(t){}}()):"function"==typeof define&&define.amd?define(["esprima"],e):"object"==typeof exports?exports.SwaggerUIStandalonePreset=e(function(){try{return require("esprima")}catch(t){}}()):t.SwaggerUIStandalonePreset=e(t.esprima)}(this,(function(t){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/dist",n(n.s=241)}([function(t,e,n){t.exports=function(){"use strict";var t=Array.prototype.slice;function e(t,e){e&&(t.prototype=Object.create(e.prototype)),t.prototype.constructor=t}function n(t){return u(t)?t:J(t)}function r(t){return s(t)?t:Z(t)}function i(t){return a(t)?t:V(t)}function o(t){return u(t)&&!c(t)?t:X(t)}function u(t){return!(!t||!t[l])}function s(t){return!(!t||!t[p])}function a(t){return!(!t||!t[h])}function c(t){return s(t)||a(t)}function f(t){return!(!t||!t[d])}e(r,n),e(i,n),e(o,n),n.isIterable=u,n.isKeyed=s,n.isIndexed=a,n.isAssociative=c,n.isOrdered=f,n.Keyed=r,n.Indexed=i,n.Set=o;var l="@@__IMMUTABLE_ITERABLE__@@",p="@@__IMMUTABLE_KEYED__@@",h="@@__IMMUTABLE_INDEXED__@@",d="@@__IMMUTABLE_ORDERED__@@",y="delete",v=5,g=1<<v,w=g-1,M={},m={value:!1},_={value:!1};function L(t){return t.value=!1,t}function x(t){t&&(t.value=!0)}function b(){}function j(t,e){e=e||0;for(var n=Math.max(0,t.length-e),r=new Array(n),i=0;i<n;i++)r[i]=t[i+e];return r}function N(t){return void 0===t.size&&(t.size=t.__iterate(D)),t.size}function S(t,e){if("number"!=typeof e){var n=e>>>0;if(""+n!==e||4294967295===n)return NaN;e=n}return e<0?N(t)+e:e}function D(){return!0}function I(t,e,n){return(0===t||void 0!==n&&t<=-n)&&(void 0===e||void 0!==n&&e>=n)}function A(t,e){return C(t,e,0)}function E(t,e){return C(t,e,e)}function C(t,e,n){return void 0===t?n:t<0?Math.max(0,e+t):void 0===e?t:Math.min(e,t)}var O=0,T=1,z=2,k="function"==typeof Symbol&&Symbol.iterator,U="@@iterator",Y=k||U;function P(t){this.next=t}function R(t,e,n,r){var i=0===t?e:1===t?n:[e,n];return r?r.value=i:r={value:i,done:!1},r}function Q(){return{value:void 0,done:!0}}function F(t){return!!W(t)}function B(t){return t&&"function"==typeof t.next}function G(t){var e=W(t);return e&&e.call(t)}function W(t){var e=t&&(k&&t[k]||t[U]);if("function"==typeof e)return e}function q(t){return t&&"number"==typeof t.length}function J(t){return null==t?ut():u(t)?t.toSeq():ct(t)}function Z(t){return null==t?ut().toKeyedSeq():u(t)?s(t)?t.toSeq():t.fromEntrySeq():st(t)}function V(t){return null==t?ut():u(t)?s(t)?t.entrySeq():t.toIndexedSeq():at(t)}function X(t){return(null==t?ut():u(t)?s(t)?t.entrySeq():t:at(t)).toSetSeq()}P.prototype.toString=function(){return"[Iterator]"},P.KEYS=O,P.VALUES=T,P.ENTRIES=z,P.prototype.inspect=P.prototype.toSource=function(){return this.toString()},P.prototype[Y]=function(){return this},e(J,n),J.of=function(){return J(arguments)},J.prototype.toSeq=function(){return this},J.prototype.toString=function(){return this.__toString("Seq {","}")},J.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},J.prototype.__iterate=function(t,e){return lt(this,t,e,!0)},J.prototype.__iterator=function(t,e){return pt(this,t,e,!0)},e(Z,J),Z.prototype.toKeyedSeq=function(){return this},e(V,J),V.of=function(){return V(arguments)},V.prototype.toIndexedSeq=function(){return this},V.prototype.toString=function(){return this.__toString("Seq [","]")},V.prototype.__iterate=function(t,e){return lt(this,t,e,!1)},V.prototype.__iterator=function(t,e){return pt(this,t,e,!1)},e(X,J),X.of=function(){return X(arguments)},X.prototype.toSetSeq=function(){return this},J.isSeq=ot,J.Keyed=Z,J.Set=X,J.Indexed=V;var H,K,$,tt="@@__IMMUTABLE_SEQ__@@";function et(t){this._array=t,this.size=t.length}function nt(t){var e=Object.keys(t);this._object=t,this._keys=e,this.size=e.length}function rt(t){this._iterable=t,this.size=t.length||t.size}function it(t){this._iterator=t,this._iteratorCache=[]}function ot(t){return!(!t||!t[tt])}function ut(){return H||(H=new et([]))}function st(t){var e=Array.isArray(t)?new et(t).fromEntrySeq()Line truncated
|
||||
//# sourceMappingURL=swagger-ui-standalone-preset.js.map
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,58 +0,0 @@
|
||||
<!-- HTML for static distribution bundle build -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Swagger UI</title>
|
||||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
|
||||
<style>
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="./swagger-ui-bundle.js" charset="UTF-8"> </script>
|
||||
<script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
// Begin Swagger UI call region
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "/docs/openapi.json",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
// End Swagger UI call region
|
||||
|
||||
window.ui = ui
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
import { swaggerUI } from '@hono/swagger-ui'
|
||||
|
||||
const routes = {
|
||||
'/api/v1/email': {
|
||||
post: {
|
||||
summary: 'Send an email',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['to', 'templateName', 'language', 'data'],
|
||||
properties: {
|
||||
to: {
|
||||
type: 'string',
|
||||
format: 'email'
|
||||
},
|
||||
templateName: {
|
||||
type: 'string'
|
||||
},
|
||||
language: {
|
||||
type: 'string',
|
||||
enum: ['en', 'de']
|
||||
},
|
||||
data: {
|
||||
type: 'object'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'Email queued successfully',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
success: {
|
||||
type: 'boolean'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'400': {
|
||||
description: 'Bad request or email queueing failed',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
success: {
|
||||
type: 'boolean'
|
||||
},
|
||||
error: {
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
get: {
|
||||
path: '/status',
|
||||
summary: 'Get email queue status',
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'Queue status retrieved successfully',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
waiting: {
|
||||
type: 'number'
|
||||
},
|
||||
active: {
|
||||
type: 'number'
|
||||
},
|
||||
completed: {
|
||||
type: 'number'
|
||||
},
|
||||
failed: {
|
||||
type: 'number'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const apiDoc = {
|
||||
openapi: '3.0.0',
|
||||
info: {
|
||||
title: process.env.npm_package_name,
|
||||
version: process.env.npm_package_version,
|
||||
description: 'API for sending templated emails in multiple languages'
|
||||
},
|
||||
paths: routes
|
||||
}
|
||||
|
||||
export const createSwaggerUI = () => {
|
||||
return swaggerUI({
|
||||
url: '/api/docs',
|
||||
spec: apiDoc
|
||||
})
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,46 @@
|
||||
import { Language } from '../types'
|
||||
import { readFileSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import { compile } from 'handlebars'
|
||||
|
||||
interface TemplateCache {
|
||||
[key: string]: {
|
||||
html: HandlebarsTemplateDelegate
|
||||
subject: HandlebarsTemplateDelegate,
|
||||
text: HandlebarsTemplateDelegate
|
||||
}
|
||||
}
|
||||
|
||||
const templateCache: TemplateCache = {}
|
||||
|
||||
function loadTemplate(name: string, language: Language) {
|
||||
const cacheKey = `${name}:${language}`
|
||||
|
||||
if (!templateCache[cacheKey]) {
|
||||
const htmlPath = join(process.cwd(), 'src', 'templates', name, `${language}.html`)
|
||||
const textPath = join(process.cwd(), 'src', 'templates', name, `${language}.txt`)
|
||||
const subjectPath = join(process.cwd(), 'src', 'templates', name, `${language}.subject.txt`)
|
||||
|
||||
const htmlTemplate = readFileSync(htmlPath, 'utf-8')
|
||||
const textTemplate = readFileSync(textPath, 'utf-8')
|
||||
const subjectTemplate = readFileSync(subjectPath, 'utf-8')
|
||||
|
||||
templateCache[cacheKey] = {
|
||||
html: compile(htmlTemplate),
|
||||
subject: compile(subjectTemplate),
|
||||
text: compile(textTemplate)
|
||||
}
|
||||
}
|
||||
|
||||
return templateCache[cacheKey]
|
||||
}
|
||||
|
||||
export function getEmailTemplate(name: string, language: Language) {
|
||||
const template = loadTemplate(name, language)
|
||||
|
||||
return {
|
||||
subject: (data: any) => template.subject(data),
|
||||
html: (data: any) => template.html(data),
|
||||
text: (data: any) => template.text(data)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html dir="ltr" lang="en">
|
||||
<head>
|
||||
<meta content="width=device-width" name="viewport" />
|
||||
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
|
||||
<meta name="x-apple-disable-message-reformatting" />
|
||||
<meta content="IE=edge" http-equiv="X-UA-Compatible" />
|
||||
<meta name="x-apple-disable-message-reformatting" />
|
||||
<meta
|
||||
content="telephone=no,address=no,email=no,date=no,url=no"
|
||||
name="format-detection"
|
||||
/>
|
||||
<meta content="light" name="color-scheme" />
|
||||
<meta content="light" name="supported-color-schemes" />
|
||||
<!--$-->
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
mso-font-alt: "sans-serif";
|
||||
src: url(https://rsms.me/inter/font-files/Inter-Regular.woff2?v=3.19)
|
||||
format("woff2");
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: "Inter", sans-serif;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
blockquote,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
img,
|
||||
li,
|
||||
ol,
|
||||
p,
|
||||
ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
@media only screen and (max-width: 425px) {
|
||||
.tab-row-full {
|
||||
width: 100% !important;
|
||||
}
|
||||
.tab-col-full {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
.tab-pad {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0">
|
||||
<div
|
||||
style="
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
line-height: 1px;
|
||||
opacity: 0;
|
||||
max-height: 0;
|
||||
max-width: 0;
|
||||
"
|
||||
id="__react-email-preview"
|
||||
>
|
||||
Anfrage zum Zurücksetzen des Passworts
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<table
|
||||
align="center"
|
||||
width="100%"
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="presentation"
|
||||
style="
|
||||
max-width: 600px;
|
||||
min-width: 300px;
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 0.5rem;
|
||||
"
|
||||
>
|
||||
<tbody>
|
||||
<tr style="width: 100%">
|
||||
<td>
|
||||
<table
|
||||
align="center"
|
||||
width="100%"
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="presentation"
|
||||
style="margin-top: 0px; margin-bottom: 32px"
|
||||
>
|
||||
<tbody style="width: 100%">
|
||||
<tr style="width: 100%">
|
||||
<td align="left" data-id="__react-email-column">
|
||||
<img
|
||||
title="Logo"
|
||||
alt="Logo"
|
||||
src="https://run.lauf-fuer-kaya.de/lfk-logo.png"
|
||||
style="
|
||||
display: block;
|
||||
outline: none;
|
||||
border: none;
|
||||
text-decoration: none;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h2
|
||||
style="
|
||||
text-align: left;
|
||||
color: #111827;
|
||||
margin-bottom: 12px;
|
||||
margin-top: 0;
|
||||
font-size: 30px;
|
||||
line-height: 36px;
|
||||
font-weight: 700;
|
||||
"
|
||||
>
|
||||
<strong>Anfrage zum Zurücksetzen des Passworts</strong>
|
||||
</h2>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
<strong>Hallo 👋</strong>
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
Wir haben eine Anfrage zum Zurücksetzen deines Passworts
|
||||
erhalten.<br />Verwende den folgenden Link, um ein neues Passwort
|
||||
zu erstellen:
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
<a
|
||||
href="{{reset_link}}"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>{{reset_link}}</a
|
||||
>
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
Falls du diese Anfrage nicht gestellt hast, ignoriere bitte diese
|
||||
E-Mail.
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
Sportliche Grüße 🏃♂️<br />Dein Team Lauf für Kaya!
|
||||
</p>
|
||||
<hr
|
||||
style="
|
||||
width: 100%;
|
||||
border: none;
|
||||
border-top: 1px solid #eaeaea;
|
||||
margin-top: 32px;
|
||||
margin-bottom: 32px;
|
||||
"
|
||||
/>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
Lauf für Kaya! <strong>Powered by </strong
|
||||
><u
|
||||
><strong
|
||||
><a
|
||||
href="https://odit.services?ref=lfkmail"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>ODIT.Services</a
|
||||
></strong
|
||||
></u
|
||||
>.<br /><u
|
||||
><strong
|
||||
><a
|
||||
href="https://lauf-fuer-kaya.de/impressum/"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>Impressum</a
|
||||
></strong
|
||||
></u
|
||||
>
|
||||
-
|
||||
<u
|
||||
><strong
|
||||
><a
|
||||
href="https://lauf-fuer-kaya.de/datenschutz/"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>Datenschutzerklärung</a
|
||||
></strong
|
||||
></u
|
||||
>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!--/$-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Lauf für Kaya! - Passwort Reset
|
||||
@@ -0,0 +1,17 @@
|
||||
Hallo 👋
|
||||
|
||||
Wir haben eine Anfrage zum Zurücksetzen deines Passworts erhalten.
|
||||
Verwende den folgenden Link, um ein neues Passwort zu erstellen:
|
||||
{{reset_link}}
|
||||
|
||||
Falls du diese Anfrage nicht gestellt hast, ignoriere bitte diese E-Mail.
|
||||
|
||||
Sportliche Grüße 🏃♂️
|
||||
Dein Team Lauf für Kaya!
|
||||
|
||||
-
|
||||
|
||||
Lauf für Kaya!
|
||||
Powered by ODIT.Services (https://odit.services)
|
||||
Impressum: https://lauf-fuer-kaya.de/impressum/
|
||||
Datenschutzerklärung: https://lauf-fuer-kaya.de/datenschutz/
|
||||
@@ -0,0 +1,297 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html dir="ltr" lang="en">
|
||||
<head>
|
||||
<meta content="width=device-width" name="viewport" />
|
||||
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
|
||||
<meta name="x-apple-disable-message-reformatting" />
|
||||
<meta content="IE=edge" http-equiv="X-UA-Compatible" />
|
||||
<meta name="x-apple-disable-message-reformatting" />
|
||||
<meta
|
||||
content="telephone=no,address=no,email=no,date=no,url=no"
|
||||
name="format-detection"
|
||||
/>
|
||||
<meta content="light" name="color-scheme" />
|
||||
<meta content="light" name="supported-color-schemes" />
|
||||
<!--$-->
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
mso-font-alt: "sans-serif";
|
||||
src: url(https://rsms.me/inter/font-files/Inter-Regular.woff2?v=3.19)
|
||||
format("woff2");
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: "Inter", sans-serif;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
blockquote,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
img,
|
||||
li,
|
||||
ol,
|
||||
p,
|
||||
ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
@media only screen and (max-width: 425px) {
|
||||
.tab-row-full {
|
||||
width: 100% !important;
|
||||
}
|
||||
.tab-col-full {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
.tab-pad {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0">
|
||||
<div
|
||||
style="
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
line-height: 1px;
|
||||
opacity: 0;
|
||||
max-height: 0;
|
||||
max-width: 0;
|
||||
"
|
||||
id="__react-email-preview"
|
||||
>
|
||||
Password-Reset
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<table
|
||||
align="center"
|
||||
width="100%"
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="presentation"
|
||||
style="
|
||||
max-width: 600px;
|
||||
min-width: 300px;
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 0.5rem;
|
||||
"
|
||||
>
|
||||
<tbody>
|
||||
<tr style="width: 100%">
|
||||
<td>
|
||||
<table
|
||||
align="center"
|
||||
width="100%"
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="presentation"
|
||||
style="margin-top: 0px; margin-bottom: 32px"
|
||||
>
|
||||
<tbody style="width: 100%">
|
||||
<tr style="width: 100%">
|
||||
<td align="left" data-id="__react-email-column">
|
||||
<img
|
||||
title="Logo"
|
||||
alt="Logo"
|
||||
src="https://run.lauf-fuer-kaya.de/lfk-logo.png"
|
||||
style="
|
||||
display: block;
|
||||
outline: none;
|
||||
border: none;
|
||||
text-decoration: none;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h2
|
||||
style="
|
||||
text-align: left;
|
||||
color: #111827;
|
||||
margin-bottom: 12px;
|
||||
margin-top: 0;
|
||||
font-size: 30px;
|
||||
line-height: 36px;
|
||||
font-weight: 700;
|
||||
"
|
||||
>
|
||||
<strong>Password-Reset</strong>
|
||||
</h2>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
<strong>Hi 👋</strong>
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
We received a request to reset your password.<br />Use the
|
||||
following link to create a new password:
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
<a
|
||||
href="{{reset_link}}"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>{{reset_link}}</a
|
||||
>
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
If you didn't request this password reset, please ignore this
|
||||
email.
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
Sporty Greetings 🏃♂️<br />Your Team Lauf für Kaya!
|
||||
</p>
|
||||
<hr
|
||||
style="
|
||||
width: 100%;
|
||||
border: none;
|
||||
border-top: 1px solid #eaeaea;
|
||||
margin-top: 32px;
|
||||
margin-bottom: 32px;
|
||||
"
|
||||
/>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
Lauf für Kaya! <strong>Powered by </strong
|
||||
><u
|
||||
><strong
|
||||
><a
|
||||
href="https://odit.services?ref=lfkmail"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>ODIT.Services</a
|
||||
></strong
|
||||
></u
|
||||
>.<br /><u
|
||||
><strong
|
||||
><a
|
||||
href="https://lauf-fuer-kaya.de/impressum/"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>Imprint</a
|
||||
></strong
|
||||
></u
|
||||
>
|
||||
-
|
||||
<u
|
||||
><strong
|
||||
><a
|
||||
href="https://lauf-fuer-kaya.de/datenschutz/"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>Privacy Policy</a
|
||||
></strong
|
||||
></u
|
||||
>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!--/$-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Lauf für Kaya! - Password Reset
|
||||
@@ -0,0 +1,17 @@
|
||||
Hello 👋
|
||||
|
||||
We received a request to reset your password.
|
||||
Use the following link to create a new password:
|
||||
{{reset_link}}
|
||||
|
||||
If you didn't request this password reset, please ignore this email.
|
||||
|
||||
Sporty Greetings 🏃♂️
|
||||
Your Team Lauf für Kaya!
|
||||
|
||||
-
|
||||
|
||||
Lauf für Kaya!
|
||||
Powered by ODIT.Services (https://odit.services)
|
||||
Imprint: https://lauf-fuer-kaya.de/impressum/
|
||||
Privacy Policy: https://lauf-fuer-kaya.de/datenschutz/
|
||||
@@ -1,384 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="de" xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:v="urn:schemas-microsoft-com:vml">
|
||||
<head>
|
||||
<title>{{__ "lfk-password-reset"}}</title> <!-- The title tag shows in email notifications, like Android 4.4. -->
|
||||
<meta charset="utf-8"> <!-- utf-8 works for most cases -->
|
||||
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width"> <!-- Forcing initial-scale shouldn't be necessary -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- Use the latest (edge) version of IE rendering engine -->
|
||||
<meta name="x-apple-disable-message-reformatting"> <!-- Disable auto-scale in iOS 10 Mail entirely -->
|
||||
<meta name="format-detection" content="telephone=no,address=no,email=no,date=no,url=no"> <!-- Tell iOS not to automatically link certain text strings. -->
|
||||
|
||||
<!-- CSS Reset : BEGIN -->
|
||||
<style>
|
||||
/* What it does: Remove spaces around the email design added by some email clients. */
|
||||
/* Beware: It can remove the padding / margin and add a background color to the compose a reply window. */
|
||||
html,
|
||||
body {
|
||||
margin: 0 auto !important;
|
||||
padding: 0 !important;
|
||||
height: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* What it does: Stops email clients resizing small text. */
|
||||
* {
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
/* What it does: Centers email on Android 4.4 */
|
||||
div[style*="margin: 16px 0"] {
|
||||
margin:0 !important;
|
||||
}
|
||||
|
||||
/* What it does: Stops Outlook from adding extra spacing to tables. */
|
||||
table,
|
||||
td {
|
||||
mso-table-lspace: 0pt !important;
|
||||
mso-table-rspace: 0pt !important;
|
||||
}
|
||||
|
||||
/* What it does: Fixes webkit padding issue. */
|
||||
table {
|
||||
border: 0;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse
|
||||
}
|
||||
|
||||
/* What it does: Forces Samsung Android mail clients to use the entire viewport. */
|
||||
#MessageViewBody,
|
||||
#MessageWebViewDiv{
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* What it does: Uses a better rendering method when resizing images in IE. */
|
||||
img {
|
||||
-ms-interpolation-mode:bicubic;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Windows 10 Mail from underlining links despite inline CSS. Styles for underlined links should be inline. */
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* What it does: A work-around for email clients automatically linking certain text strings. */
|
||||
/* iOS */
|
||||
a[x-apple-data-detectors],
|
||||
.unstyle-auto-detected-links a,
|
||||
.aBn {
|
||||
border-bottom: 0 !important;
|
||||
cursor: default !important;
|
||||
color: inherit !important;
|
||||
text-decoration: none !important;
|
||||
font-size: inherit !important;
|
||||
font-family: inherit !important;
|
||||
font-weight: inherit !important;
|
||||
line-height: inherit !important;
|
||||
}
|
||||
u + #body a, /* Gmail */
|
||||
#MessageViewBody a /* Samsung Mail */
|
||||
{
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Gmail from changing the text color in conversation threads. */
|
||||
.im {
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Gmail from displaying an download button on large, non-linked images. */
|
||||
.a6S {
|
||||
display: none !important;
|
||||
opacity: 0.01 !important;
|
||||
}
|
||||
/* If the above doesn't work, add a .g-img class to any image in question. */
|
||||
img.g-img + div {
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
/* What it does: Removes right gutter in Gmail iOS app: https://github.com/TedGoas/Cerberus/issues/89 */
|
||||
/* Create one of these media queries for each additional viewport size you'd like to fix */
|
||||
|
||||
/* iPhone 4, 4S, 5, 5S, 5C, and 5SE */
|
||||
@media only screen and (min-device-width: 320px) and (max-device-width: 374px) {
|
||||
u ~ div .email-container {
|
||||
min-width: 320px !important;
|
||||
}
|
||||
}
|
||||
/* iPhone 6, 6S, 7, 8, and X */
|
||||
@media only screen and (min-device-width: 375px) and (max-device-width: 413px) {
|
||||
u ~ div .email-container {
|
||||
min-width: 375px !important;
|
||||
}
|
||||
}
|
||||
/* iPhone 6+, 7+, and 8+ */
|
||||
@media only screen and (min-device-width: 414px) {
|
||||
u ~ div .email-container {
|
||||
min-width: 414px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<!-- What it does: Helps DPI scaling in Outlook 2007-2013 -->
|
||||
<!--[if gte mso 9]>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:AllowPNG/>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
<![endif]-->
|
||||
|
||||
<!-- CSS Reset : END -->
|
||||
|
||||
<!-- Progressive Enhancements : BEGIN -->
|
||||
<style>
|
||||
/* What it does: Hover styles for buttons and tags */
|
||||
.s-btn__primary:hover {
|
||||
background: #0077CC !important;
|
||||
border-color: #0077CC !important;
|
||||
}
|
||||
.s-btn__white:hover {
|
||||
background: #EFF0F1 !important;
|
||||
border-color: #EFF0F1 !important;
|
||||
}
|
||||
.s-btn__outlined:hover {
|
||||
background: rgba(0,119,204,.05) !important;
|
||||
color: #005999 !important;
|
||||
}
|
||||
.s-tag:hover,
|
||||
.post-tag:hover {
|
||||
border-color: #cee0ed !important;
|
||||
background: #cee0ed !important;
|
||||
}
|
||||
|
||||
/* What it does: Styles markdown links that we can't write inline CSS for. */
|
||||
.has-markdown a,
|
||||
.has-markdown a:visited {
|
||||
color: #0077CC !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/* What it does: Styles markdown code blocks that we can't write inline CSS for. */
|
||||
code {
|
||||
padding: 1px 5px;
|
||||
background-color: #EFF0F1;
|
||||
color: #242729;
|
||||
font-size: 13px;
|
||||
line-height: inherit;
|
||||
font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, sans-serif;
|
||||
}
|
||||
pre {
|
||||
margin: 0 0 15px;
|
||||
line-height: 17px;
|
||||
background-color: #EFF0F1;
|
||||
padding: 4px 8px;
|
||||
border-radius: 3px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
pre code {
|
||||
margin: 0 0 15px;
|
||||
padding: 0;
|
||||
line-height: 17px;
|
||||
background-color: none;
|
||||
}
|
||||
|
||||
/* What it does: Styles markdown blockquotes that we can't write inline CSS for. */
|
||||
blockquote {
|
||||
margin: 0 0 15px;
|
||||
padding: 4px 10px;
|
||||
background-color: #FFF8DC;
|
||||
border-left: 2px solid #ffeb8e;
|
||||
}
|
||||
blockquote p {
|
||||
padding: 4px 0;
|
||||
margin: 0;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
/* What it does: Rounds corners in email clients that support it */
|
||||
.bar {
|
||||
border-radius: 5px;
|
||||
}
|
||||
.btr {
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
}
|
||||
.bbr {
|
||||
border-bottom-left-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 680px) {
|
||||
/* What it does: Forces table cells into full-width rows. */
|
||||
.stack-column,
|
||||
.stack-column-center {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
direction: ltr !important;
|
||||
}
|
||||
/* And center justify these ones. */
|
||||
.stack-column-center {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
/* Hides things in small viewports. */
|
||||
.hide-on-mobile {
|
||||
display: none !important;
|
||||
max-height: 0 !important;
|
||||
overflow: hidden !important;
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
/* What it does: Utility classes to reduce spacing for smaller viewports. */
|
||||
.sm-p-none {padding: 0 !important;}
|
||||
.sm-pt-none {padding-top: 0 !important;}
|
||||
.sm-pb-none {padding-bottom: 0 !important;}
|
||||
.sm-pr-none {padding-right: 0 !important;}
|
||||
.sm-pl-none {padding-left: 0 !important;}
|
||||
.sm-px-none {padding-left: 0 !important; padding-right: 0 !important;}
|
||||
.sm-py-none {padding-top: 0 !important; padding-bottom: 0 !important;}
|
||||
|
||||
.sm-p {padding: 20px !important;}
|
||||
.sm-pt {padding-top: 20px !important;}
|
||||
.sm-pb {padding-bottom: 20px !important;}
|
||||
.sm-pr {padding-right: 20px !important;}
|
||||
.sm-pl {padding-left: 20px !important;}
|
||||
.sm-px {padding-left: 20px !important; padding-right: 20px !important;}
|
||||
.sm-py {padding-top: 20px !important; padding-bottom: 20px !important;}
|
||||
.sm-mb {margin-bottom: 20px !important;}
|
||||
|
||||
/* What it does: Utility classes to kill border radius for smaller viewports. Used mainly on the email's main container(s). */
|
||||
.bar,
|
||||
.btr,
|
||||
.bbr {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<!-- Progressive Enhancements : END -->
|
||||
</head>
|
||||
|
||||
<!--
|
||||
The email background color is defined in three places, just below. If you change one, remember to change the others.
|
||||
1. body tag: for most email clients
|
||||
2. center tag: for Gmail and Inbox mobile apps and web versions of Gmail, GSuite, Inbox, Yahoo, AOL, Libero, Comcast, freenet, Mail.ru, Orange.fr
|
||||
3. mso conditional: For Windows 10 Mail
|
||||
-->
|
||||
<body width="100%" style="margin: 0; padding: 0 !important; background: #f3f3f5; mso-line-height-rule: exactly;">
|
||||
<center style="width: 100%; background: #f3f3f5;">
|
||||
<!--[if mso | IE]>
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="background-color: #f3f3f5;">
|
||||
<tr>
|
||||
<td>
|
||||
<![endif]-->
|
||||
|
||||
<!-- Visually Hidden Preview Text : BEGIN -->
|
||||
<div style="display: none; font-size: 1px; line-height: 1px; max-height: 0px; max-width: 0px; opacity: 0; overflow: hidden; mso-hide: all; font-family: sans-serif;">
|
||||
{{__ "lfk-password-reset"}}
|
||||
</div>
|
||||
<!-- Visually Hidden Preview Text : END -->
|
||||
|
||||
<div class="email-container" style="max-width: 680px; margin: 0 auto;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="680" align="center">
|
||||
<tr>
|
||||
<td>
|
||||
<![endif]-->
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="max-width: 680px; width:100%">
|
||||
<tr>
|
||||
<td style="padding: 30px; background-color: #ffffff;" class="sm-p bar">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
|
||||
<tr>
|
||||
<td style="padding-bottom: 15px; font-family: arial, sans-serif; font-size: 15px; line-height: 21px; color: #3C3F44; text-align: left;">
|
||||
<h1 style="font-weight: bold; font-size: 27px; line-height: 27px; color: #0C0D0E; margin: 0 0 15px 0;">LfK!</h1>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-bottom: 15px; font-family: arial, sans-serif; font-size: 15px; line-height: 21px; color: #3C3F44; text-align: left;">
|
||||
<h1 style="font-weight: bold; font-size: 21px; line-height: 21px; color: #0C0D0E; margin: 0 0 15px 0;">{{__ "password-reset"}}</h1>
|
||||
<p style="margin: 0 0 15px;" class="has-markdown">{{__ "a-password-reset-for-your-account-got-requested"}}<br><b>{{__ "if-you-didnt-request-the-reset-please-ignore-this-mail"}}</b><br>{{__ "your-password-wont-be-changed-until-you-click-the-reset-link-below-and-set-a-new-one"}}</p>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Button Row : BEGIN -->
|
||||
<tr>
|
||||
<td>
|
||||
<!-- Button : BEGIN -->
|
||||
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation">
|
||||
<tr>
|
||||
<td class="s-btn s-btn__primary" style="border-radius: 4px; background: #0095ff;">
|
||||
<a class="s-btn s-btn__primary" href="{{reset_link}}" target="_parent" style="background: #0095FF; border: 1px solid #0077cc; box-shadow: inset 0 1px 0 0 rgba(102,191,255,.75); font-family: arial, sans-serif; font-size: 17px; line-height: 17px; color: #ffffff; text-align: center; text-decoration: none; padding: 13px 17px; display: block; border-radius: 4px; white-space: nowrap;">{{__ "reset-password"}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- Button : END -->
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Button Row : END -->
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-----------------------------
|
||||
|
||||
EMAIL BODY : END
|
||||
|
||||
------------------------------>
|
||||
|
||||
<!-- Footer : BEGIN -->
|
||||
<tr>
|
||||
<td style="padding: 30px;" class="sm-p">
|
||||
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation" width="100%">
|
||||
<!-- Subscription Info : BEGIN -->
|
||||
<tr>
|
||||
<td style="padding-bottom: 10px; font-size: 12px; line-height: 15px; font-family: arial, sans-serif; color: #9199A1; text-align: left;">
|
||||
Copyright © {{copyright_owner}}. {{__ "all-rights-reserved"}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-size: 12px; line-height: 15px; font-family: arial, sans-serif; color: #9199A1; text-align: left;">
|
||||
<a href="{{link_imprint}}"
|
||||
style="color: #9199A1; text-decoration: underline;">{{__ "imprint"}}</a>
|
||||
<a href="{{link_privacy}}" style="color: #9199A1; text-decoration: underline;">{{__ "privacy"}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Subscription Info : BEGIN -->
|
||||
<!-- HR line : BEGIN -->
|
||||
<tr>
|
||||
<td style="padding: 30px 0;" width="100%" class="sm-py">
|
||||
<table aria-hidden="true" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%">
|
||||
<tr>
|
||||
<td height="1" width="100%" style="font-size: 0; line-height: 0; border-top: 1px solid #D6D8DB;"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- HR line : END -->
|
||||
<tr>
|
||||
<td style="padding-bottom: 5px; font-size: 12px; line-height: 15px; font-family: arial, sans-serif; color: #9199A1; text-align: left;">{{__ "this-mail-was-sent-to-you-because-someone-request-a-password-reset-for-a-account-linked-to-the-mail-address"}}</td>
|
||||
</tr>
|
||||
<!-- Sender Info : END -->
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Footer : END -->
|
||||
</table>
|
||||
</div>
|
||||
<!--[if mso | IE]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,12 +0,0 @@
|
||||
{{__ "lfk-password-reset"}}
|
||||
|
||||
{{__ "a-password-reset-for-your-account-got-requested"}}
|
||||
{{__ "if-you-didnt-request-the-reset-please-ignore-this-mail"}}
|
||||
{{__ "your-password-wont-be-changed-until-you-click-the-reset-link-below-and-set-a-new-one"}}
|
||||
|
||||
{{__ "reset-password"}}: {{reset_link}}
|
||||
|
||||
|
||||
Copyright © {{copyright_owner}}. {{__ "all-rights-reserved"}}.
|
||||
{{__ "imprint"}}: {{link_imprint}} | {{__ "privacy"}}: {{link_privacy}}
|
||||
{{__ "this-mail-was-sent-to-you-because-someone-request-a-password-reset-for-a-account-linked-to-the-mail-address"}}
|
||||
@@ -1,396 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="de" xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:v="urn:schemas-microsoft-com:vml">
|
||||
<head>
|
||||
<title>{{__ "your-event_name-profile"}}<title> <!-- The title tag shows in email notifications, like Android 4.4. -->
|
||||
<meta charset="utf-8"> <!-- utf-8 works for most cases -->
|
||||
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width"> <!-- Forcing initial-scale shouldn't be necessary -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- Use the latest (edge) version of IE rendering engine -->
|
||||
<meta name="x-apple-disable-message-reformatting"> <!-- Disable auto-scale in iOS 10 Mail entirely -->
|
||||
<meta name="format-detection" content="telephone=no,address=no,email=no,date=no,url=no"> <!-- Tell iOS not to automatically link certain text strings. -->
|
||||
|
||||
<!-- CSS Reset : BEGIN -->
|
||||
<style>
|
||||
/* What it does: Remove spaces around the email design added by some email clients. */
|
||||
/* Beware: It can remove the padding / margin and add a background color to the compose a reply window. */
|
||||
html,
|
||||
body {
|
||||
margin: 0 auto !important;
|
||||
padding: 0 !important;
|
||||
height: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* What it does: Stops email clients resizing small text. */
|
||||
* {
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
/* What it does: Centers email on Android 4.4 */
|
||||
div[style*="margin: 16px 0"] {
|
||||
margin:0 !important;
|
||||
}
|
||||
|
||||
/* What it does: Stops Outlook from adding extra spacing to tables. */
|
||||
table,
|
||||
td {
|
||||
mso-table-lspace: 0pt !important;
|
||||
mso-table-rspace: 0pt !important;
|
||||
}
|
||||
|
||||
/* What it does: Fixes webkit padding issue. */
|
||||
table {
|
||||
border: 0;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse
|
||||
}
|
||||
|
||||
/* What it does: Forces Samsung Android mail clients to use the entire viewport. */
|
||||
#MessageViewBody,
|
||||
#MessageWebViewDiv{
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* What it does: Uses a better rendering method when resizing images in IE. */
|
||||
img {
|
||||
-ms-interpolation-mode:bicubic;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Windows 10 Mail from underlining links despite inline CSS. Styles for underlined links should be inline. */
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* What it does: A work-around for email clients automatically linking certain text strings. */
|
||||
/* iOS */
|
||||
a[x-apple-data-detectors],
|
||||
.unstyle-auto-detected-links a,
|
||||
.aBn {
|
||||
border-bottom: 0 !important;
|
||||
cursor: default !important;
|
||||
color: inherit !important;
|
||||
text-decoration: none !important;
|
||||
font-size: inherit !important;
|
||||
font-family: inherit !important;
|
||||
font-weight: inherit !important;
|
||||
line-height: inherit !important;
|
||||
}
|
||||
u + #body a, /* Gmail */
|
||||
#MessageViewBody a /* Samsung Mail */
|
||||
{
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Gmail from changing the text color in conversation threads. */
|
||||
.im {
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Gmail from displaying an download button on large, non-linked images. */
|
||||
.a6S {
|
||||
display: none !important;
|
||||
opacity: 0.01 !important;
|
||||
}
|
||||
/* If the above doesn't work, add a .g-img class to any image in question. */
|
||||
img.g-img + div {
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
/* What it does: Removes right gutter in Gmail iOS app: https://github.com/TedGoas/Cerberus/issues/89 */
|
||||
/* Create one of these media queries for each additional viewport size you'd like to fix */
|
||||
|
||||
/* iPhone 4, 4S, 5, 5S, 5C, and 5SE */
|
||||
@media only screen and (min-device-width: 320px) and (max-device-width: 374px) {
|
||||
u ~ div .email-container {
|
||||
min-width: 320px !important;
|
||||
}
|
||||
}
|
||||
/* iPhone 6, 6S, 7, 8, and X */
|
||||
@media only screen and (min-device-width: 375px) and (max-device-width: 413px) {
|
||||
u ~ div .email-container {
|
||||
min-width: 375px !important;
|
||||
}
|
||||
}
|
||||
/* iPhone 6+, 7+, and 8+ */
|
||||
@media only screen and (min-device-width: 414px) {
|
||||
u ~ div .email-container {
|
||||
min-width: 414px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<!-- What it does: Helps DPI scaling in Outlook 2007-2013 -->
|
||||
<!--[if gte mso 9]>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:AllowPNG/>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
<![endif]-->
|
||||
|
||||
<!-- CSS Reset : END -->
|
||||
|
||||
<!-- Progressive Enhancements : BEGIN -->
|
||||
<style>
|
||||
/* What it does: Hover styles for buttons and tags */
|
||||
.s-btn__primary:hover {
|
||||
background: #0077CC !important;
|
||||
border-color: #0077CC !important;
|
||||
}
|
||||
.s-btn__white:hover {
|
||||
background: #EFF0F1 !important;
|
||||
border-color: #EFF0F1 !important;
|
||||
}
|
||||
.s-btn__outlined:hover {
|
||||
background: rgba(0,119,204,.05) !important;
|
||||
color: #005999 !important;
|
||||
}
|
||||
.s-tag:hover,
|
||||
.post-tag:hover {
|
||||
border-color: #cee0ed !important;
|
||||
background: #cee0ed !important;
|
||||
}
|
||||
|
||||
/* What it does: Styles markdown links that we can't write inline CSS for. */
|
||||
.has-markdown a,
|
||||
.has-markdown a:visited {
|
||||
color: #0077CC !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/* What it does: Styles markdown code blocks that we can't write inline CSS for. */
|
||||
code {
|
||||
padding: 1px 5px;
|
||||
background-color: #EFF0F1;
|
||||
color: #242729;
|
||||
font-size: 13px;
|
||||
line-height: inherit;
|
||||
font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, sans-serif;
|
||||
}
|
||||
pre {
|
||||
margin: 0 0 15px;
|
||||
line-height: 17px;
|
||||
background-color: #EFF0F1;
|
||||
padding: 4px 8px;
|
||||
border-radius: 3px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
pre code {
|
||||
margin: 0 0 15px;
|
||||
padding: 0;
|
||||
line-height: 17px;
|
||||
background-color: none;
|
||||
}
|
||||
|
||||
/* What it does: Styles markdown blockquotes that we can't write inline CSS for. */
|
||||
blockquote {
|
||||
margin: 0 0 15px;
|
||||
padding: 4px 10px;
|
||||
background-color: #FFF8DC;
|
||||
border-left: 2px solid #ffeb8e;
|
||||
}
|
||||
blockquote p {
|
||||
padding: 4px 0;
|
||||
margin: 0;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
/* What it does: Rounds corners in email clients that support it */
|
||||
.bar {
|
||||
border-radius: 5px;
|
||||
}
|
||||
.btr {
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
}
|
||||
.bbr {
|
||||
border-bottom-left-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 680px) {
|
||||
/* What it does: Forces table cells into full-width rows. */
|
||||
.stack-column,
|
||||
.stack-column-center {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
direction: ltr !important;
|
||||
}
|
||||
/* And center justify these ones. */
|
||||
.stack-column-center {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
/* Hides things in small viewports. */
|
||||
.hide-on-mobile {
|
||||
display: none !important;
|
||||
max-height: 0 !important;
|
||||
overflow: hidden !important;
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
/* What it does: Utility classes to reduce spacing for smaller viewports. */
|
||||
.sm-p-none {padding: 0 !important;}
|
||||
.sm-pt-none {padding-top: 0 !important;}
|
||||
.sm-pb-none {padding-bottom: 0 !important;}
|
||||
.sm-pr-none {padding-right: 0 !important;}
|
||||
.sm-pl-none {padding-left: 0 !important;}
|
||||
.sm-px-none {padding-left: 0 !important; padding-right: 0 !important;}
|
||||
.sm-py-none {padding-top: 0 !important; padding-bottom: 0 !important;}
|
||||
|
||||
.sm-p {padding: 20px !important;}
|
||||
.sm-pt {padding-top: 20px !important;}
|
||||
.sm-pb {padding-bottom: 20px !important;}
|
||||
.sm-pr {padding-right: 20px !important;}
|
||||
.sm-pl {padding-left: 20px !important;}
|
||||
.sm-px {padding-left: 20px !important; padding-right: 20px !important;}
|
||||
.sm-py {padding-top: 20px !important; padding-bottom: 20px !important;}
|
||||
.sm-mb {margin-bottom: 20px !important;}
|
||||
|
||||
/* What it does: Utility classes to kill border radius for smaller viewports. Used mainly on the email's main container(s). */
|
||||
.bar,
|
||||
.btr,
|
||||
.bbr {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<!-- Progressive Enhancements : END -->
|
||||
</head>
|
||||
|
||||
<!--
|
||||
The email background color is defined in three places, just below. If you change one, remember to change the others.
|
||||
1. body tag: for most email clients
|
||||
2. center tag: for Gmail and Inbox mobile apps and web versions of Gmail, GSuite, Inbox, Yahoo, AOL, Libero, Comcast, freenet, Mail.ru, Orange.fr
|
||||
3. mso conditional: For Windows 10 Mail
|
||||
-->
|
||||
<body width="100%" style="margin: 0; padding: 0 !important; background: #f3f3f5; mso-line-height-rule: exactly;">
|
||||
<center style="width: 100%; background: #f3f3f5;">
|
||||
<!--[if mso | IE]>
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="background-color: #f3f3f5;">
|
||||
<tr>
|
||||
<td>
|
||||
<![endif]-->
|
||||
|
||||
<!-- Visually Hidden Preview Text : BEGIN -->
|
||||
<div style="display: none; font-size: 1px; line-height: 1px; max-height: 0px; max-width: 0px; opacity: 0; overflow: hidden; mso-hide: all; font-family: sans-serif;">
|
||||
{{__ "your-event_name-profile"}}
|
||||
</div>
|
||||
<!-- Visually Hidden Preview Text : END -->
|
||||
|
||||
<div class="email-container" style="max-width: 680px; margin: 0 auto;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="680" align="center">
|
||||
<tr>
|
||||
<td>
|
||||
<![endif]-->
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="max-width: 680px; width:100%">
|
||||
<tr>
|
||||
<td style="padding: 30px; background-color: #ffffff;" class="sm-p bar">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
|
||||
<tr>
|
||||
<td style="padding-bottom: 15px; font-family: arial, sans-serif; font-size: 15px; line-height: 21px; color: #3C3F44; text-align: left;">
|
||||
<h1 style="font-weight: bold; font-size: 27px; line-height: 27px; color: #0C0D0E; margin: 0 0 15px 0;">{{event_name}}</h1>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-bottom: 15px; font-family: arial, sans-serif; font-size: 15px; line-height: 21px; color: #3C3F44; text-align: left;">
|
||||
<h1 style="font-weight: bold; font-size: 21px; line-height: 21px; color: #0C0D0E; margin: 0 0 15px 0;">{{__ "your-profile"}}</h1>
|
||||
<p style="margin: 0 0 15px;" class="has-markdown">
|
||||
{{__ "thank-you-for-requesting-a-new-link-to-your-event_name-runner-profile"}}<br>
|
||||
{{__ "you-can-view-your-registration-code-lap-times-and-much-more-by-visiting-our-selfservice"}}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Button Row : BEGIN -->
|
||||
<tr>
|
||||
<td>
|
||||
<!-- Button : BEGIN -->
|
||||
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation">
|
||||
<tr>
|
||||
<td class="s-btn s-btn__primary" style="border-radius: 4px; background: #0095ff;">
|
||||
<a class="s-btn s-btn__primary" href="{{selfservice_link}}" target="_parent" style="background: #0095FF; border: 1px solid #0077cc; box-shadow: inset 0 1px 0 0 rgba(102,191,255,.75); font-family: arial, sans-serif; font-size: 17px; line-height: 17px; color: #ffffff; text-align: center; text-decoration: none; padding: 13px 17px; display: block; border-radius: 4px; white-space: nowrap;">{{__ "view-my-data"}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- Button : END -->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-bottom: 15px; font-family: arial, sans-serif; font-size: 15px; line-height: 21px; color: #3C3F44; text-align: left;">
|
||||
<p>Link: <a href="{{selfservice_link}}">{{selfservice_link}}</a><br>
|
||||
{{__ "if-you-ever-loose-the-link-you-can-request-a-new-one-by-visiting-our-website"}} <a href="{{forgot_link}}">{{forgot_link}}</a></p></td>
|
||||
</tr>
|
||||
<!-- Button Row : END -->
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-----------------------------
|
||||
|
||||
EMAIL BODY : END
|
||||
|
||||
------------------------------>
|
||||
|
||||
<!-- Footer : BEGIN -->
|
||||
<tr>
|
||||
<td style="padding: 30px;" class="sm-p">
|
||||
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation" width="100%">
|
||||
<!-- Subscription Info : BEGIN -->
|
||||
<tr>
|
||||
<td style="padding-bottom: 10px; font-size: 12px; line-height: 15px; font-family: arial, sans-serif; color: #9199A1; text-align: left;">
|
||||
Copyright © {{copyright_owner}}. {{__ "all-rights-reserved"}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-size: 12px; line-height: 15px; font-family: arial, sans-serif; color: #9199A1; text-align: left;">
|
||||
<a href="{{link_imprint}}"
|
||||
style="color: #9199A1; text-decoration: underline;">{{__ "imprint"}}</a>
|
||||
<a href="{{link_privacy}}" style="color: #9199A1; text-decoration: underline;">{{__ "privacy"}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Subscription Info : BEGIN -->
|
||||
<!-- HR line : BEGIN -->
|
||||
<tr>
|
||||
<td style="padding: 30px 0;" width="100%" class="sm-py">
|
||||
<table aria-hidden="true" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%">
|
||||
<tr>
|
||||
<td height="1" width="100%" style="font-size: 0; line-height: 0; border-top: 1px solid #D6D8DB;"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- HR line : END -->
|
||||
<tr>
|
||||
<td style="padding-bottom: 5px; font-size: 12px; line-height: 15px; font-family: arial, sans-serif; color: #9199A1; text-align: left;">
|
||||
{{__ "this-mail-was-sent-to-you-because-someone-requested-a-new-link-to-access-your-profile-for-the-event_name"}}<br>
|
||||
{{__ "to-prevent-spam-you-can-only-request-a-new-link-every-24hrs"}}<br>
|
||||
{{__ "if-you-didnt-register-yourself-you-should-contact-us-to-get-your-data-removed-from-our-systems"}} <a href="mailto:{{contact_mail}}">{{contact_mail}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Sender Info : END -->
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Footer : END -->
|
||||
</table>
|
||||
</div>
|
||||
<!--[if mso | IE]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,15 +0,0 @@
|
||||
{{__ "your-event_name-profile"}}
|
||||
|
||||
{{__ "thank-you-for-requesting-a-new-link-to-your-event_name-runner-profile"}}
|
||||
{{__ "you-can-view-your-registration-code-lap-times-and-much-more-by-visiting-our-selfservice"}}
|
||||
|
||||
{{selfservice_link}}
|
||||
|
||||
{{__ "if-you-ever-loose-the-link-you-can-request-a-new-one-by-visiting-our-website"}} {{forgot_link}}
|
||||
|
||||
|
||||
Copyright © {{copyright_owner}}. {{__ "all-rights-reserved"}}.
|
||||
{{__ "imprint"}}: {{link_imprint}} | {{__ "privacy"}}: {{link_privacy}}
|
||||
{{__ "this-mail-was-sent-to-you-because-someone-requested-a-new-link-to-access-your-profile-for-the-event_name"}}
|
||||
{{__ "to-prevent-spam-you-can-only-request-a-new-link-every-24hrs"}}
|
||||
{{__ "if-you-didnt-register-yourself-you-should-contact-us-to-get-your-data-removed-from-our-systems"}} {{contact_mail}}
|
||||
@@ -1,450 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de" xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office"
|
||||
xmlns:v="urn:schemas-microsoft-com:vml">
|
||||
|
||||
<head>
|
||||
<title>{{__ "lfk-mail-test"}}</title> <!-- The title tag shows in email notifications, like Android 4.4. -->
|
||||
<meta charset="utf-8"> <!-- utf-8 works for most cases -->
|
||||
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width"> <!-- Forcing initial-scale shouldn't be necessary -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- Use the latest (edge) version of IE rendering engine -->
|
||||
<meta name="x-apple-disable-message-reformatting"> <!-- Disable auto-scale in iOS 10 Mail entirely -->
|
||||
<meta name="format-detection" content="telephone=no,address=no,email=no,date=no,url=no">
|
||||
<!-- Tell iOS not to automatically link certain text strings. -->
|
||||
|
||||
<!-- CSS Reset : BEGIN -->
|
||||
<style>
|
||||
/* What it does: Remove spaces around the email design added by some email clients. */
|
||||
/* Beware: It can remove the padding / margin and add a background color to the compose a reply window. */
|
||||
html,
|
||||
body {
|
||||
margin: 0 auto !important;
|
||||
padding: 0 !important;
|
||||
height: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* What it does: Stops email clients resizing small text. */
|
||||
* {
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
/* What it does: Centers email on Android 4.4 */
|
||||
div[style*="margin: 16px 0"] {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
/* What it does: Stops Outlook from adding extra spacing to tables. */
|
||||
table,
|
||||
td {
|
||||
mso-table-lspace: 0pt !important;
|
||||
mso-table-rspace: 0pt !important;
|
||||
}
|
||||
|
||||
/* What it does: Fixes webkit padding issue. */
|
||||
table {
|
||||
border: 0;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse
|
||||
}
|
||||
|
||||
/* What it does: Forces Samsung Android mail clients to use the entire viewport. */
|
||||
#MessageViewBody,
|
||||
#MessageWebViewDiv {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* What it does: Uses a better rendering method when resizing images in IE. */
|
||||
img {
|
||||
-ms-interpolation-mode: bicubic;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Windows 10 Mail from underlining links despite inline CSS. Styles for underlined links should be inline. */
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* What it does: A work-around for email clients automatically linking certain text strings. */
|
||||
/* iOS */
|
||||
a[x-apple-data-detectors],
|
||||
.unstyle-auto-detected-links a,
|
||||
.aBn {
|
||||
border-bottom: 0 !important;
|
||||
cursor: default !important;
|
||||
color: inherit !important;
|
||||
text-decoration: none !important;
|
||||
font-size: inherit !important;
|
||||
font-family: inherit !important;
|
||||
font-weight: inherit !important;
|
||||
line-height: inherit !important;
|
||||
}
|
||||
|
||||
u+#body a,
|
||||
/* Gmail */
|
||||
#MessageViewBody a
|
||||
|
||||
/* Samsung Mail */
|
||||
{
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Gmail from changing the text color in conversation threads. */
|
||||
.im {
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Gmail from displaying an download button on large, non-linked images. */
|
||||
.a6S {
|
||||
display: none !important;
|
||||
opacity: 0.01 !important;
|
||||
}
|
||||
|
||||
/* If the above doesn't work, add a .g-img class to any image in question. */
|
||||
img.g-img+div {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* What it does: Removes right gutter in Gmail iOS app: https://github.com/TedGoas/Cerberus/issues/89 */
|
||||
/* Create one of these media queries for each additional viewport size you'd like to fix */
|
||||
|
||||
/* iPhone 4, 4S, 5, 5S, 5C, and 5SE */
|
||||
@media only screen and (min-device-width: 320px) and (max-device-width: 374px) {
|
||||
u~div .email-container {
|
||||
min-width: 320px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* iPhone 6, 6S, 7, 8, and X */
|
||||
@media only screen and (min-device-width: 375px) and (max-device-width: 413px) {
|
||||
u~div .email-container {
|
||||
min-width: 375px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* iPhone 6+, 7+, and 8+ */
|
||||
@media only screen and (min-device-width: 414px) {
|
||||
u~div .email-container {
|
||||
min-width: 414px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<!-- What it does: Helps DPI scaling in Outlook 2007-2013 -->
|
||||
<!--[if gte mso 9]>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:AllowPNG/>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
<![endif]-->
|
||||
|
||||
<!-- CSS Reset : END -->
|
||||
|
||||
<!-- Progressive Enhancements : BEGIN -->
|
||||
<style>
|
||||
/* What it does: Hover styles for buttons and tags */
|
||||
.s-btn__primary:hover {
|
||||
background: #0077CC !important;
|
||||
border-color: #0077CC !important;
|
||||
}
|
||||
|
||||
.s-btn__white:hover {
|
||||
background: #EFF0F1 !important;
|
||||
border-color: #EFF0F1 !important;
|
||||
}
|
||||
|
||||
.s-btn__outlined:hover {
|
||||
background: rgba(0, 119, 204, .05) !important;
|
||||
color: #005999 !important;
|
||||
}
|
||||
|
||||
.s-tag:hover,
|
||||
.post-tag:hover {
|
||||
border-color: #cee0ed !important;
|
||||
background: #cee0ed !important;
|
||||
}
|
||||
|
||||
/* What it does: Styles markdown links that we can't write inline CSS for. */
|
||||
.has-markdown a,
|
||||
.has-markdown a:visited {
|
||||
color: #0077CC !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/* What it does: Styles markdown code blocks that we can't write inline CSS for. */
|
||||
code {
|
||||
padding: 1px 5px;
|
||||
background-color: #EFF0F1;
|
||||
color: #242729;
|
||||
font-size: 13px;
|
||||
line-height: inherit;
|
||||
font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, sans-serif;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 0 0 15px;
|
||||
line-height: 17px;
|
||||
background-color: #EFF0F1;
|
||||
padding: 4px 8px;
|
||||
border-radius: 3px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
pre code {
|
||||
margin: 0 0 15px;
|
||||
padding: 0;
|
||||
line-height: 17px;
|
||||
background-color: none;
|
||||
}
|
||||
|
||||
/* What it does: Styles markdown blockquotes that we can't write inline CSS for. */
|
||||
blockquote {
|
||||
margin: 0 0 15px;
|
||||
padding: 4px 10px;
|
||||
background-color: #FFF8DC;
|
||||
border-left: 2px solid #ffeb8e;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
padding: 4px 0;
|
||||
margin: 0;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
/* What it does: Rounds corners in email clients that support it */
|
||||
.bar {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.btr {
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
}
|
||||
|
||||
.bbr {
|
||||
border-bottom-left-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 680px) {
|
||||
|
||||
/* What it does: Forces table cells into full-width rows. */
|
||||
.stack-column,
|
||||
.stack-column-center {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
direction: ltr !important;
|
||||
}
|
||||
|
||||
/* And center justify these ones. */
|
||||
.stack-column-center {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
/* Hides things in small viewports. */
|
||||
.hide-on-mobile {
|
||||
display: none !important;
|
||||
max-height: 0 !important;
|
||||
overflow: hidden !important;
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
/* What it does: Utility classes to reduce spacing for smaller viewports. */
|
||||
.sm-p-none {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.sm-pt-none {
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
.sm-pb-none {
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.sm-pr-none {
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
.sm-pl-none {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
.sm-px-none {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
.sm-py-none {
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.sm-p {
|
||||
padding: 20px !important;
|
||||
}
|
||||
|
||||
.sm-pt {
|
||||
padding-top: 20px !important;
|
||||
}
|
||||
|
||||
.sm-pb {
|
||||
padding-bottom: 20px !important;
|
||||
}
|
||||
|
||||
.sm-pr {
|
||||
padding-right: 20px !important;
|
||||
}
|
||||
|
||||
.sm-pl {
|
||||
padding-left: 20px !important;
|
||||
}
|
||||
|
||||
.sm-px {
|
||||
padding-left: 20px !important;
|
||||
padding-right: 20px !important;
|
||||
}
|
||||
|
||||
.sm-py {
|
||||
padding-top: 20px !important;
|
||||
padding-bottom: 20px !important;
|
||||
}
|
||||
|
||||
.sm-mb {
|
||||
margin-bottom: 20px !important;
|
||||
}
|
||||
|
||||
/* What it does: Utility classes to kill border radius for smaller viewports. Used mainly on the email's main container(s). */
|
||||
.bar,
|
||||
.btr,
|
||||
.bbr {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<!-- Progressive Enhancements : END -->
|
||||
</head>
|
||||
|
||||
<!--
|
||||
The email background color is defined in three places, just below. If you change one, remember to change the others.
|
||||
1. body tag: for most email clients
|
||||
2. center tag: for Gmail and Inbox mobile apps and web versions of Gmail, GSuite, Inbox, Yahoo, AOL, Libero, Comcast, freenet, Mail.ru, Orange.fr
|
||||
3. mso conditional: For Windows 10 Mail
|
||||
-->
|
||||
|
||||
<body width="100%" style="margin: 0; padding: 0 !important; background: #f3f3f5; mso-line-height-rule: exactly;">
|
||||
<center style="width: 100%; background: #f3f3f5;">
|
||||
<!--[if mso | IE]>
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="background-color: #f3f3f5;">
|
||||
<tr>
|
||||
<td>
|
||||
<![endif]-->
|
||||
|
||||
<!-- Visually Hidden Preview Text : BEGIN -->
|
||||
<div
|
||||
style="display: none; font-size: 1px; line-height: 1px; max-height: 0px; max-width: 0px; opacity: 0; overflow: hidden; mso-hide: all; font-family: sans-serif;">
|
||||
{{__ "lfk-mail-test"}}
|
||||
</div>
|
||||
<!-- Visually Hidden Preview Text : END -->
|
||||
|
||||
<div class="email-container" style="max-width: 680px; margin: 0 auto;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="680" align="center">
|
||||
<tr>
|
||||
<td>
|
||||
<![endif]-->
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="max-width: 680px; width:100%">
|
||||
<tr>
|
||||
<td style="padding: 30px; background-color: #ffffff;" class="sm-p bar">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
|
||||
<tr>
|
||||
<td
|
||||
style="padding-bottom: 15px; font-family: arial, sans-serif; font-size: 15px; line-height: 21px; color: #3C3F44; text-align: left;">
|
||||
<h1
|
||||
style="font-weight: bold; font-size: 27px; line-height: 27px; color: #0C0D0E; margin: 0 0 15px 0;">
|
||||
LfK!</h1>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
style="padding-bottom: 15px; font-family: arial, sans-serif; font-size: 15px; line-height: 21px; color: #3C3F44; text-align: left;">
|
||||
<h1
|
||||
style="font-weight: bold; font-size: 21px; line-height: 21px; color: #0C0D0E; margin: 0 0 15px 0;">
|
||||
{{__ "test-mail"}}</h1>
|
||||
<p style="margin: 0 0 15px;" class="has-markdown">{{__ "this-is-a-test-mail-triggered-by-an-admin-in-the-lfk-backend"}}</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-----------------------------
|
||||
|
||||
EMAIL BODY : END
|
||||
|
||||
------------------------------>
|
||||
|
||||
<!-- Footer : BEGIN -->
|
||||
<tr>
|
||||
<td style="padding: 30px;" class="sm-p">
|
||||
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation" width="100%">
|
||||
<!-- Subscription Info : BEGIN -->
|
||||
<tr>
|
||||
<td
|
||||
style="padding-bottom: 10px; font-size: 12px; line-height: 15px; font-family: arial, sans-serif; color: #9199A1; text-align: left;">
|
||||
Copyright © {{copyright_owner}}. {{__ "all-rights-reserved"}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
style="font-size: 12px; line-height: 15px; font-family: arial, sans-serif; color: #9199A1; text-align: left;">
|
||||
<a href="{{link_imprint}}" style="color: #9199A1; text-decoration: underline;">{{__ "imprint"}}</a>
|
||||
<a href="{{link_privacy}}" style="color: #9199A1; text-decoration: underline;">{{__ "privacy"}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Subscription Info : BEGIN -->
|
||||
<!-- HR line : BEGIN -->
|
||||
<tr>
|
||||
<td style="padding: 30px 0;" width="100%" class="sm-py">
|
||||
<table aria-hidden="true" border="0" cellpadding="0" cellspacing="0"
|
||||
role="presentation" style="width:100%">
|
||||
<tr>
|
||||
<td height="1" width="100%"
|
||||
style="font-size: 0; line-height: 0; border-top: 1px solid #D6D8DB;">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- HR line : END -->
|
||||
<tr>
|
||||
<td
|
||||
style="padding-bottom: 5px; font-size: 12px; line-height: 15px; font-family: arial, sans-serif; color: #9199A1; text-align: left;">
|
||||
{{__ "this-mail-was-sent-to-recipient_mail-because-someone-request-a-mail-test-for-this-mail-address"}}
|
||||
</tr>
|
||||
<!-- Sender Info : END -->
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Footer : END -->
|
||||
</table>
|
||||
</div>
|
||||
<!--[if mso | IE]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</center>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,7 +0,0 @@
|
||||
{{__ "lfk-mail-test"}}.
|
||||
|
||||
{{__ "this-is-a-test-mail-triggered-by-an-admin-in-the-lfk-backend"}}
|
||||
|
||||
Copyright © {{copyright_owner}}. {{__ "all-rights-reserved"}}.
|
||||
{{__ "imprint"}}: {{link_imprint}} | {{__ "privacy"}}: {{link_privacy}}
|
||||
{{__ "this-mail-was-sent-to-recipient_mail-because-someone-request-a-mail-test-for-this-mail-address"}}
|
||||
@@ -0,0 +1,377 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html dir="ltr" lang="en">
|
||||
<head>
|
||||
<meta content="width=device-width" name="viewport" />
|
||||
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
|
||||
<meta name="x-apple-disable-message-reformatting" />
|
||||
<meta content="IE=edge" http-equiv="X-UA-Compatible" />
|
||||
<meta name="x-apple-disable-message-reformatting" />
|
||||
<meta
|
||||
content="telephone=no,address=no,email=no,date=no,url=no"
|
||||
name="format-detection"
|
||||
/>
|
||||
<meta content="light" name="color-scheme" />
|
||||
<meta content="light" name="supported-color-schemes" />
|
||||
<!--$-->
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
mso-font-alt: "sans-serif";
|
||||
src: url(https://rsms.me/inter/font-files/Inter-Regular.woff2?v=3.19)
|
||||
format("woff2");
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: "Inter", sans-serif;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
blockquote,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
img,
|
||||
li,
|
||||
ol,
|
||||
p,
|
||||
ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
@media only screen and (max-width: 425px) {
|
||||
.tab-row-full {
|
||||
width: 100% !important;
|
||||
}
|
||||
.tab-col-full {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
.tab-pad {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0">
|
||||
<div
|
||||
style="
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
line-height: 1px;
|
||||
opacity: 0;
|
||||
max-height: 0;
|
||||
max-width: 0;
|
||||
"
|
||||
id="__react-email-preview"
|
||||
>
|
||||
Willkommen beim {{event_name}} 🏃♂️🌏
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<table
|
||||
align="center"
|
||||
width="100%"
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="presentation"
|
||||
style="
|
||||
max-width: 600px;
|
||||
min-width: 300px;
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 0.5rem;
|
||||
"
|
||||
>
|
||||
<tbody>
|
||||
<tr style="width: 100%">
|
||||
<td>
|
||||
<table
|
||||
align="center"
|
||||
width="100%"
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="presentation"
|
||||
style="margin-top: 0px; margin-bottom: 32px"
|
||||
>
|
||||
<tbody style="width: 100%">
|
||||
<tr style="width: 100%">
|
||||
<td align="left" data-id="__react-email-column">
|
||||
<img
|
||||
title="Logo"
|
||||
alt="Logo"
|
||||
src="https://run.lauf-fuer-kaya.de/lfk-logo.png"
|
||||
style="
|
||||
display: block;
|
||||
outline: none;
|
||||
border: none;
|
||||
text-decoration: none;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h2
|
||||
style="
|
||||
text-align: left;
|
||||
color: #111827;
|
||||
margin-bottom: 12px;
|
||||
margin-top: 0;
|
||||
font-size: 30px;
|
||||
line-height: 36px;
|
||||
font-weight: 700;
|
||||
"
|
||||
>
|
||||
<strong>Willkommen beim {{event_name}}</strong>
|
||||
</h2>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
<strong>Hallo {{name}} 👋</strong>
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
vielen Dank für deine Registrierung beim {{event_name}}
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
Am Lauftag (<strong>{{event_date}}</strong>) musst du nur noch diesen
|
||||
Barcode vorzeigen, damit erhältst du deine Läuferkarte.
|
||||
</p>
|
||||
<table
|
||||
align="center"
|
||||
width="100%"
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="presentation"
|
||||
style="margin-top: 0px; margin-bottom: 32px"
|
||||
>
|
||||
<tbody style="width: 100%">
|
||||
<tr style="width: 100%">
|
||||
<td align="center" data-id="__react-email-column">
|
||||
<img
|
||||
title="Dein Registrierungs-Code"
|
||||
alt="Dein Registrierungs-Code"
|
||||
src="{{barcode_url}}"
|
||||
style="
|
||||
display: block;
|
||||
outline: none;
|
||||
border: none;
|
||||
text-decoration: none;
|
||||
height: 150px;
|
||||
width: auto;
|
||||
max-width: 601px;
|
||||
max-height: 315.2938461538462px;
|
||||
"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
Deinen Registrierungs-Code, Rundenzeiten und weitere Infos kannst
|
||||
du jederzeit im
|
||||
<a
|
||||
href="{{link}}"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>Lauf für Kaya! Selfservice</a
|
||||
>
|
||||
einsehen.
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
Wir freuen uns schon auf dich und einen erfolgreichen Lauf für
|
||||
Kaya!
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
Bei Fragen antworte gerne jederzeit auf diese E-Mail oder schreibe
|
||||
an
|
||||
<u
|
||||
><strong
|
||||
><a
|
||||
href="mailto:info@lauf-fuer-kaya.de"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>info@lauf-fuer-kaya.de</a
|
||||
></strong
|
||||
></u
|
||||
>
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
Sportliche Grüße 🏃♂️<br />Dein Team Lauf für Kaya!
|
||||
</p>
|
||||
<hr
|
||||
style="
|
||||
width: 100%;
|
||||
border: none;
|
||||
border-top: 1px solid #eaeaea;
|
||||
margin-top: 32px;
|
||||
margin-bottom: 32px;
|
||||
"
|
||||
/>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
Lauf für Kaya! <strong>Powered by </strong
|
||||
><u
|
||||
><strong
|
||||
><a
|
||||
href="https://odit.services?ref=lfkmail"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>ODIT.Services</a
|
||||
></strong
|
||||
></u
|
||||
>.<br /><u
|
||||
><strong
|
||||
><a
|
||||
href="https://lauf-fuer-kaya.de/impressum/"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>Impressum</a
|
||||
></strong
|
||||
></u
|
||||
>
|
||||
-
|
||||
<u
|
||||
><strong
|
||||
><a
|
||||
href="https://lauf-fuer-kaya.de/datenschutz/"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>Datenschutzerklärung</a
|
||||
></strong
|
||||
></u
|
||||
>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!--/$-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Willkommen beim {{event_name}}
|
||||
@@ -0,0 +1,20 @@
|
||||
Hallo {{name}} 👋
|
||||
|
||||
vielen Dank für deine Registrierung beim {{event_name}}
|
||||
|
||||
Am Lauftag ({{event_date}}) musst du nur noch deinen Barcode vorzeigen, damit erhältst du deine Läuferkarte.
|
||||
Deinen Registrierungs-Code, Rundenzeiten und weitere Infos kannst du jederzeit im Lauf für Kaya! Selfservice unter {{link}} einsehen.
|
||||
|
||||
Wir freuen uns schon auf dich und einen erfolgreichen Lauf für Kaya!
|
||||
|
||||
Bei Fragen antworte gerne jederzeit auf diese E-Mail oder schreibe an info@lauf-fuer-kaya.de
|
||||
|
||||
Sportliche Grüße 🏃♂️
|
||||
Dein Team Lauf für Kaya!
|
||||
|
||||
-
|
||||
|
||||
Lauf für Kaya!
|
||||
Powered by ODIT.Services (https://odit.services)
|
||||
Impressum: https://lauf-fuer-kaya.de/impressum/
|
||||
Datenschutzerklärung: https://lauf-fuer-kaya.de/datenschutz/
|
||||
@@ -0,0 +1,372 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html dir="ltr" lang="en">
|
||||
<head>
|
||||
<meta content="width=device-width" name="viewport" />
|
||||
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
|
||||
<meta name="x-apple-disable-message-reformatting" />
|
||||
<meta content="IE=edge" http-equiv="X-UA-Compatible" />
|
||||
<meta name="x-apple-disable-message-reformatting" />
|
||||
<meta
|
||||
content="telephone=no,address=no,email=no,date=no,url=no"
|
||||
name="format-detection"
|
||||
/>
|
||||
<meta content="light" name="color-scheme" />
|
||||
<meta content="light" name="supported-color-schemes" />
|
||||
<!--$-->
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
mso-font-alt: "sans-serif";
|
||||
src: url(https://rsms.me/inter/font-files/Inter-Regular.woff2?v=3.19)
|
||||
format("woff2");
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: "Inter", sans-serif;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
blockquote,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
img,
|
||||
li,
|
||||
ol,
|
||||
p,
|
||||
ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
@media only screen and (max-width: 425px) {
|
||||
.tab-row-full {
|
||||
width: 100% !important;
|
||||
}
|
||||
.tab-col-full {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
.tab-pad {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0">
|
||||
<div
|
||||
style="
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
line-height: 1px;
|
||||
opacity: 0;
|
||||
max-height: 0;
|
||||
max-width: 0;
|
||||
"
|
||||
id="__react-email-preview"
|
||||
>
|
||||
Welcome to {{event_name}} 🏃♂️🌏
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<table
|
||||
align="center"
|
||||
width="100%"
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="presentation"
|
||||
style="
|
||||
max-width: 600px;
|
||||
min-width: 300px;
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 0.5rem;
|
||||
"
|
||||
>
|
||||
<tbody>
|
||||
<tr style="width: 100%">
|
||||
<td>
|
||||
<table
|
||||
align="center"
|
||||
width="100%"
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="presentation"
|
||||
style="margin-top: 0px; margin-bottom: 32px"
|
||||
>
|
||||
<tbody style="width: 100%">
|
||||
<tr style="width: 100%">
|
||||
<td align="left" data-id="__react-email-column">
|
||||
<img
|
||||
title="Logo"
|
||||
alt="Logo"
|
||||
src="https://run.lauf-fuer-kaya.de/lfk-logo.png"
|
||||
style="
|
||||
display: block;
|
||||
outline: none;
|
||||
border: none;
|
||||
text-decoration: none;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h2
|
||||
style="
|
||||
text-align: left;
|
||||
color: #111827;
|
||||
margin-bottom: 12px;
|
||||
margin-top: 0;
|
||||
font-size: 30px;
|
||||
line-height: 36px;
|
||||
font-weight: 700;
|
||||
"
|
||||
>
|
||||
<strong>Welcome to {{event_name}}</strong>
|
||||
</h2>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
<strong>Hello {{name}} 👋</strong>
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
Thank you for registering for the {{event_name}}
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
On the day of the run (<strong>{{event_date}}</strong>) you only have to show your barcode to receive your runner's card.
|
||||
</p>
|
||||
<table
|
||||
align="center"
|
||||
width="100%"
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
role="presentation"
|
||||
style="margin-top: 0px; margin-bottom: 32px"
|
||||
>
|
||||
<tbody style="width: 100%">
|
||||
<tr style="width: 100%">
|
||||
<td align="center" data-id="__react-email-column">
|
||||
<img
|
||||
title="Your registration code"
|
||||
alt="Your registration code"
|
||||
src="{{barcode_url}}"
|
||||
style="
|
||||
display: block;
|
||||
outline: none;
|
||||
border: none;
|
||||
text-decoration: none;
|
||||
height: 150px;
|
||||
width: auto;
|
||||
max-width: 601px;
|
||||
max-height: 315.2938461538462px;
|
||||
"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
You can view your registration code, lap times and further information at any time from the
|
||||
<a
|
||||
href="{{link}}"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>Lauf für Kaya! Selfservice</a
|
||||
>
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
We look forward to seeing you and to a successful Lauf für Kaya!
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
If you have any questions, please reply to this e-mail at any time or write to
|
||||
<u
|
||||
><strong
|
||||
><a
|
||||
href="mailto:info@lauf-fuer-kaya.de"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>info@lauf-fuer-kaya.de</a
|
||||
></strong
|
||||
></u
|
||||
>
|
||||
</p>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
Sporty Greetings 🏃♂️<br />Your Team Lauf für Kaya!
|
||||
</p>
|
||||
<hr
|
||||
style="
|
||||
width: 100%;
|
||||
border: none;
|
||||
border-top: 1px solid #eaeaea;
|
||||
margin-top: 32px;
|
||||
margin-bottom: 32px;
|
||||
"
|
||||
/>
|
||||
<p
|
||||
style="
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
color: #374151;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
"
|
||||
>
|
||||
Lauf für Kaya! <strong>Powered by </strong
|
||||
><u
|
||||
><strong
|
||||
><a
|
||||
href="https://odit.services?ref=lfkmail"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>ODIT.Services</a
|
||||
></strong
|
||||
></u
|
||||
>.<br /><u
|
||||
><strong
|
||||
><a
|
||||
href="https://lauf-fuer-kaya.de/impressum/"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>Imprint</a
|
||||
></strong
|
||||
></u
|
||||
>
|
||||
-
|
||||
<u
|
||||
><strong
|
||||
><a
|
||||
href="https://lauf-fuer-kaya.de/datenschutz/"
|
||||
rel="noopener noreferrer nofollow"
|
||||
style="
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
"
|
||||
target="_blank"
|
||||
>Privacy Policy</a
|
||||
></strong
|
||||
></u
|
||||
>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!--/$-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Welcome to {{event_name}}
|
||||
@@ -0,0 +1,20 @@
|
||||
Hello {{name}} 👋
|
||||
|
||||
Thank you for registering for the {{event_name}}
|
||||
|
||||
On the day of the run ({{event_date}}) you only have to show your barcode to receive your runner's card.
|
||||
You can view your registration code, lap times and further information at any time from the Lauf für Kaya! Selfservice at {{link}}.
|
||||
|
||||
We look forward to seeing you and to a successful Lauf für Kaya!
|
||||
|
||||
If you have any questions, please reply to this e-mail at any time or write to info@lauf-fuer-kaya.de
|
||||
|
||||
Sporty Greetings 🏃♂️
|
||||
Your Team Lauf für Kaya!
|
||||
|
||||
-
|
||||
|
||||
Lauf für Kaya!
|
||||
Powered by ODIT.Services (https://odit.services)
|
||||
Imprint: https://lauf-fuer-kaya.de/impressum/
|
||||
Privacy Policy: https://lauf-fuer-kaya.de/datenschutz/
|
||||
@@ -1,397 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="de" xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:v="urn:schemas-microsoft-com:vml">
|
||||
<head>
|
||||
<title>{{__ "event_name-registration"}}</title> <!-- The title tag shows in email notifications, like Android 4.4. -->
|
||||
<meta charset="utf-8"> <!-- utf-8 works for most cases -->
|
||||
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width"> <!-- Forcing initial-scale shouldn't be necessary -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- Use the latest (edge) version of IE rendering engine -->
|
||||
<meta name="x-apple-disable-message-reformatting"> <!-- Disable auto-scale in iOS 10 Mail entirely -->
|
||||
<meta name="format-detection" content="telephone=no,address=no,email=no,date=no,url=no"> <!-- Tell iOS not to automatically link certain text strings. -->
|
||||
|
||||
<!-- CSS Reset : BEGIN -->
|
||||
<style>
|
||||
/* What it does: Remove spaces around the email design added by some email clients. */
|
||||
/* Beware: It can remove the padding / margin and add a background color to the compose a reply window. */
|
||||
html,
|
||||
body {
|
||||
margin: 0 auto !important;
|
||||
padding: 0 !important;
|
||||
height: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* What it does: Stops email clients resizing small text. */
|
||||
* {
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
/* What it does: Centers email on Android 4.4 */
|
||||
div[style*="margin: 16px 0"] {
|
||||
margin:0 !important;
|
||||
}
|
||||
|
||||
/* What it does: Stops Outlook from adding extra spacing to tables. */
|
||||
table,
|
||||
td {
|
||||
mso-table-lspace: 0pt !important;
|
||||
mso-table-rspace: 0pt !important;
|
||||
}
|
||||
|
||||
/* What it does: Fixes webkit padding issue. */
|
||||
table {
|
||||
border: 0;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse
|
||||
}
|
||||
|
||||
/* What it does: Forces Samsung Android mail clients to use the entire viewport. */
|
||||
#MessageViewBody,
|
||||
#MessageWebViewDiv{
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* What it does: Uses a better rendering method when resizing images in IE. */
|
||||
img {
|
||||
-ms-interpolation-mode:bicubic;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Windows 10 Mail from underlining links despite inline CSS. Styles for underlined links should be inline. */
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* What it does: A work-around for email clients automatically linking certain text strings. */
|
||||
/* iOS */
|
||||
a[x-apple-data-detectors],
|
||||
.unstyle-auto-detected-links a,
|
||||
.aBn {
|
||||
border-bottom: 0 !important;
|
||||
cursor: default !important;
|
||||
color: inherit !important;
|
||||
text-decoration: none !important;
|
||||
font-size: inherit !important;
|
||||
font-family: inherit !important;
|
||||
font-weight: inherit !important;
|
||||
line-height: inherit !important;
|
||||
}
|
||||
u + #body a, /* Gmail */
|
||||
#MessageViewBody a /* Samsung Mail */
|
||||
{
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Gmail from changing the text color in conversation threads. */
|
||||
.im {
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Gmail from displaying an download button on large, non-linked images. */
|
||||
.a6S {
|
||||
display: none !important;
|
||||
opacity: 0.01 !important;
|
||||
}
|
||||
/* If the above doesn't work, add a .g-img class to any image in question. */
|
||||
img.g-img + div {
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
/* What it does: Removes right gutter in Gmail iOS app: https://github.com/TedGoas/Cerberus/issues/89 */
|
||||
/* Create one of these media queries for each additional viewport size you'd like to fix */
|
||||
|
||||
/* iPhone 4, 4S, 5, 5S, 5C, and 5SE */
|
||||
@media only screen and (min-device-width: 320px) and (max-device-width: 374px) {
|
||||
u ~ div .email-container {
|
||||
min-width: 320px !important;
|
||||
}
|
||||
}
|
||||
/* iPhone 6, 6S, 7, 8, and X */
|
||||
@media only screen and (min-device-width: 375px) and (max-device-width: 413px) {
|
||||
u ~ div .email-container {
|
||||
min-width: 375px !important;
|
||||
}
|
||||
}
|
||||
/* iPhone 6+, 7+, and 8+ */
|
||||
@media only screen and (min-device-width: 414px) {
|
||||
u ~ div .email-container {
|
||||
min-width: 414px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<!-- What it does: Helps DPI scaling in Outlook 2007-2013 -->
|
||||
<!--[if gte mso 9]>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:AllowPNG/>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
<![endif]-->
|
||||
|
||||
<!-- CSS Reset : END -->
|
||||
|
||||
<!-- Progressive Enhancements : BEGIN -->
|
||||
<style>
|
||||
/* What it does: Hover styles for buttons and tags */
|
||||
.s-btn__primary:hover {
|
||||
background: #0077CC !important;
|
||||
border-color: #0077CC !important;
|
||||
}
|
||||
.s-btn__white:hover {
|
||||
background: #EFF0F1 !important;
|
||||
border-color: #EFF0F1 !important;
|
||||
}
|
||||
.s-btn__outlined:hover {
|
||||
background: rgba(0,119,204,.05) !important;
|
||||
color: #005999 !important;
|
||||
}
|
||||
.s-tag:hover,
|
||||
.post-tag:hover {
|
||||
border-color: #cee0ed !important;
|
||||
background: #cee0ed !important;
|
||||
}
|
||||
|
||||
/* What it does: Styles markdown links that we can't write inline CSS for. */
|
||||
.has-markdown a,
|
||||
.has-markdown a:visited {
|
||||
color: #0077CC !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/* What it does: Styles markdown code blocks that we can't write inline CSS for. */
|
||||
code {
|
||||
padding: 1px 5px;
|
||||
background-color: #EFF0F1;
|
||||
color: #242729;
|
||||
font-size: 13px;
|
||||
line-height: inherit;
|
||||
font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, sans-serif;
|
||||
}
|
||||
pre {
|
||||
margin: 0 0 15px;
|
||||
line-height: 17px;
|
||||
background-color: #EFF0F1;
|
||||
padding: 4px 8px;
|
||||
border-radius: 3px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
pre code {
|
||||
margin: 0 0 15px;
|
||||
padding: 0;
|
||||
line-height: 17px;
|
||||
background-color: none;
|
||||
}
|
||||
|
||||
/* What it does: Styles markdown blockquotes that we can't write inline CSS for. */
|
||||
blockquote {
|
||||
margin: 0 0 15px;
|
||||
padding: 4px 10px;
|
||||
background-color: #FFF8DC;
|
||||
border-left: 2px solid #ffeb8e;
|
||||
}
|
||||
blockquote p {
|
||||
padding: 4px 0;
|
||||
margin: 0;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
/* What it does: Rounds corners in email clients that support it */
|
||||
.bar {
|
||||
border-radius: 5px;
|
||||
}
|
||||
.btr {
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
}
|
||||
.bbr {
|
||||
border-bottom-left-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 680px) {
|
||||
/* What it does: Forces table cells into full-width rows. */
|
||||
.stack-column,
|
||||
.stack-column-center {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
direction: ltr !important;
|
||||
}
|
||||
/* And center justify these ones. */
|
||||
.stack-column-center {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
/* Hides things in small viewports. */
|
||||
.hide-on-mobile {
|
||||
display: none !important;
|
||||
max-height: 0 !important;
|
||||
overflow: hidden !important;
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
/* What it does: Utility classes to reduce spacing for smaller viewports. */
|
||||
.sm-p-none {padding: 0 !important;}
|
||||
.sm-pt-none {padding-top: 0 !important;}
|
||||
.sm-pb-none {padding-bottom: 0 !important;}
|
||||
.sm-pr-none {padding-right: 0 !important;}
|
||||
.sm-pl-none {padding-left: 0 !important;}
|
||||
.sm-px-none {padding-left: 0 !important; padding-right: 0 !important;}
|
||||
.sm-py-none {padding-top: 0 !important; padding-bottom: 0 !important;}
|
||||
|
||||
.sm-p {padding: 20px !important;}
|
||||
.sm-pt {padding-top: 20px !important;}
|
||||
.sm-pb {padding-bottom: 20px !important;}
|
||||
.sm-pr {padding-right: 20px !important;}
|
||||
.sm-pl {padding-left: 20px !important;}
|
||||
.sm-px {padding-left: 20px !important; padding-right: 20px !important;}
|
||||
.sm-py {padding-top: 20px !important; padding-bottom: 20px !important;}
|
||||
.sm-mb {margin-bottom: 20px !important;}
|
||||
|
||||
/* What it does: Utility classes to kill border radius for smaller viewports. Used mainly on the email's main container(s). */
|
||||
.bar,
|
||||
.btr,
|
||||
.bbr {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<!-- Progressive Enhancements : END -->
|
||||
</head>
|
||||
|
||||
<!--
|
||||
The email background color is defined in three places, just below. If you change one, remember to change the others.
|
||||
1. body tag: for most email clients
|
||||
2. center tag: for Gmail and Inbox mobile apps and web versions of Gmail, GSuite, Inbox, Yahoo, AOL, Libero, Comcast, freenet, Mail.ru, Orange.fr
|
||||
3. mso conditional: For Windows 10 Mail
|
||||
-->
|
||||
<body width="100%" style="margin: 0; padding: 0 !important; background: #f3f3f5; mso-line-height-rule: exactly;">
|
||||
<center style="width: 100%; background: #f3f3f5;">
|
||||
<!--[if mso | IE]>
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="background-color: #f3f3f5;">
|
||||
<tr>
|
||||
<td>
|
||||
<![endif]-->
|
||||
|
||||
<!-- Visually Hidden Preview Text : BEGIN -->
|
||||
<div style="display: none; font-size: 1px; line-height: 1px; max-height: 0px; max-width: 0px; opacity: 0; overflow: hidden; mso-hide: all; font-family: sans-serif;">
|
||||
{{__ "event_name-registration"}}
|
||||
</div>
|
||||
<!-- Visually Hidden Preview Text : END -->
|
||||
|
||||
<div class="email-container" style="max-width: 680px; margin: 0 auto;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="680" align="center">
|
||||
<tr>
|
||||
<td>
|
||||
<![endif]-->
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="max-width: 680px; width:100%">
|
||||
<tr>
|
||||
<td style="padding: 30px; background-color: #ffffff;" class="sm-p bar">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
|
||||
<tr>
|
||||
<td style="padding-bottom: 15px; font-family: arial, sans-serif; font-size: 15px; line-height: 21px; color: #3C3F44; text-align: left;">
|
||||
<h1 style="font-weight: bold; font-size: 27px; line-height: 27px; color: #0C0D0E; margin: 0 0 15px 0;">{{event_name}}</h1>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-bottom: 15px; font-family: arial, sans-serif; font-size: 15px; line-height: 21px; color: #3C3F44; text-align: left;">
|
||||
<h1 style="font-weight: bold; font-size: 21px; line-height: 21px; color: #0C0D0E; margin: 0 0 15px 0;">{{__ "welcome"}}</h1>
|
||||
<p style="margin: 0 0 15px;" class="has-markdown">
|
||||
{{__ "thanks-for-registering-and-welcome-to-the-event_name"}} <br>
|
||||
{{__ "we-successfully-processed-your-registration"}}<br><br>
|
||||
{{__ "the-only-thing-you-have-to-do-now-is-to-bring-your-registration-code-with-you"}}<br>
|
||||
{{__ "you-can-view-your-registration-code-lap-times-and-much-more-by-visiting-our-selfservice"}}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Button Row : BEGIN -->
|
||||
<tr>
|
||||
<td>
|
||||
<!-- Button : BEGIN -->
|
||||
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation">
|
||||
<tr>
|
||||
<td class="s-btn s-btn__primary" style="border-radius: 4px; background: #0095ff;">
|
||||
<a class="s-btn s-btn__primary" href="{{selfservice_link}}" target="_parent" style="background: #0095FF; border: 1px solid #0077cc; box-shadow: inset 0 1px 0 0 rgba(102,191,255,.75); font-family: arial, sans-serif; font-size: 17px; line-height: 17px; color: #ffffff; text-align: center; text-decoration: none; padding: 13px 17px; display: block; border-radius: 4px; white-space: nowrap;">{{__ "view-my-data"}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- Button : END -->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-bottom: 15px; font-family: arial, sans-serif; font-size: 15px; line-height: 21px; color: #3C3F44; text-align: left;">
|
||||
<p>Link: <a href="{{selfservice_link}}">{{selfservice_link}}</a><br>
|
||||
{{__ "if-you-ever-loose-the-link-you-can-request-a-new-one-by-visiting-our-website"}} <a href="{{forgot_link}}">{{forgot_link}}</a></p></td>
|
||||
</tr>
|
||||
<!-- Button Row : END -->
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-----------------------------
|
||||
|
||||
EMAIL BODY : END
|
||||
|
||||
------------------------------>
|
||||
|
||||
<!-- Footer : BEGIN -->
|
||||
<tr>
|
||||
<td style="padding: 30px;" class="sm-p">
|
||||
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation" width="100%">
|
||||
<!-- Subscription Info : BEGIN -->
|
||||
<tr>
|
||||
<td style="padding-bottom: 10px; font-size: 12px; line-height: 15px; font-family: arial, sans-serif; color: #9199A1; text-align: left;">
|
||||
Copyright © {{copyright_owner}}. {{__ "all-rights-reserved"}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-size: 12px; line-height: 15px; font-family: arial, sans-serif; color: #9199A1; text-align: left;">
|
||||
<a href="{{link_imprint}}"
|
||||
style="color: #9199A1; text-decoration: underline;">{{__ "imprint"}}</a>
|
||||
<a href="{{link_privacy}}" style="color: #9199A1; text-decoration: underline;">{{__ "privacy"}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Subscription Info : BEGIN -->
|
||||
<!-- HR line : BEGIN -->
|
||||
<tr>
|
||||
<td style="padding: 30px 0;" width="100%" class="sm-py">
|
||||
<table aria-hidden="true" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%">
|
||||
<tr>
|
||||
<td height="1" width="100%" style="font-size: 0; line-height: 0; border-top: 1px solid #D6D8DB;"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- HR line : END -->
|
||||
<tr>
|
||||
<td style="padding-bottom: 5px; font-size: 12px; line-height: 15px; font-family: arial, sans-serif; color: #9199A1; text-align: left;">
|
||||
{{__ "this-mail-was-sent-to-you-because-someone-used-your-mail-address-to-register-themselfes-for-the-event_name"}}.<br>
|
||||
{{__ "if-you-didnt-register-yourself-you-should-contact-us-to-get-your-data-removed-from-our-systems"}} <a href="mailto:{{contact_mail}}">{{contact_mail}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Sender Info : END -->
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Footer : END -->
|
||||
</table>
|
||||
</div>
|
||||
<!--[if mso | IE]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,17 +0,0 @@
|
||||
{{__ "event_name-registration"}}
|
||||
|
||||
{{__ "thanks-for-registering-and-welcome-to-the-event_name"}}
|
||||
{{__ "we-successfully-processed-your-registration"}}
|
||||
|
||||
{{__ "the-only-thing-you-have-to-do-now-is-to-bring-your-registration-code-with-you"}}
|
||||
{{__ "you-can-view-your-registration-code-lap-times-and-much-more-by-visiting-our-selfservice"}}
|
||||
|
||||
{{selfservice_link}}
|
||||
|
||||
{{__ "if-you-ever-loose-the-link-you-can-request-a-new-one-by-visiting-our-website"}} {{forgot_link}}
|
||||
|
||||
|
||||
Copyright © {{copyright_owner}}. {{__ "all-rights-reserved"}}.
|
||||
{{__ "imprint"}}: {{link_imprint}} | {{__ "privacy"}}: {{link_privacy}}
|
||||
{{__ "this-mail-was-sent-to-you-because-someone-used-your-mail-address-to-register-themselfes-for-the-event_name"}}
|
||||
{{__ "if-you-didnt-register-yourself-you-should-contact-us-to-get-your-data-removed-from-our-systems"}} {{contact_mail}}
|
||||
@@ -1,34 +0,0 @@
|
||||
import axios from 'axios';
|
||||
import { config } from '../config';
|
||||
const base = "http://localhost:" + config.internal_port
|
||||
|
||||
describe('GET /docs/openapi.json', () => {
|
||||
it('OpenAPI Spec is availdable 200', async () => {
|
||||
const res = await axios.get(base + '/docs/openapi.json');
|
||||
expect(res.status).toEqual(200);
|
||||
});
|
||||
});
|
||||
describe('GET /docs/swagger.json', () => {
|
||||
it('OpenAPI Spec is availdable 200', async () => {
|
||||
const res = await axios.get(base + '/docs/swagger.json');
|
||||
expect(res.status).toEqual(200);
|
||||
});
|
||||
});
|
||||
describe('GET /docs/swaggerui', () => {
|
||||
it('swaggerui is availdable 200', async () => {
|
||||
const res = await axios.get(base + '/docs/swaggerui');
|
||||
expect(res.status).toEqual(200);
|
||||
});
|
||||
});
|
||||
describe('GET /docs/redoc', () => {
|
||||
it('redoc is availdable 200', async () => {
|
||||
const res = await axios.get(base + '/docs/redoc');
|
||||
expect(res.status).toEqual(200);
|
||||
});
|
||||
});
|
||||
describe('GET /docs/rapidoc', () => {
|
||||
it('rapidoc is availdable 200', async () => {
|
||||
const res = await axios.get(base + '/docs/rapidoc');
|
||||
expect(res.status).toEqual(200);
|
||||
});
|
||||
});
|
||||
@@ -1,75 +0,0 @@
|
||||
import axios from 'axios';
|
||||
import { config } from '../config';
|
||||
const base = "http://localhost:" + config.internal_port
|
||||
|
||||
const axios_config = {
|
||||
validateStatus: undefined
|
||||
};
|
||||
|
||||
describe('POST /reset without auth', () => {
|
||||
it('Post without auth should return 401', async () => {
|
||||
const res = await axios.post(base + '/reset', null, axios_config);
|
||||
expect(res.status).toEqual(401);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /reset with auth but wrong body', () => {
|
||||
it('Post with auth but no body should return 400', async () => {
|
||||
const res = await axios.post(base + '/reset?key=' + config.api_key, null, axios_config);
|
||||
expect(res.status).toEqual(400);
|
||||
});
|
||||
it('Post with auth but no mail should return 400', async () => {
|
||||
const res = await axios.post(base + '/reset?key=' + config.api_key, { resetKey: "test" }, axios_config);
|
||||
expect(res.status).toEqual(400);
|
||||
});
|
||||
it('Post with auth but no reset key should return 400', async () => {
|
||||
const res = await axios.post(base + '/reset?key=' + config.api_key, { address: "test@dev.lauf-fuer-kaya.de" }, axios_config);
|
||||
expect(res.status).toEqual(400);
|
||||
});
|
||||
it('Post with auth but invalid mail should return 400', async () => {
|
||||
const res = await axios.post(base + '/reset?key=' + config.api_key, { resetKey: "test", address: "testdev.l.de" }, axios_config);
|
||||
expect(res.status).toEqual(400);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /reset with auth and vaild body', () => {
|
||||
it('Post with auth, body and no locale should return 200', async () => {
|
||||
const res = await axios.post(base + '/reset?key=' + config.api_key, {
|
||||
resetKey: "test",
|
||||
address: "test@dev.lauf-fuer-kaya.de"
|
||||
}, axios_config);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "en",
|
||||
type: "PASSWORD_RESET"
|
||||
})
|
||||
});
|
||||
it('Post with auth, body and locale=en should return 200', async () => {
|
||||
const res = await axios.post(base + '/reset?locale=en&key=' + config.api_key, {
|
||||
resetKey: "test",
|
||||
address: "test@dev.lauf-fuer-kaya.de"
|
||||
}, axios_config);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "en",
|
||||
type: "PASSWORD_RESET"
|
||||
})
|
||||
});
|
||||
it('Post with auth, body and locale=de should return 200', async () => {
|
||||
const res = await axios.post(base + '/reset?locale=de&key=' + config.api_key, {
|
||||
resetKey: "test",
|
||||
address: "test@dev.lauf-fuer-kaya.de"
|
||||
}, axios_config);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "de",
|
||||
type: "PASSWORD_RESET"
|
||||
})
|
||||
});
|
||||
});
|
||||
@@ -1,75 +0,0 @@
|
||||
import axios from 'axios';
|
||||
import { config } from '../config';
|
||||
const base = "http://localhost:" + config.internal_port
|
||||
|
||||
const axios_config = {
|
||||
validateStatus: undefined
|
||||
};
|
||||
|
||||
describe('POST /registration_forgot without auth', () => {
|
||||
it('Post without auth should return 401', async () => {
|
||||
const res = await axios.post(base + '/registration_forgot', null, axios_config);
|
||||
expect(res.status).toEqual(401);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /registration_forgot with auth but wrong body', () => {
|
||||
it('Post with auth but no body should return 400', async () => {
|
||||
const res = await axios.post(base + '/registration_forgot?key=' + config.api_key, null, axios_config);
|
||||
expect(res.status).toEqual(400);
|
||||
});
|
||||
it('Post with auth but no mail should return 400', async () => {
|
||||
const res = await axios.post(base + '/registration_forgot?key=' + config.api_key, { selfserviceToken: "test" }, axios_config);
|
||||
expect(res.status).toEqual(400);
|
||||
});
|
||||
it('Post with auth but no reset key should return 400', async () => {
|
||||
const res = await axios.post(base + '/registration_forgot?key=' + config.api_key, { address: "test@dev.lauf-fuer-kaya.de" }, axios_config);
|
||||
expect(res.status).toEqual(400);
|
||||
});
|
||||
it('Post with auth but invalid mail should return 400', async () => {
|
||||
const res = await axios.post(base + '/registration_forgot?key=' + config.api_key, { selfserviceToken: "test", address: "testdev.l.de" }, axios_config);
|
||||
expect(res.status).toEqual(400);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /reset with auth and vaild body', () => {
|
||||
it('Post with auth, body and no locale should return 200', async () => {
|
||||
const res = await axios.post(base + '/registration_forgot?key=' + config.api_key, {
|
||||
selfserviceToken: "test",
|
||||
address: "test@dev.lauf-fuer-kaya.de"
|
||||
}, axios_config);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "en",
|
||||
type: "RUNNER_FORGOT"
|
||||
})
|
||||
});
|
||||
it('Post with auth, body and locale=en should return 200', async () => {
|
||||
const res = await axios.post(base + '/registration_forgot?locale=en&key=' + config.api_key, {
|
||||
selfserviceToken: "test",
|
||||
address: "test@dev.lauf-fuer-kaya.de"
|
||||
}, axios_config);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "en",
|
||||
type: "RUNNER_FORGOT"
|
||||
})
|
||||
});
|
||||
it('Post with auth, body and locale=de should return 200', async () => {
|
||||
const res = await axios.post(base + '/registration_forgot?locale=de&key=' + config.api_key, {
|
||||
selfserviceToken: "test",
|
||||
address: "test@dev.lauf-fuer-kaya.de"
|
||||
}, axios_config);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "de",
|
||||
type: "RUNNER_FORGOT"
|
||||
})
|
||||
});
|
||||
});
|
||||
@@ -1,75 +0,0 @@
|
||||
import axios from 'axios';
|
||||
import { config } from '../config';
|
||||
const base = "http://localhost:" + config.internal_port
|
||||
|
||||
const axios_config = {
|
||||
validateStatus: undefined
|
||||
};
|
||||
|
||||
describe('POST /registration without auth', () => {
|
||||
it('Post without auth should return 401', async () => {
|
||||
const res = await axios.post(base + '/registration', null, axios_config);
|
||||
expect(res.status).toEqual(401);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /registration with auth but wrong body', () => {
|
||||
it('Post with auth but no body should return 400', async () => {
|
||||
const res = await axios.post(base + '/registration?key=' + config.api_key, null, axios_config);
|
||||
expect(res.status).toEqual(400);
|
||||
});
|
||||
it('Post with auth but no mail should return 400', async () => {
|
||||
const res = await axios.post(base + '/registration?key=' + config.api_key, { selfserviceToken: "test" }, axios_config);
|
||||
expect(res.status).toEqual(400);
|
||||
});
|
||||
it('Post with auth but no reset key should return 400', async () => {
|
||||
const res = await axios.post(base + '/registration?key=' + config.api_key, { address: "test@dev.lauf-fuer-kaya.de" }, axios_config);
|
||||
expect(res.status).toEqual(400);
|
||||
});
|
||||
it('Post with auth but invalid mail should return 400', async () => {
|
||||
const res = await axios.post(base + '/registration?key=' + config.api_key, { selfserviceToken: "test", address: "testdev.l.de" }, axios_config);
|
||||
expect(res.status).toEqual(400);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /reset with auth and vaild body', () => {
|
||||
it('Post with auth, body and no locale should return 200', async () => {
|
||||
const res = await axios.post(base + '/registration?key=' + config.api_key, {
|
||||
selfserviceToken: "test",
|
||||
address: "test@dev.lauf-fuer-kaya.de"
|
||||
}, axios_config);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "en",
|
||||
type: "RUNNER_WELCOME"
|
||||
})
|
||||
});
|
||||
it('Post with auth, body and locale=en should return 200', async () => {
|
||||
const res = await axios.post(base + '/registration?locale=en&key=' + config.api_key, {
|
||||
selfserviceToken: "test",
|
||||
address: "test@dev.lauf-fuer-kaya.de"
|
||||
}, axios_config);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "en",
|
||||
type: "RUNNER_WELCOME"
|
||||
})
|
||||
});
|
||||
it('Post with auth, body and locale=de should return 200', async () => {
|
||||
const res = await axios.post(base + '/registration?locale=de&key=' + config.api_key, {
|
||||
selfserviceToken: "test",
|
||||
address: "test@dev.lauf-fuer-kaya.de"
|
||||
}, axios_config);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "de",
|
||||
type: "RUNNER_WELCOME"
|
||||
})
|
||||
});
|
||||
});
|
||||
@@ -1,47 +0,0 @@
|
||||
import axios from 'axios';
|
||||
import { config } from '../config';
|
||||
const base = "http://localhost:" + config.internal_port
|
||||
|
||||
const axios_config = {
|
||||
validateStatus: undefined
|
||||
};
|
||||
|
||||
describe('POST /test without auth', () => {
|
||||
it('Post without auth should return 401', async () => {
|
||||
const res = await axios.post(base + '/test', null, axios_config);
|
||||
expect(res.status).toEqual(401);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /test with auth', () => {
|
||||
it('Post with auth and no locale should return 200', async () => {
|
||||
const res = await axios.post(base + '/test?key=' + config.api_key, null, axios_config);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "en",
|
||||
type: "TEST"
|
||||
})
|
||||
});
|
||||
it('Post with auth and locale=en should return 200', async () => {
|
||||
const res = await axios.post(base + '/test?locale=en&key=' + config.api_key, null, axios_config);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "en",
|
||||
type: "TEST"
|
||||
})
|
||||
});
|
||||
it('Post with auth and locale=de should return 200', async () => {
|
||||
const res = await axios.post(base + '/test?locale=de&key=' + config.api_key, null, axios_config);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.data).toEqual({
|
||||
success: true,
|
||||
message: "Sent!",
|
||||
locale: "de",
|
||||
type: "TEST"
|
||||
})
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,6 @@
|
||||
export type Language = 'en' | 'de'
|
||||
|
||||
export interface EmailTemplate {
|
||||
html: (data: any) => string
|
||||
text: (data: any) => string
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist",
|
||||
"esModuleInterop": true,
|
||||
"strict": false,
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"sourceMap": false
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user