diff --git a/Dockerfile b/Dockerfile
index c1c3cfa..9f87418 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,6 +6,12 @@ FROM node:16-alpine AS frontend-builder
# 设置工作目录
WORKDIR /app/Open-OAuth2Playground
+# 设置 npm 的超时时间 (ms)
+# ENV npm_config_timeout=5*60*1000
+
+# 设置 npm proxy
+RUN npm config set registry https://registry.npmmirror.com/
+
# 复制前端项目并构建
COPY ./front-standalone /app/Open-OAuth2Playground/front-standalone
RUN cd front-standalone && npm install && npm run build
diff --git a/README.md b/README.md
index bb6bd75..e888fd2 100644
--- a/README.md
+++ b/README.md
@@ -47,7 +47,7 @@ Open-OAuth2Playground 是一个仿 Google [OAuth 2.0 Playground](https://develop
本项目提供 docker 一键部署、手动源码编译运行、二进制文件一键运行和二进制文件托管运行 4 种方式。
-docker 运行方式 #TODO
+docker 运行方式
源码编译、二进制文件运行均依赖于 `Open-OAuth2Playground` 二进制文件和 `cfg` 配置文件。默认读取二进制文件平级目录的 `cfg.json` 文件作为配置文件,支持通过 `-c /path/to/cfg` 运行时传参的方式指定特定的 `cfg` 配置文件(systemctl 托管运行时需要自行修改 service 文件)。
@@ -55,7 +55,9 @@ docker 运行方式 #TODO
(内置用于测试的 [oauth-server-lite](https://github.com/shanghai-edu/oauth-server-lite/) 服务)
-项目提供 `docker-compose.yaml` 文件,可直接一键拉起。
+项目提供 `docker-compose.yaml` 文件,可直接一键拉起。`docker-compose.yaml` 提供了一种基于容器模式启动的方案。此方案可共享 `redis` 和 `oauth-server-lite` 的容器网络,仅供测试使用。
+
+![docker 容器模式下 oauth2playground 结构图](imgs/docker-container.svg)
```shell
docker-compose -p oauth-server-lite up -d
@@ -65,26 +67,15 @@ docker-compose -p oauth-server-lite up -d
- 此方式启动时,由于容器内无法直接通过 `localhost` 访问其它服务,因此需要通过访问 service name 的方式 ( `redis:6379` ) 连接 redis 。其它配置见文件。
- `cas.db` 默认写入用户信息:
- - `username: cas`,可通过配置 `${CAS_USERNAME}` 修改
- - `password: 123456`,可通过配置 `${CAS_PASSWORD}` 修改
+ - `username`: `cas`,可通过配置 `${CAS_USERNAME}` 修改
+ - `password`: `123456`,可通过配置 `${CAS_PASSWORD}` 修改
- `sqlite.db` 默认写入 oauth client 信息:
- - `client_id: oauth`,可通过配置 `${OAUTH_CLIENT_ID}` 修改
- - `client_secret: 123456`,可通过配置 `${OAUTH_CLIENT_SECRET}` 修改
- - `domains: open-oauth2playground`,可通过配置 `${PLAYGROUND_HOST}` 修改
- - `grant_types: authorization_code,client_credentials,device_flow`,
-
-[//]: # (todo:这部分要修改)
-- **cas的service**
- - authorization_code | client_credentials | device_flow模式:
- ```txt
- client_id:open-oauth2playground
- password:open-oauth2playground
- ```
- - pkce模式:
- ```txt
- client_id:open-oauth2playground-pkce
- ```
-可在Open-OAuth2Playground/apereo-cas/etc/services目录下自行添加新的service
+ - `client_id`: `oauth`,可通过配置 `${OAUTH_CLIENT_ID}` 修改
+ - `client_secret`: `123456`,可通过配置 `${OAUTH_CLIENT_SECRET}` 修改
+ - `domains`: `open-oauth2playground`,可通过配置 `${PLAYGROUND_HOST}` 修改
+ - `grant_types`: `password`,`authorization_code`,`urn:ietf:params:oauth:grant-type:device_code`,`client_credentials`
+
+- 可在 `Open-OAuth2Playground/apereo-cas/etc/services` 目录下自行添加新的service
### 方式二、源码编译运行
@@ -378,16 +369,68 @@ VUE_APP_API_VERSION=v1
## 使用
+**[Reference 1]** [RFC6749](https://www.rfc-editor.org/rfc/rfc6749.html)
+
+首先需要进入 `Open-OAuth2Playground` 前端首页,在右上角 `Configuration Settings` 完成信息配置:
+
+![客户端配置](imgs/configuration.png)
+
### 一、Authorization Code 模式
+Authorization Code 模式也被称作授权码模式。步骤如下:
+
+1. 访问 APP 服务,即点击 GO 图标,这时客户端将用户导向认证服务器 (Authorization Server),即 `apereo-cas` server ;
+2. 用户(登录后)选择是否授权;
+3. 授权后,认证服务器将用户导向重定向 URI,同时返回授权码,即 Step 2 中的 `Authorization Code`;
+4. 通过该授权码,用户可以获得访问令牌 (Token) 和刷新访问令牌。之后就可以携带访问令牌访问资源服务器了,即 Step 3 。
+
+![授权码模式](imgs/authorization-code-mode.png)
+
### 二、Resource Owner Password Credentials 模式
+Resource Owner Password Credentials 模式也被称作密码模式,步骤如下:
+
+1. 访问 APP 服务,并向客户端提供用户名和密码,然后点击 Get Token ;
+2. 得到访问令牌,即可访问资源服务器。
+
+![密码模式](/imgs/password.png)
+
### 三、Client Credentials 模式
+Client Credentials 模式也被称作客户端模式。步骤如下:
+
+1. 客户端直接向认证服务器进行身份认证,并要求一个访问令牌(无需用户信息);
+2. 认证服务器向客户端提供访问令牌,用户使用此令牌访问资源服务器。
+
+![客户端模式](/imgs/client.png)
+
+客户端模式下认证行为是客户端发出的。由于不存在用户信息的绑定,可以看到,虽然请求成功,但用户是无法获得到和个人信息相关的内容的。
+
### 四、Device Flow 模式
+Device Flow 模式也被称作设备流模式。步骤如下:
+
+1. 访问 APP 服务,即点击 GO 图标,客户端会提供一个用户验证码 (User Code) 。这时客户端会将验证码发送给认证服务器,并监听认证服务器的状态;
+![设备流模式-1](imgs/device-flow-1.png)
+2. 用户可通过扫码或通过认证链接(可以是不同设备)进入认证页面,在有效时间内通过输入验证码完成认证;
+![设备流模式-2](imgs/device-flow-2.png)
+3. 认证成功后,可返回客户端,这时客户端成功监听到用户完成认证并获取访问令牌;
+![设备流模式-3](imgs/device-flow-3.png)
+![设备流模式-4](imgs/device-flow-4.png)
+4. 用户可通过该访问令牌访问资源服务器。
+![设备流模式-5](imgs/device-flow-5.png)
+
### 五、PKCE 模式
+PKCE (Proof Key for Code Exchange) 模式是一种更安全的授权码模式。步骤如下:
+
+1. 客户端生成一个随机的 `code verifier` (点击 Refresh) ,并通过 `code challenge method` (如 SHA256) 得到 `code challenge`;
+2. 用户同样通过认证服务器授权(点击 GO,并在认证服务器完成认证,由认证服务器重定向回客户端),得到授权码;
+3. 与授权码模式不同,PKCE 授权码模式获取访问令牌需要携带 `code verifier` 进行认证,以防止授权码拦截攻击;
+4. 获得访问令牌后,即可访问资源服务器。
+
+![PKCE 授权码模式](imgs/pkce.png)
+
## 鸣谢
本项目受 Google 的 [OAuth 2.0 Playground](https://developers.google.com/oauthplayground/) 启发
diff --git a/README_en.md b/README_en.md
index 53c11dd..5bb6bc0 100644
--- a/README_en.md
+++ b/README_en.md
@@ -1,250 +1,340 @@
# Open-OAuth2Playground
-Open-OAuth2Playground is an open source version of OAuth2.0 Playground that mimics Google’s OAuth 2.0 Playground
-It supports local out-of-the-box use, suitable for OAuth2.0 learners to test and learn the OAuth2.0 protocol.
+[English](./README_en.md) | [中文](./README.md)
-When used for server-side deployment, it is also very suitable for synchronizing with the OAuth2 Server documentation, making it easy for third-party callers to quickly develop and debug.
+**[Project Introduction]**
-[English](./README_en.md) | [中文](./README.md)
+Open-OAuth2Playground is an open-source version of OAuth2.0 Playground, modeled after Google's [OAuth 2.0 Playground](https://developers.google.com/oauthplayground/).
+
+This project supports out-of-the-box local use, making it suitable for learners to test and learn the OAuth2.0 protocol.
+
+When deployed on the server side, it is also ideal for synchronizing with OAuth2 interface documentation, facilitating rapid development and debugging for third-party callers.
+
+**Note:** This project relies on the [oauth-server-lite](https://github.com/shanghai-edu/oauth-server-lite/) service (or prepare your own / configure the authorization service backend and modify `cfg.json`), and you need to start oauth-server-lite before use. If you wish to use this project for testing and learning, it is recommended to use [Method Four: Docker Operation](#Method-Four-Docker-Operation) to quickly set up a complete set of front-end and back-end services for OAuth2 authorization and testing.
-![](https://github.com/ECNU/Open-OAuth2Playground/blob/main/demo.png?raw=true)
+![Open-OAuth2Playground](imgs/demo.png)
+
+**[Table of Contents]**
- [Open-OAuth2Playground](#open-oauth2playground)
- - [Installation and Running](#installation-and-running)
- - [Binary Direct Running](#binary-direct-running)
- - [Linux](#linux)
- - [Windows](#windows)
- - [Systemctl Hosting](#systemctl-hosting)
- - [Compilation and Packaging](#compilation-and-packaging)
- - [Backend Compilation](#backend-compilation)
- - [Frontend Compilation](#frontend-compilation)
- - [Unified Packaging](#unified-packaging)
- - [Running via Docker](#running-via-docker)
- - [Configuration](#configuration)
- - [Backend Configuration](#backend-configuration)
- - [Backend Configuration Description](#backend-configuration-description)
- - [Frontend Configuration](#frontend-configuration)
- - [Frontend Configuration Description](#frontend-configuration-description)
- - [Frontend Deployment](#frontend-deployment)
- - [Customize Frontend Menu](#customize-frontend-menu)
- - [API](#api)
- - [Acknowledgements](#acknowledgements)
-
-## Installation and Running
-
-### Binary Direct Running
-#### Linux
-Download the latest [release] package from [release](https://github.com/ECNU/Open-OAuth2Playground/releases), unzip it and run it directly.
+ - [Installation and Operation](#installation-and-operation)
+ - [Method One: Docker One-click Deployment and Operation](#Method-One-Docker-One-click-Deployment-and-Operation)
+ - [Method Two: Source Code Compilation and Operation](#Method-Two-Source-Code-Compilation-and-Operation)
+ - [1. Obtain the Project Source Code](#1-Obtain-the-Project-Source-Code)
+ - [2. Modify the Configuration File](#2-Modify-the-Configuration-File)
+ - [3. Front-end Compilation](#3-Front-end-Compilation)
+ - [4. Back-end Compilation](#4-Back-end-Compilation)
+ - [5. Operation](#5-Operation)
+ - [Unified Packaging](#Unified-Packaging)
+ - [Method Three: Binary Package - Unzip and Run Directly](#Method-Three-Binary-Package---Unzip-and-Run-Directly)
+ - [Linux](#Linux)
+ - [Windows](#Windows)
+ - [Method Four: Binary Package - Systemctl Hosted Operation](#Method-Four-Binary-Package---Systemctl-Hosted-Operation)
+ - [Configuration](#configuration)
+ - [I. Backend Configuration](#I-Backend-Configuration)
+ - [Backend Configuration Description](#Backend-Configuration-Description)
+ - [II. Frontend Configuration](#II-Frontend-Configuration)
+ - [Frontend Configuration Description](#Frontend-Configuration-Description)
+ - [III. Frontend Project Independent Deployment](#III-Frontend-Project-Independent-Deployment)
+ - [Customized Frontend Menu](#Customized-Frontend-Menu)
+ - [Usage](#usage)
+ - [Acknowledgements](#acknowledgements)
-```
-mkdir Open-OAuth2Playground
-cd Open-OAuth2Playground/
-wget https://github.com/ECNU/Open-OAuth2Playground/releases/download/v0.2.0/Open-OAuth2Playground-linux-0.2.0.tar.gz
-tar -zxvf Open-OAuth2Playground-linux-0.2.0.tar.gz
-./control start
-```
-Visit port 80 of your server to use it.
+---
-#### Windows
-If you only need to run tests on Windows, you can download `Open-OAuth2Playground-windows-0.2.0.zip` from [release], unzip it and run `Open-OAuth2Playground.exe`.
+## Installation and Operation
-### Systemctl Hosting
-Assuming deployment in the `/opt/Open-OAuth2Playground` directory, if deployed in other directories, modify the `WorkingDirectory` and `ExecStart` fields in `playground.service`.
-```
-cp playground.service /etc/systemd/system/
-systemctl daemon-reload
-systemctl enable playground
-systemctl start playground
-```
+This project provides four methods: Docker one-click deployment, manual source code compilation and operation, binary file one-click operation, and binary file hosted operation with systemctl.
+
+Docker operation method #TODO
+
+Both source code compilation and binary file operation depend on the `Open-OAuth2Playground` binary file and `cfg` configuration file. The default reads the `cfg.json` file in the same directory as the binary file as the configuration file, and supports specifying a specific `cfg` configuration file at runtime through the `-c /path/to/cfg` parameter (you need to modify the service file yourself when running with systemctl).
+
+### Method One: Docker One-click Deployment and Operation
+
+(Built-in [oauth-server-lite](https://github.com/shanghai-edu/oauth-server-lite/) service for testing)
+
+The project provides a `docker-compose.yaml` file, which can be started with one click. `docker-compose.yaml` provides a container-based startup solution. This solution allows for a shared `redis` and `oauth-server-lite` container network, for testing purposes only.
-### Compilation and Packaging
-Get the project source code
+![Docker container mode oauth2playground structure chart](imgs/docker-container.svg)
+
+```shell
+docker-compose -p oauth-server-lite up -d
```
+
+**Notes**
+
+- When starting in this way, since containers cannot directly access other services via `localhost`, you need to connect to redis via the service name (e.g., `redis:6379`). See the file for other configurations.
+- `cas.db` writes default user information:
+ - `username`: `cas`, can be modified via `${CAS_USERNAME}`
+ - `password`: `123456`, can be modified via `${CAS_PASSWORD}`
+- `sqlite.db` writes default oauth client information:
+ - `client_id`: `oauth`, can be modified via `${OAUTH_CLIENT_ID}`
+ - `client_secret`: `123456`, can be modified via `${OAUTH_CLIENT_SECRET}`
+ - `domains`: `open-oauth2playground`, can be modified via `${PLAYGROUND_HOST}`
+ - `grant_types`: `password`,`authorization_code`,`urn:ietf:params:oauth:grant-type:device_code`,`client_credentials`
+
+- You can add new services in the `Open-OAuth2Playground/apereo-cas/etc/services` directory as needed.
+
+### Method Two: Source Code Compilation and Operation
+
+This method is aimed at developers / advanced users who have secondary development / customization needs.
+
+This method requires you to first complete the modification of the configuration file `cfg.json`, and then proceed with [3 Front-end Compilation](#3-Front-end-Compilation) and [4 Back-end Compilation](#4-Back-end-Compilation) in sequence.
+
+#### Prerequisites:
+
+- go >= 1.20.0
+- pnpm (npm && node ^12.0.0 || >= 14.0.0)
+
+#### 1. Obtain the Project Source Code
+
+```shell
git clone https://github.com/ECNU/Open-OAuth2Playground.git
```
-#### Backend Compilation
-```
-cd Open-OAuth2Playground/
-go mod tidy
-go build
-```
-#### Frontend Compilation
+
+#### 2. Modify the Configuration File
+
+Refer to `cfg.json.example` to modify the configuration file.
+
+```shell
+cd Open-OAuth2Playground
+cp cfg.json.example cfg.json
+# vim cfg.json ## Modify the configuration file
```
+
+#### 3. Front-end Compilation
+
+```shell
cd front-standalone/
+# Ensure you are in the Open-OAuth2Playground/front-standalone directory
pnpm install
pnpm build
```
-#### Unified Packaging
-```
-cd ..
-chmod +x control
-./control pack
-```
-### Running via Docker
-(Built-in oauth2 server for testing)
+Compilation success result:
+
+```shell
+...
+
+ Build at: 2024-10-31T03:41:50.137Z - Hash: fa1d180a37fe6b83 - Time: 32612ms
+
+ DONE Build complete. The dist directory is ready to be deployed.
+ INFO Check out deployment instructions at https://cli.vuejs.org/guide/deployment.html
+ ```
+
+At this point, a `dist` directory will be compiled under `front-standalone`.
-#### 1. Grant execute permission to the `cas_init_script.sh` file
+#### 4. Back-end Compilation
-Execute the following command
```shell
-chmod +x cas_init_script.sh
+cd ..
+# Ensure you are in the Open-OAuth2Playground root directory
+go mod tidy
+go build
```
-#### 2. Modify the `docker-compose.yml` file
+After successful compilation, the `Open-OAuth2Playground` binary file will be compiled in the root directory.
-##### 2.1 Setting Environment Variables
-Modify the `environment` field of the `cas-demo` container in the `docker-compose.yml` file
+#### 5. Operation
-```yaml
-environment:
- - CAS_SERVER_NAME=
- - SERVER_PORT=
+```shell
+./Open-OAuth2Playground
```
-If not set, the default is as follows
+Output:
-```yaml
-environment:
- - CAS_SERVER_NAME=http://localhost:8444
- - SERVER_PORT=8444
+```shell
+[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
+ - using env: export GIN_MODE=release
+ - using code: gin.SetMode(gin.ReleaseMode)
+
+[GIN-debug] GET /css/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (4 handlers)
+[GIN-debug] HEAD /css/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (4 handlers)
+[GIN-debug] GET /js/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (4 handlers)
+[GIN-debug] HEAD /js/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (4 handlers)
+[GIN-debug] GET / --> github.com/ECNU/Open-OAuth2Playground/controller.Routes.(*RouterGroup).StaticFile.func1 (4 handlers)
+[GIN-debug] HEAD / --> github.com/ECNU/Open-OAuth2Playground/controller.Routes.(*RouterGroup).StaticFile.func1 (4 handlers)
+[GIN-debug] GET /favicon.ico --> github.com/ECNU/Open-OAuth2Playground/controller.Routes.(*RouterGroup).StaticFile.func2 (4 handlers)
+[GIN-debug] HEAD /favicon.ico --> github.com/ECNU/Open-OAuth2Playground/controller.Routes.(*RouterGroup).StaticFile.func2 (4 handlers)
+[GIN-debug] GET /v1/config --> github.com/ECNU/Open-OAuth2Playground/controller.getConfig (4 handlers)
+[GIN-debug] POST /v1/oauth2/pkce --> github.com/ECNU/Open-OAuth2
+Playground/controller.pkce (6 handlers)
+[GIN-debug] POST /v1/oauth2/user_code --> github.com/ECNU/Open-OAuth2Playground/controller.getUserCode (6 handlers)
+[GIN-debug] POST /v1/oauth2/device_flow --> github.com/ECNU/Open-OAuth2Playground/controller.deviceFlow (6 handlers)
+[GIN-debug] POST /v1/oauth2/client_credentials --> github.com/ECNU/Open-OAuth2Playground/controller.clientCredentials (6 handlers)
+[GIN-debug] POST /v1/oauth2/password --> github.com/ECNU/Open-OAuth2Playground/controller.passwordMode (6 handlers)
+[GIN-debug] POST /v1/oauth2/authorization_code --> github.com/ECNU/Open-OAuth2Playground/controller.exchangeTokenByCode (6 handlers)
+[GIN-debug] POST /v1/oauth2/refresh_token --> github.com/ECNU/Open-OAuth2Playground/controller.refreshToken (6 handlers)
+[GIN-debug] POST /v1/api --> github.com/ECNU/Open-OAuth2Playground/controller.api (6 handlers)
```
-##### 2.2 Modify the port mapping
+The service has started normally. Visit [http://127.0.0.1:80](http://127.0.0.1:80) (default) or the `.http.listen` configured in `cfg.json` to access Open-OAuth2Playground.
-Modify the `ports` field of the container in the `docker-compose.yml` file
+#### Unified Packaging
-If `SERVER_PORT` in step 1 is not the default value of 8444, then you need to change the port of the `cas-demo` container to the value of `SERVER_PORT`, noting that the container and host ports must be the same.
+Package the compiled results into `Open-OAuth2Playground-${release}.tar.gz`:
-```yml
-# he port of the open-oauth2playground container, you can modify it on your own
-ports:
- - "8080:80"
-# The port of the cas-demo container, both need to be identical
-ports:
- - "your_port:your_port"
+```shell
+cd ..
+chmod +x control
+./control pack
```
-#### 3. Modify the `cfg.json` configuration
+If you need to add/modify the packaging content, please modify the control file.
-##### 3.1 Modify the `endpoints` field
+### Method Three: Binary Package - Unzip and Run Directly
-Set the `cas server` domain name in the `endpoints` field in the `cfg.json` file to `CAS_SERVER_NAME` from step 1, or to `http://localhost:8444` if not set in step 1
+This project provides a pre-compiled project compressed package, which can be directly downloaded and unzipped for operation.
-```json
-"endpoints": {
- "authorization": "http://localhost:8444/cas/oauth2.0/authorize",
- "token": "http://localhost:8444/cas/oauth2.0/accessToken",
- "userinfo": "http://localhost:8444/cas/oauth2.0/profile"
-}
+#### Linux
+
+Download the latest [release] package from [release](https://github.com/ECNU/Open-OAuth2Playground/releases), unzip it, and run it directly.
+
+```
+mkdir Open-OAuth2Playground
+cd Open-OAuth2Playground/
+wget https://github.com/ECNU/Open-OAuth2Playground/releases/download/v0.2.0/Open-OAuth2Playground-linux-0.2.0.tar.gz
+tar -zxvf Open-OAuth2Playground-linux-0.2.0.tar.gz
+./control start
+# ./control stop
```
+Access your server's port 80 to use it (default local access: [http://127.0.0.1:80](http://127.0.0.1:80)).
-##### 3.2 Modify the `trust_domain` field
+#### Windows
-If `CAS_SERVER_NAME` filed is `http://localhost:8444`, add `localhost:8444` to the `trust_domain` field in the `cfg.json` file, and vice versa, add the value of `CAS_SERVER_NAME` that you set.
+If you only need to run tests on Windows, you can directly download the `Open-OAuth2Playground-windows-0.2.0.zip` from [release](https://github.com/ECNU/Open-OAuth2Playground/releases), unzip it, and run `Open-OAuth2Playground.exe`.
+
+### Method Four: Binary Package - Systemctl Hosted Operation
+
+[Method Three: Binary Package - Unzip and Run Directly](#Method-Three-Binary-Package---Unzip-and-Run-Directly) can also be automatically hosted and operated with systemctl.
-```json
- "trust_domain": [
- "localhost:8444",
- ]
```
+# 1. Download and unzip the release package in /opt/Open-OAuth2Playground
+cd /opt
+mkdir Open-OAuth2Playground
+cd Open-OAuth2Playground/
+wget https://github.com/ECNU/Open-OAuth2Playground/releases/download/v0.2.0/Open-OAuth2Playground-linux-0.2.0.tar.gz
+tar -zxvf Open-OAuth2Playground-linux-0.2.0.tar.gz
-#### 4. Start the container
+# 2. Create a service file
+# Please adjust the file content according to your specific needs
-Execute the following command in the directory where `docker-compose.yml` is located
+# Method One: Directly write in
+sudo tee /etc/systemd/system/playground.service > /dev/null << 'EOF'
+[Unit]
+Description=playground
+After=network-online.target
+Wants=network-online.target
-```shell
-docker-compose up
-```
+[Service]
+# modify when deploy in prod env
+User=root
+Group=root
+
+Type=simple
+ExecStart=/opt/Open-OAuth2Playground/Open-OAuth2Playground
+WorkingDirectory=/opt/Open-OAuth2Playground
+
+Restart=always
+RestartSec=1
+StartLimitInterval=0
-If you see the word `ready` in the `cas-domo` container log, the startup was successful.
+[Install]
+WantedBy=multi-user.target
+EOF
-#### 5. Note
+# Method Two: Copy the playground.service from the compressed package to the system directory
+# cp playground.service /etc/systemd/system/playground.service
-- **cas test users are as follows:**:
-```txt
-user:cas
-password:123456
+# 3. Start playground.service
+systemctl daemon-reload
+systemctl enable playground
+systemctl start playground
```
-You can edit the `cas_init_script.sh` script to add a new user or change the username and password.
+
+At this point, the file tree structure is as follows (the `Open-OAuth2Playground` binary file and `cfg.json` configuration file must exist). If deployed in other directories, modify the `WorkingDirectory` and `ExecStart` fields in `playground.service`.
+
```shell
-INSERT INTO user (username, password, name) VALUES ('cas', '123456', '测试用户');
+[root@iZm05jcnfytljnZ Open-OAuth2Playground]# tree /opt
+/opt
+└── Open-OAuth2Playground
+ ├── cfg.json
+ ├── control
+ ├── front-standalone
+ │ ├── dist
+ │ │ ├── css
+ │ │ │ ├── ...
+ │ │ └── js
+ │ │ └── ...
+ │ └── ...
+ ├── gitversion
+ ├── logs
+ │ ├── DEBUG.log
+ │ ├── INFO.log
+ │ └── *.log
+ ├── Open-OAuth2Playground
+ └── Open-OAuth2Playground-linux-0.2.0.tar.gz
```
-Or start the `cas-demo` container and go to the /export/data/ directory, connect to the sqlite database cas.db and modify it.
-```shell
-# Enter the cas-demo container
-docker exec -it container_id /bin/bash
+## Configuration
-cd /export/data
-# Connect to the database
-sqlite3 cas.db
-```
+### I. Backend Configuration
+
+Refer to `cfg.json.example`, create a `cfg.jon` configuration file, and modify the configuration.
-- **the service of the cas**
- - authorization_code | client_credentials | device_flow mode:
- ```txt
- client_id:open-oauth2playground
- password:open-oauth2playground
- ```
- - pkce mode:
- ```txt
- client_id:open-oauth2playground-pkce
- ```
-You can add a new service yourself in the Open-OAuth2Playground/apereo-cas/etc/services directory.
-
-
-### Configuration
-#### Backend Configuration
-Refer to `cfg.json.example`, create `cfg.jon` configuration file, modify configuration as needed.
```json
{
- "logger": {
- "dir": "logs/",
- "level": "DEBUG",
- "keepHours": 24
- },
- "endpoints": {
- "authorization": "http://cas.example.org/cas/oauth2.0/authorize",
- "token": "http://cas.example.org/cas/oauth2.0/accessToken",
- "userinfo": "http://cas.example.org/cas/oauth2.0/profile"
- },
- "iplimit": {
- "enable": false,
- "trust_ip": ["127.0.0.1","::1"]
- },
- "http": {
- "route_base":"/",
- "trust_proxy": ["127.0.0.1", "::1"],
- "cors": ["http://127.0.0.1:8080","http://localhost:8080"],
- "listen": "0.0.0.0:80"
- },
- "trust_domain": ["cas.example.org", "localhost"],
- "default_scope": "Basic",
- "timeout": 10
+ "logger": {
+ "dir": "logs/",
+ "level": "DEBUG",
+ "keepHours": 24
+ },
+ "endpoints": {
+ "authorization": "http://oauth.example.org/oauth2/device/authorize",
+ "token": "http://oauth.example.org/oauth2/token",
+ "userinfo": "http://oauth.example.org/oauth2/userinfo"
+ },
+ "iplimit": {
+ "enable": false,
+ "trust_ip": ["127.0.0.1","::1"]
+ },
+ "http": {
+ "route_base":"/",
+ "trust_proxy": ["127.0.0.1", "::1"],
+ "cors": ["http://127.0.0.1:8080","http://localhost:8080"],
+ "listen": "0.0.0.0:80"
+ },
+ "trust_domain": ["oauth.example.org", "localhost"],
+ "default_scope": "Basic",
+ "timeout": 10
}
```
-##### Backend Configuration Description
-| Configuration Item | Type | Description |
-| --- | --- | --- |
-| logger.dir | string | Log folder |
-| logger.level | string | Log level |
-| logger.keepHours | int | Log retention time |
-| endpoints.authorization | string | OAuth2.0 authorization address |
-| endpoints.token | string | OAuth2.0 get token address |
-| endpoints.userinfo | string | OAuth2.0 get user information address |
-| iplimit.enable | bool | Whether to enable IP restriction |
-| iplimit.trust_ip | []string | List of trusted IP addresses |
-| http.route_base | string | Route prefix, note to match with frontend |
-| http.trust_proxy | []string | List of trusted proxy IP addresses |
-| http.cors | []string | List of domain names allowed for frontend cross-domain access |
-| http.listen | string | Listening address |
-| trust_domain | []string | List of trusted domain names when backend forwards API calls |
-| default_scope | string | Default scope |
-| timeout | int | Timeout time |
-
-#### Frontend Configuration
-Modify `.env.production`
+
+#### Backend Configuration Description
+
+| Configuration Item | Type | Description |
+|-------------------------|----------|-------------------------------------------------------------|
+| logger.dir | string | Log folder |
+| logger.level | string | Log level |
+| logger.keepHours | int | Log retention time |
+| endpoints.authorization | string | OAuth2.0 authorization address |
+| endpoints.token | string | OAuth2.0 token acquisition address |
+| endpoints.userinfo | string | OAuth2.0 user information acquisition address |
+| iplimit.enable | bool | Whether to enable IP restriction |
+| iplimit.trust_ip | []string | List of trusted IPs |
+| http.route_base | string | Route prefix, note to match with the front end |
+| http.trust_proxy | []string | List of trusted proxy IPs |
+| http.cors | []string | List of domains allowed for front-end cross-domain |
+| http.listen | string | Listening address |
+| trust_domain | []string | List of trusted domains when the backend forwards API calls |
+| default_scope | string | Default scope |
+| timeout | int | Timeout time |
+
+### II. Frontend Configuration
+
+Modify `.env.production`:
+
```ini
# Router path
VUE_APP_ROUTER_BASE=/
@@ -254,31 +344,96 @@ VUE_APP_API_HOST=localhost
VUE_APP_API_PORT=
VUE_APP_API_VERSION=v1
```
-##### Frontend Configuration Description
-| Configuration Item | Type| Description |
-| --- | --- | --- |
-| VUE_APP_ROUTER_BASE | string | Route prefix, note to match with backend |
-| VUE_APP_API_PROTO | string | Required when frontend is deployed independently, the proto of the backend server |
-| VUE_APP_API_HOST | string | Required when frontend is deployed independently, the domain name of the backend |
-| VUE_APP_API_PORT | string | Required when frontend is deployed independently, the port of the backend. If it is the default port, it can be ignored (such as https'443 or http'80) |
-| VUE_APP_API_VERSION | string | API version, currently fixed to v1 |
-##### Frontend Deployment
-The frontend part of the project can be deployed independently or published by the backend.
+#### Frontend Configuration Description
+
+| Configuration Item | Type | Description |
+|---------------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| VUE_APP_ROUTER_BASE | string | Route prefix, note to match with the backend |
+| VUE_APP_API_PROTO | string | Needed when the front end is deployed independently, the proto of the backend server |
+| VUE_APP_API_HOST | string | Needed when the front end is deployed independently, the domain name of the backend |
+| VUE_APP_API_PORT | string | Needed when the front end is deployed independently, the port of the backend. If it's the default port, it can be ignored (e.g., 443 for https or 80 for http) |
+| VUE_APP_API_VERSION | string | API version, currently fixed at v1 |
+
+### III. Frontend Project Independent Deployment
+
+The front-end part of the project can be deployed and published independently, or it can be published by the backend.
+
+By default, it is published by the backend, at which time the front-end configurations such as `VUE_APP_API_HOST`,`VUE_APP_API_PROTO`, `VUE
+_APP_API_PORT` can be ignored. At this time, the compiled and packaged front-end code should be deployed under the front-standalone/dist directory relative to the backend binary file.
+
+If the front end is deployed independently, it is necessary to configure `VUE_APP_API_HOST`,`VUE_APP_API_PROTO`, `VUE_APP_API_PORT` and other configuration items during compilation, and ensure that the domain name of the front end is within the backend's cross-domain list.
+
+#### Customized Frontend Menu
+
+The menu part of the project corresponds to the `front-standalone/src/views/Layourt.vue` file, and you can modify the content of `el-menu-item` as needed, and then compile and package.
+
+## Usage
+
+**[Reference 1]** [RFC6749](https://www.rfc-editor.org/rfc/rfc6749.html)
+
+First, you need to enter the `Open-OAuth2Playground` front-end home page, and complete the information configuration in the top right corner `Configuration Settings`:
+
+![Client Configuration](imgs/configuration.png)
+
+### I. Authorization Code Mode
+
+Authorization Code Mode is also known as the authorization code flow. The steps are as follows:
+
+1. Visit the APP service, i.e., click the GO icon, at this time the client will direct the user to the authentication server (Authorization Server), i.e., `apereo-cas` server;
+2. The user (after logging in) chooses whether to authorize;
+3. After authorization, the authentication server directs the user to the redirect URI, and returns the authorization code, i.e., the `Authorization Code` in Step 2;
+4. With this authorization code, the user can obtain an access token (Token) and a refresh access token. Then you can carry the access token to access the resource server, i.e., Step 3.
+
+![Authorization Code Flow](imgs/authorization-code-mode.png)
+
+### II. Resource Owner Password Credentials Mode
+
+Resource Owner Password Credentials Mode is also known as the password flow. The steps are as follows:
+
+1. Visit the APP service, and provide the username and password to the client, then click Get Token;
+2. Obtain the access token, and you can access the resource server.
+
+![Password Flow](/imgs/password.png)
+
+### III. Client Credentials Mode
+
+Client Credentials Mode is also known as the client flow. The steps are as follows:
+
+1. The client directly authenticates to the authentication server and requests an access token (without user information);
+2. The authentication server provides the client with an access token, which is used to access the resource server.
+
+![Client Flow](/imgs/client.png)
+
+In client flow, the authentication behavior is initiated by the client. Since there is no binding of user information, it can be seen that although the request is successful, the user cannot obtain content related to personal information.
+
+### IV. Device Flow Mode
+
+Device Flow Mode is also known as the device flow. The steps are as follows:
-By default, it is published by the backend, in which case the frontend's `VUE_APP_API_HOST`,`VUE_APP_API_PROTO`, `VUE_APP_API_PORT` and other configuration items can be ignored. At this time, the compiled and packaged frontend code should be deployed under the front-standalone/dist directory relative to the backend binary file.
+1. Visit the APP service, i.e., click the GO icon, the client will provide a user verification code (User Code). At this time, the client will send the verification code to the authentication server and listen to the status of the authentication server;
+ ![Device Flow - 1](imgs/device-flow-1.png)
+2. The user can scan the code or enter the authentication page through the authentication link (which can be a different device) and complete the authentication by entering the verification code within the valid time;
+ ![Device Flow - 2](imgs/device-flow-2.png)
+3. After successful authentication, return to the client, at this time the client successfully listens to the user completing the authentication and obtaining the access token;
+ ![Device Flow - 3](imgs/device-flow-3.png)
+ ![Device Flow - 4](imgs/device-flow-4.png)
+4. The user can access the resource server with this access token.
+ ![Device Flow - 5](imgs/device-flow-5.png)
-If the frontend is deployed independently, you need to configure `VUE_APP_API_HOST`,`VUE_APP_API_PROTO`, `VUE_APP_API_PORT` and other configuration items at compile time, and make sure that the frontend domain name is in the backend's cross-domain list.
+### V. PKCE Mode
-##### Customize Frontend Menu
+PKCE (Proof Key for Code Exchange) mode is a more secure authorization code flow. The steps are as follows:
-The menu part of the project corresponds to the `front-standalone/src/views/Layourt.vue` file, you can modify the content of `el-menu-item` as needed, and then compile and package it.
+1. The client generates a random `code verifier` (click Refresh), and obtains the `code challenge` through `code challenge method` (e.g., SHA256);
+2. The user also authorizes through the authentication server (click GO, and complete the authentication at the authentication server, redirected back to the client by the authentication server), obtaining the authorization code;
+3. Different from the authorization code flow, the PKCE authorization code flow requires the `code verifier` to be carried for authentication when obtaining the access token, to prevent interception attacks on the authorization code;
+4. After obtaining the access token, you can access the resource server.
-### API
-todo
+![PKCE Authorization Code Flow](imgs/pkce.png)
+## Acknowledgements
-### Acknowledgements
-This project was inspired by Google's [OAuth 2.0 Playground](https://developers.google.com/oauthplayground/)
+This project is inspired by Google's [OAuth 2.0 Playground](https://developers.google.com/oauthplayground/).
-Thanks to Google for providing excellent tools.
\ No newline at end of file
+Thank you to Google for providing such an excellent tool.
diff --git a/docker-build.sh b/docker-build.sh
index 0bed369..d95e796 100644
--- a/docker-build.sh
+++ b/docker-build.sh
@@ -1,7 +1,7 @@
#!/bin/bash
# 构建方式: 本地构建 or 多平台构建打包上传镜像
-BUILD_MODE="local" # local / remote
+BUILD_MODE="remote" # local / remote
# DockerHub 用户名、镜像名称和版本号
USERNAME="ecnunic"
diff --git a/docker-compose.yaml b/docker-compose.yaml
index efe3584..7ac55bf 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -19,9 +19,9 @@ services:
ports:
- "80:80" # open-oauth2playground 端口
# - "6379:6379" # redis 端口
- - "8080:8080" # apereo-cas 服务占用 1
+# - "8080:8080" # apereo-cas 后端服务占用
- "8081:8081" # oauth-server-lite 前端服务
- - "8444:8444" # apereo-cas 服务占用 2
+ - "8444:8444" # apereo-cas 前端服务占用
networks:
- open-oauth2playground
# volumes:
@@ -52,6 +52,7 @@ services:
- OAUTH_REDIS_DSN=localhost:6379 # redis 服务地址/域名
- OAUTH_REDIS_PASSWORD= # redis 服务连接密码
- PLAYGROUND_HOST=localhost # oauth2playground 服务地址/域名
+ - PLAYGROUND_PORT=80 # oauth2playground 服务端口号
depends_on:
- open-oauth2playground
- redis
diff --git a/imgs/authorization-code-mode.png b/imgs/authorization-code-mode.png
new file mode 100644
index 0000000..0be94d1
Binary files /dev/null and b/imgs/authorization-code-mode.png differ
diff --git a/imgs/client.png b/imgs/client.png
new file mode 100644
index 0000000..3293b69
Binary files /dev/null and b/imgs/client.png differ
diff --git a/imgs/configuration.png b/imgs/configuration.png
new file mode 100644
index 0000000..a1b5263
Binary files /dev/null and b/imgs/configuration.png differ
diff --git a/imgs/device-flow-1.png b/imgs/device-flow-1.png
new file mode 100644
index 0000000..5b2f78b
Binary files /dev/null and b/imgs/device-flow-1.png differ
diff --git a/imgs/device-flow-2.png b/imgs/device-flow-2.png
new file mode 100644
index 0000000..199ac95
Binary files /dev/null and b/imgs/device-flow-2.png differ
diff --git a/imgs/device-flow-3.png b/imgs/device-flow-3.png
new file mode 100644
index 0000000..70670b3
Binary files /dev/null and b/imgs/device-flow-3.png differ
diff --git a/imgs/device-flow-4.png b/imgs/device-flow-4.png
new file mode 100644
index 0000000..eca3a28
Binary files /dev/null and b/imgs/device-flow-4.png differ
diff --git a/imgs/device-flow-5.png b/imgs/device-flow-5.png
new file mode 100644
index 0000000..ada0ada
Binary files /dev/null and b/imgs/device-flow-5.png differ
diff --git a/imgs/docker-bridge.excalidraw b/imgs/docker-bridge.excalidraw
new file mode 100644
index 0000000..59cc9b1
--- /dev/null
+++ b/imgs/docker-bridge.excalidraw
@@ -0,0 +1,2947 @@
+{
+ "type": "excalidraw",
+ "version": 2,
+ "source": "https://excalidraw.com",
+ "elements": [
+ {
+ "id": "h5KVcWhtOmvNYpKKM60No",
+ "type": "rectangle",
+ "x": 549.3207291773347,
+ "y": 181.5078958439758,
+ "width": 900.1539748802556,
+ "height": 490.0548387416398,
+ "angle": 0,
+ "strokeColor": "#96f2d7",
+ "backgroundColor": "#ebfbee",
+ "fillStyle": "cross-hatch",
+ "strokeWidth": 1,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0J",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 30083886,
+ "version": 189,
+ "versionNonce": 522805486,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807835104,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "ObmMxiMvrqwEqQfrMJ6sQ",
+ "type": "rectangle",
+ "x": 431.5880371268839,
+ "y": 137.78789565102318,
+ "width": 1043.40234375,
+ "height": 536.3133713632769,
+ "angle": 0,
+ "strokeColor": "#1971c2",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0J2",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 131755879,
+ "version": 884,
+ "versionNonce": 1222058034,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792127,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "bsujuZnE0migXwc2713no",
+ "type": "text",
+ "x": 458.5704552631267,
+ "y": 157.41543921209262,
+ "width": 64.43995702266693,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0J4",
+ "roundness": null,
+ "seed": 1318096039,
+ "version": 271,
+ "versionNonce": 19417586,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792127,
+ "link": null,
+ "locked": false,
+ "text": "docker",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "docker",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "E_kwiFtlRqioM7mcOWGn7",
+ "type": "rectangle",
+ "x": 631.5706031778029,
+ "y": 404.6925929094113,
+ "width": 794.48828125,
+ "height": 190.53125000000006,
+ "angle": 0,
+ "strokeColor": "#4dabf7",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "_zNKuGHsIm4TFxrBs274F",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0JS",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 124659111,
+ "version": 1320,
+ "versionNonce": 1898855346,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "qs2K8DtoGY_SVtKXOFZd8",
+ "type": "arrow"
+ },
+ {
+ "id": "q1aFZZIw1PuMuAUysXiHL",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792127,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "zmkmfQ5WC6GG8x3SztTs6",
+ "type": "text",
+ "x": 648.2385719278029,
+ "y": 421.4621241594113,
+ "width": 164.3398675918579,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "_zNKuGHsIm4TFxrBs274F",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0JV",
+ "roundness": null,
+ "seed": 973658311,
+ "version": 919,
+ "versionNonce": 1218625778,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792127,
+ "link": null,
+ "locked": false,
+ "text": "oauth-server-lite",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "oauth-server-lite",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "GG1Q_QnP4IBvrDHJv5JtW",
+ "type": "rectangle",
+ "x": 1169.258884958465,
+ "y": 457.4894679094113,
+ "width": 212.65234375,
+ "height": 107.8046875,
+ "angle": 0,
+ "strokeColor": "#4dabf7",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "GSiHpJBWRivw6steyHsa_",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Jl",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 1728556007,
+ "version": 1311,
+ "versionNonce": 1883361970,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "_bW3I3e_Q7m3mKRCZBI8o",
+ "type": "arrow"
+ },
+ {
+ "id": "L5V1mppKIrdSJk6msfe-f",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792127,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "nwRR6E2l0L80tkAsV34Lb",
+ "type": "text",
+ "x": 1187.192478708465,
+ "y": 467.4504054094113,
+ "width": 104.7199227809906,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "GSiHpJBWRivw6steyHsa_",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Jn",
+ "roundness": null,
+ "seed": 1897371399,
+ "version": 1203,
+ "versionNonce": 2107157618,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "apereo-cas",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "apereo-cas",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "inXx_nl6tRFlsXoRqXaaB",
+ "type": "diamond",
+ "x": 1151.973728708465,
+ "y": 495.1066554094113,
+ "width": 37.703125,
+ "height": 31.58203125,
+ "angle": 0,
+ "strokeColor": "#1971c2",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "GSiHpJBWRivw6steyHsa_",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Jp",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 71114279,
+ "version": 1430,
+ "versionNonce": 1986940466,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "L5V1mppKIrdSJk6msfe-f",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "mW59uMx6695nqaCRdPEH_",
+ "type": "text",
+ "x": 1196.6503089289258,
+ "y": 504.6847804094113,
+ "width": 28.916445314884186,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "GSiHpJBWRivw6steyHsa_",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Jr",
+ "roundness": null,
+ "seed": 593805639,
+ "version": 1262,
+ "versionNonce": 262780914,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8444",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8444",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "WwTuoNAipiAjIBt7222yk",
+ "type": "text",
+ "x": 1114.0514874975274,
+ "y": 505.61777688845,
+ "width": 28.916445314884186,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "GSiHpJBWRivw6steyHsa_",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Jt",
+ "roundness": null,
+ "seed": 1072365671,
+ "version": 1294,
+ "versionNonce": 1230105010,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8444",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8444",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "bb7GorAvbKtx_-8YuYxe5",
+ "type": "text",
+ "x": 1196.8823590795587,
+ "y": 530.46543313845,
+ "width": 35.18228149414062,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "GSiHpJBWRivw6steyHsa_",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Jv",
+ "roundness": null,
+ "seed": 824874855,
+ "version": 1354,
+ "versionNonce": 177070962,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8080",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8080",
+ "autoResize": false,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "z8s43ybhnVYowCLBYluKP",
+ "type": "ellipse",
+ "x": 1274.0126081029962,
+ "y": 496.8996241594113,
+ "width": 90.5156250000001,
+ "height": 49,
+ "angle": 0,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "GSiHpJBWRivw6steyHsa_",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Jx",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1523587593,
+ "version": 1174,
+ "versionNonce": 1034200370,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "ewS8OZxi2jCNFxW0Rg8NC"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "ewS8OZxi2jCNFxW0Rg8NC",
+ "type": "text",
+ "x": 1292.6783292311502,
+ "y": 509.07550802034086,
+ "width": 53.179970502853394,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "GSiHpJBWRivw6steyHsa_",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0K",
+ "roundness": null,
+ "seed": 1753316135,
+ "version": 1197,
+ "versionNonce": 1811754738,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "sqlite",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "z8s43ybhnVYowCLBYluKP",
+ "originalText": "sqlite",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "LldGF3VFnMGbIVWxs5sKJ",
+ "type": "rectangle",
+ "x": 802.9756821952803,
+ "y": 458.4855616594113,
+ "width": 212.65234375,
+ "height": 107.8046875,
+ "angle": 0,
+ "strokeColor": "#4dabf7",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "lnPcJGNQb2eYI4W12C_oS",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0K4",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 1209120807,
+ "version": 1408,
+ "versionNonce": 1511948466,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "_bW3I3e_Q7m3mKRCZBI8o",
+ "type": "arrow"
+ },
+ {
+ "id": "L5V1mppKIrdSJk6msfe-f",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "VzkuuI7BQtpMXa1zfZ5dB",
+ "type": "text",
+ "x": 820.9092759452803,
+ "y": 468.4464991594113,
+ "width": 125.17991733551025,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "lnPcJGNQb2eYI4W12C_oS",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0K8",
+ "roundness": null,
+ "seed": 1972771655,
+ "version": 1306,
+ "versionNonce": 1467448370,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "oauth-server",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "oauth-server",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "ccF7TixQDB3FfDe5IvARw",
+ "type": "diamond",
+ "x": 785.6905259452803,
+ "y": 496.1027491594113,
+ "width": 37.703125,
+ "height": 31.58203125,
+ "angle": 0,
+ "strokeColor": "#1971c2",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "lnPcJGNQb2eYI4W12C_oS",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0KC",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 920722023,
+ "version": 1518,
+ "versionNonce": 324871666,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "KfO_O2QwVBws84bDpv4CN",
+ "type": "text",
+ "x": 830.3671061657412,
+ "y": 505.6808741594113,
+ "width": 28.916445314884186,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "lnPcJGNQb2eYI4W12C_oS",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0KG",
+ "roundness": null,
+ "seed": 280966535,
+ "version": 1358,
+ "versionNonce": 543659954,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8081",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8081",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "fk7gB889rOUWao856kpV0",
+ "type": "text",
+ "x": 747.7682847343428,
+ "y": 506.6138706384499,
+ "width": 28.916445314884186,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "lnPcJGNQb2eYI4W12C_oS",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0KK",
+ "roundness": null,
+ "seed": 980216999,
+ "version": 1388,
+ "versionNonce": 247320946,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8081",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8081",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "PN42MKgOMT4Ur1EtXQQOR",
+ "type": "ellipse",
+ "x": 907.7294053398116,
+ "y": 497.8957179094113,
+ "width": 90.5156250000001,
+ "height": 49,
+ "angle": 0,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "lnPcJGNQb2eYI4W12C_oS",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0KO",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1113140967,
+ "version": 1265,
+ "versionNonce": 1369887538,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "R-KPOeSjlspWzmpwW9fJ8"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "R-KPOeSjlspWzmpwW9fJ8",
+ "type": "text",
+ "x": 926.3951264679656,
+ "y": 510.07160177034086,
+ "width": 53.179970502853394,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "lnPcJGNQb2eYI4W12C_oS",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0KV",
+ "roundness": null,
+ "seed": 222345735,
+ "version": 1288,
+ "versionNonce": 1535745266,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "sqlite",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "PN42MKgOMT4Ur1EtXQQOR",
+ "originalText": "sqlite",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "_bW3I3e_Q7m3mKRCZBI8o",
+ "type": "arrow",
+ "x": 1022.0238924288878,
+ "y": 484.6127428300213,
+ "width": 147.5639217630777,
+ "height": 2.4865772264720363,
+ "angle": 0,
+ "strokeColor": "#343a40",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0KZ",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1469378727,
+ "version": 1326,
+ "versionNonce": 971845298,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 147.5639217630777,
+ 2.4865772264720363
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": "triangle",
+ "elbowed": false
+ },
+ {
+ "id": "ggK_2ImyH3jtFh6pCANZu",
+ "type": "text",
+ "x": 1034.1827063675596,
+ "y": 459.34953260345884,
+ "width": 110.6526780128479,
+ "height": 17.946257665140756,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Kd",
+ "roundness": null,
+ "seed": 1268840775,
+ "version": 700,
+ "versionNonce": 829982834,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "localhost:8444",
+ "fontSize": 14.357006132112604,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "localhost:8444",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "L5V1mppKIrdSJk6msfe-f",
+ "type": "arrow",
+ "x": 1165.0457202313733,
+ "y": 537.355677580558,
+ "width": 145.86318989156166,
+ "height": 0.9621084825225807,
+ "angle": 0,
+ "strokeColor": "#343a40",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Kh",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 841772615,
+ "version": 1432,
+ "versionNonce": 1312535086,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792168,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -145.86318989156166,
+ -0.9621084825225807
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": {
+ "elementId": "XiFp3cXXT0qge0XUWZfyk",
+ "focus": 2.0717902039550897,
+ "gap": 9.906441890812914,
+ "fixedPoint": null
+ },
+ "endBinding": {
+ "elementId": "LldGF3VFnMGbIVWxs5sKJ",
+ "focus": 0.42636137261614887,
+ "gap": 3.55450439453125,
+ "fixedPoint": null
+ },
+ "startArrowhead": null,
+ "endArrowhead": "triangle",
+ "elbowed": false
+ },
+ {
+ "id": "XiFp3cXXT0qge0XUWZfyk",
+ "type": "text",
+ "x": 1048.270580168079,
+ "y": 547.2621194713709,
+ "width": 110.04400797958446,
+ "height": 17.84278794067754,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Kl",
+ "roundness": null,
+ "seed": 2079863177,
+ "version": 681,
+ "versionNonce": 977441778,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "L5V1mppKIrdSJk6msfe-f",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "localhost:8081",
+ "fontSize": 14.27423035254203,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "localhost:8081",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "Eu7lMmWPEDEMeLReUHiqz",
+ "type": "diamond",
+ "x": 590.1373038954857,
+ "y": 659.5457460474637,
+ "width": 37.703125,
+ "height": 31.58203125,
+ "angle": 4.71238898038469,
+ "strokeColor": "#1971c2",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "4Q1XhLVCxUYTovc1t9DG2",
+ "o54l8ZnsIYvKH9rZEUCcP",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0LG",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1246592839,
+ "version": 1488,
+ "versionNonce": 295681906,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "LK9fNXPkTb8OWsSilsbAz",
+ "type": "text",
+ "x": 601.772878236306,
+ "y": 632.1724108360452,
+ "width": 14.431976318359375,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "sWC3N1DmftEYJp8dFHxUX",
+ "o54l8ZnsIYvKH9rZEUCcP",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0LO",
+ "roundness": null,
+ "seed": 830780713,
+ "version": 1314,
+ "versionNonce": 1041957170,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "80",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "80",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "FCd2vAM-KTdg0-sEwbW6p",
+ "type": "text",
+ "x": 601.772878236306,
+ "y": 702.9358026974713,
+ "width": 14.431976318359375,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "Sbt68FEHPrEhw2RF1Iqxy",
+ "o54l8ZnsIYvKH9rZEUCcP",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0LV",
+ "roundness": null,
+ "seed": 677189255,
+ "version": 1359,
+ "versionNonce": 1162349298,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "V6V11BvSn6bnT9jAg9c16",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "80",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "80",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "5KJCWBp2SqKvred-CgSm7",
+ "type": "diamond",
+ "x": 817.8463120517267,
+ "y": 660.4638978031068,
+ "width": 37.703125,
+ "height": 31.58203125,
+ "angle": 1.5707963267948966,
+ "strokeColor": "#1971c2",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "LWFmWXILANksJE28M4Rjg",
+ "C1wWuGiRK_6ZnbiwfK0Vt",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Ld",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 519127335,
+ "version": 1626,
+ "versionNonce": 1425241714,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "0mYPKco6DCUkwjZ9lZesj",
+ "type": "text",
+ "x": 822.2396518942846,
+ "y": 633.0905625916881,
+ "width": 28.916445314884186,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "aQXOS3o3FxLGtnKRdWBvM",
+ "C1wWuGiRK_6ZnbiwfK0Vt",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Ll",
+ "roundness": null,
+ "seed": 966558791,
+ "version": 1457,
+ "versionNonce": 1809831986,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8081",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8081",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "uPM4VovVOcTJr3YN82ZRE",
+ "type": "text",
+ "x": 822.2396518942846,
+ "y": 703.7398245664114,
+ "width": 28.916445314884186,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "TxKvmto1F4z4LRrbFox_A",
+ "C1wWuGiRK_6ZnbiwfK0Vt",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0M",
+ "roundness": null,
+ "seed": 1613914983,
+ "version": 1528,
+ "versionNonce": 844759538,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "zOfBHikVIsY0-pNT3O7AH",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8081",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8081",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "bcpbTFfJwt7lwwwgoHnAj",
+ "type": "diamond",
+ "x": 1045.5553202079673,
+ "y": 657.5683121291735,
+ "width": 37.703125,
+ "height": 31.58203125,
+ "angle": 1.5707963267948966,
+ "strokeColor": "#1971c2",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "dumEUFb2CY65s2tmjAXmq",
+ "rbFlF-hORygtq2JcjYcpZ",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0MG",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1216220969,
+ "version": 1669,
+ "versionNonce": 1093905778,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "l1EQaaqrR0GL0f-QmK-IU",
+ "type": "text",
+ "x": 1049.9486600505252,
+ "y": 630.1949769177548,
+ "width": 28.916445314884186,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "-IFkvIjdUPn1ryljMGgFU",
+ "rbFlF-hORygtq2JcjYcpZ",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0MV",
+ "roundness": null,
+ "seed": 170148361,
+ "version": 1504,
+ "versionNonce": 1895903026,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8444",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8444",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "2d-VsKbtwPr327OOSDsFQ",
+ "type": "text",
+ "x": 1049.9486600505252,
+ "y": 700.8442388924781,
+ "width": 28.916445314884186,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "tSsGD-4Vp01m0OkPH4BZR",
+ "rbFlF-hORygtq2JcjYcpZ",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Ml",
+ "roundness": null,
+ "seed": 1648433385,
+ "version": 1577,
+ "versionNonce": 1463318770,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "pCeFUAgzFQjeJDrWK_lHg",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8444",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8444",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "PpXJYR6C7EKu_ECiCDBTl",
+ "type": "diamond",
+ "x": 1273.1501984775055,
+ "y": 657.4284109777308,
+ "width": 37.703125,
+ "height": 31.58203125,
+ "angle": 1.5707963267948966,
+ "strokeColor": "#1971c2",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "RQZ7XU57WduOuW4jmvOGo",
+ "fhJJTPmf8EllHlHVZIfN_",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0N",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 632058791,
+ "version": 1839,
+ "versionNonce": 1008755826,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "GkxhQSjSHBKwLnIGNpdqx",
+ "type": "text",
+ "x": 1277.5435383200634,
+ "y": 630.0550757663121,
+ "width": 28.982045888900757,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "KMbJr-rBENubXVaV5X1K7",
+ "fhJJTPmf8EllHlHVZIfN_",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0NV",
+ "roundness": null,
+ "seed": 1464690375,
+ "version": 1678,
+ "versionNonce": 2067727922,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "6379",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "6379",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "bdFjG1_R6xjBuBo6F-fSw",
+ "type": "text",
+ "x": 1277.5435383200634,
+ "y": 700.7043377410354,
+ "width": 28.982045888900757,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "850DVCPwXx3N7mN0OJKi1",
+ "fhJJTPmf8EllHlHVZIfN_",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0O",
+ "roundness": null,
+ "seed": 178451943,
+ "version": 1746,
+ "versionNonce": 698576882,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "6379",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "6379",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "Q4UqIB_UJkuB4HQyZdBu-",
+ "type": "rectangle",
+ "x": 1210.1831153486523,
+ "y": 204.43912648096392,
+ "width": 212.65234375,
+ "height": 107.8046875,
+ "angle": 0,
+ "strokeColor": "#4dabf7",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "EG0h7Rh3z6fOt0M10fSLg",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0OG",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 1781493833,
+ "version": 633,
+ "versionNonce": 1800708530,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "q1aFZZIw1PuMuAUysXiHL",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "1TGtG3IdCaRWqNq-8oabB",
+ "type": "text",
+ "x": 1228.1167090986523,
+ "y": 214.40006398096392,
+ "width": 47.09996455907822,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "EG0h7Rh3z6fOt0M10fSLg",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0OV",
+ "roundness": null,
+ "seed": 98806119,
+ "version": 516,
+ "versionNonce": 1482251570,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "redis",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "redis",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "eGa6jMhupqqyTqSf1c4Vp",
+ "type": "rectangle",
+ "x": 897.861909868243,
+ "y": 202.2211776682919,
+ "width": 268.22345220639744,
+ "height": 107.8046875,
+ "angle": 0,
+ "strokeColor": "#4dabf7",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "-Zw45RE9bOYyu5hTu1CYY",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Q",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 1689693833,
+ "version": 1315,
+ "versionNonce": 1062921970,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "qs2K8DtoGY_SVtKXOFZd8",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "C5XTA4vTKgshDcC1PeY7o",
+ "type": "text",
+ "x": 915.795503618243,
+ "y": 212.2888960137647,
+ "width": 225.67986392974854,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "-Zw45RE9bOYyu5hTu1CYY",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0R",
+ "roundness": null,
+ "seed": 147977577,
+ "version": 1208,
+ "versionNonce": 352277106,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "open-oauth2playground",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "open-oauth2playground",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "O104zgOAcpZ2c2_rqhM1M",
+ "type": "text",
+ "x": 336.0528602773585,
+ "y": 100.178017303198,
+ "width": 42.5999755859375,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0X",
+ "roundness": null,
+ "seed": 1534404489,
+ "version": 354,
+ "versionNonce": 888183593,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731231964842,
+ "link": null,
+ "locked": false,
+ "text": "local",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "local",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "CKMCt3HyNz7Gnpxj1D1dF",
+ "type": "rectangle",
+ "x": 307.36106593126567,
+ "y": 83.81040257259781,
+ "width": 1192.5654785291902,
+ "height": 832.7277666864078,
+ "angle": 0,
+ "strokeColor": "#846358",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0Y",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 485964327,
+ "version": 1155,
+ "versionNonce": 2080689198,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "5LP1X5z6RB2aalWT9ei0l",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807335163,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "jFV0SJeU5NzlFP3LQtbs4",
+ "type": "rectangle",
+ "x": 669.8963986948238,
+ "y": 825.265599847769,
+ "width": 338.882017224971,
+ "height": 59.7899413618012,
+ "angle": 0,
+ "strokeColor": "#846358",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "eQlhM4PbazZAQamDBYGRY"
+ ],
+ "frameId": null,
+ "index": "b0Z",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 1026495177,
+ "version": 613,
+ "versionNonce": 425306930,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "V6V11BvSn6bnT9jAg9c16",
+ "type": "arrow"
+ },
+ {
+ "id": "zOfBHikVIsY0-pNT3O7AH",
+ "type": "arrow"
+ },
+ {
+ "id": "pCeFUAgzFQjeJDrWK_lHg",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807481798,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "icc-jztJZkpSPXEZjJBxZ",
+ "type": "text",
+ "x": 694.8802514686246,
+ "y": 843.6511430491073,
+ "width": 285.5398010611534,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "eQlhM4PbazZAQamDBYGRY"
+ ],
+ "frameId": null,
+ "index": "b0a",
+ "roundness": null,
+ "seed": 595238889,
+ "version": 697,
+ "versionNonce": 445273385,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232472602,
+ "link": null,
+ "locked": false,
+ "text": "web - open-oauth2playground",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "web - open-oauth2playground",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "V6V11BvSn6bnT9jAg9c16",
+ "type": "arrow",
+ "x": 839.0187616014333,
+ "y": 820.265599847769,
+ "width": 231.49791346504674,
+ "height": 95.92235260837504,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0k",
+ "roundness": null,
+ "seed": 904645447,
+ "version": 201,
+ "versionNonce": 2108546226,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ -47.961176304187575
+ ],
+ [
+ -231.49791346504674,
+ -47.961176304187575
+ ],
+ [
+ -231.49791346504674,
+ -95.92235260837504
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": {
+ "elementId": "jFV0SJeU5NzlFP3LQtbs4",
+ "focus": 0.3485637488708198,
+ "gap": 5.3985047850430306,
+ "fixedPoint": [
+ 0.4990597149164618,
+ -0.08362610643392297
+ ]
+ },
+ "endBinding": {
+ "elementId": "FCd2vAM-KTdg0-sEwbW6p",
+ "focus": 0.9123861032990002,
+ "gap": 1.424144643301588,
+ "fixedPoint": [
+ 0.3982801643575564,
+ 1.3047397166100174
+ ]
+ },
+ "startArrowhead": null,
+ "endArrowhead": "triangle",
+ "elbowed": true
+ },
+ {
+ "id": "zOfBHikVIsY0-pNT3O7AH",
+ "type": "arrow",
+ "x": 838.820185291975,
+ "y": 820.265599847769,
+ "width": 0.7476238207182178,
+ "height": 95.11833073943501,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0l",
+ "roundness": null,
+ "seed": 1738742983,
+ "version": 179,
+ "versionNonce": 57209778,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ -47.55916536971745
+ ],
+ [
+ -0.7476238207182178,
+ -47.55916536971745
+ ],
+ [
+ -0.7476238207182178,
+ -95.11833073943501
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": {
+ "elementId": "jFV0SJeU5NzlFP3LQtbs4",
+ "focus": -0.00508203021282228,
+ "gap": 1.5147216163340431,
+ "fixedPoint": [
+ 0.4984737401542587,
+ -0.08362610643392297
+ ]
+ },
+ "endBinding": {
+ "elementId": "uPM4VovVOcTJr3YN82ZRE",
+ "focus": -0.10002072086324323,
+ "gap": 1,
+ "fixedPoint": [
+ 0.5475399691960917,
+ 1.3047397166100174
+ ]
+ },
+ "startArrowhead": null,
+ "endArrowhead": "triangle",
+ "elbowed": true
+ },
+ {
+ "id": "pCeFUAgzFQjeJDrWK_lHg",
+ "type": "arrow",
+ "x": 839.2081018034752,
+ "y": 820.265599847769,
+ "width": 231.52200549365205,
+ "height": 98.01391641336829,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0m",
+ "roundness": null,
+ "seed": 6131687,
+ "version": 174,
+ "versionNonce": 325094066,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ -49.0069582066842
+ ],
+ [
+ 231.52200549365205,
+ -49.0069582066842
+ ],
+ [
+ 231.52200549365205,
+ -98.01391641336829
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": {
+ "elementId": "jFV0SJeU5NzlFP3LQtbs4",
+ "focus": -0.3793177707463059,
+ "gap": 6.742358414168223,
+ "fixedPoint": [
+ 0.4996184350385631,
+ -0.08362610643392297
+ ]
+ },
+ "endBinding": {
+ "elementId": "2d-VsKbtwPr327OOSDsFQ",
+ "focus": -1.2233451558531079,
+ "gap": 6.314248995545313,
+ "fixedPoint": [
+ 0.718672264875697,
+ 1.3047397166100174
+ ]
+ },
+ "startArrowhead": null,
+ "endArrowhead": "triangle",
+ "elbowed": true
+ },
+ {
+ "id": "qZECMiSPYv5xtI2SdmWaF",
+ "type": "text",
+ "x": 857.2693098567693,
+ "y": 792.090696927015,
+ "width": 149.59979248046875,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0o",
+ "roundness": null,
+ "seed": 919696873,
+ "version": 54,
+ "versionNonce": 439616393,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232331990,
+ "link": null,
+ "locked": false,
+ "text": "localhost:${port}",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "localhost:${port}",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "i3ZfNQCXI3YM8xcsfaqQI",
+ "type": "rectangle",
+ "x": 81.46651927120627,
+ "y": 84.26010075734206,
+ "width": 120.33060250931145,
+ "height": 831.4481962291687,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dotted",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "X6Y974B7_qQeqQyAt6VE-"
+ ],
+ "frameId": null,
+ "index": "b0oG",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 2025404199,
+ "version": 220,
+ "versionNonce": 215592169,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232583651,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "_ZI6xSh1xNckXB8Y8U3di",
+ "type": "text",
+ "x": 93.55555599568652,
+ "y": 106.12855668423268,
+ "width": 96.79986572265625,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dotted",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "X6Y974B7_qQeqQyAt6VE-"
+ ],
+ "frameId": null,
+ "index": "b0oV",
+ "roundness": null,
+ "seed": 837775047,
+ "version": 103,
+ "versionNonce": 80095177,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232583651,
+ "link": null,
+ "locked": false,
+ "text": "middlewares",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "middlewares",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "hS4tZVE-j34JGD2eZv1Pr",
+ "type": "rectangle",
+ "x": 87.45459076936322,
+ "y": 166.73837699354343,
+ "width": 102.07944978908449,
+ "height": 41.65778569338423,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "X6Y974B7_qQeqQyAt6VE-"
+ ],
+ "frameId": null,
+ "index": "b0ol",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 972169289,
+ "version": 132,
+ "versionNonce": 52446889,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "JiO2fLU2CdfO7KZaKNr2g"
+ }
+ ],
+ "updated": 1731232583651,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "JiO2fLU2CdfO7KZaKNr2g",
+ "type": "text",
+ "x": 116.35833946857008,
+ "y": 177.56726984023555,
+ "width": 44.271952390670776,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "X6Y974B7_qQeqQyAt6VE-"
+ ],
+ "frameId": null,
+ "index": "b0p",
+ "roundness": null,
+ "seed": 1779170825,
+ "version": 82,
+ "versionNonce": 848529801,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232583651,
+ "link": null,
+ "locked": false,
+ "text": "nginx",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "hS4tZVE-j34JGD2eZv1Pr",
+ "originalText": "nginx",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "7yflbQghmnHCmgRi-PNmF",
+ "type": "rectangle",
+ "x": 88.1860480497744,
+ "y": 231.2524387352739,
+ "width": 102.07944978908449,
+ "height": 41.65778569338423,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "X6Y974B7_qQeqQyAt6VE-"
+ ],
+ "frameId": null,
+ "index": "b0pV",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 130766985,
+ "version": 156,
+ "versionNonce": 1549496425,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "1_z07xQvl9Q32ABYFQPRS"
+ }
+ ],
+ "updated": 1731232583651,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "1_z07xQvl9Q32ABYFQPRS",
+ "type": "text",
+ "x": 126.00978514276483,
+ "y": 242.08133158196603,
+ "width": 26.431975603103638,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "X6Y974B7_qQeqQyAt6VE-"
+ ],
+ "frameId": null,
+ "index": "b0q",
+ "roundness": null,
+ "seed": 2009161577,
+ "version": 110,
+ "versionNonce": 373521225,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232583651,
+ "link": null,
+ "locked": false,
+ "text": "...",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "7yflbQghmnHCmgRi-PNmF",
+ "originalText": "...",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "vceXNWGdzljT9ZqfEBMvL",
+ "type": "rectangle",
+ "x": -135.52234568412212,
+ "y": 83.7675667723251,
+ "width": 120.33060250931145,
+ "height": 831.4481962291687,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0v",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 816909959,
+ "version": 503,
+ "versionNonce": 23216295,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "5LP1X5z6RB2aalWT9ei0l",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1731232565518,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "-4ld7yicuN09NWzzlmwsL",
+ "type": "text",
+ "x": -116.79766994347722,
+ "y": 103.25301533741276,
+ "width": 66.17998164892197,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0w",
+ "roundness": null,
+ "seed": 1632418217,
+ "version": 587,
+ "versionNonce": 279201255,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232591920,
+ "link": null,
+ "locked": false,
+ "text": "remote",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "remote",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "oNZN6L3k1A2noJxLfBjTg",
+ "type": "rectangle",
+ "x": -120.59924207850622,
+ "y": 151.94446444272577,
+ "width": 85.83340768018998,
+ "height": 59.7899413618012,
+ "angle": 0,
+ "strokeColor": "#846358",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "08x_2b5P145Arwkv1trFC"
+ ],
+ "frameId": null,
+ "index": "b0x",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 1382850599,
+ "version": 954,
+ "versionNonce": 799960455,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232588933,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "QoRLi83c_yuTaw7uL5wm6",
+ "type": "text",
+ "x": -95.61538930470556,
+ "y": 170.33000764406412,
+ "width": 35.819975316524506,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "08x_2b5P145Arwkv1trFC"
+ ],
+ "frameId": null,
+ "index": "b0y",
+ "roundness": null,
+ "seed": 1146356551,
+ "version": 1021,
+ "versionNonce": 649405607,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232588933,
+ "link": null,
+ "locked": false,
+ "text": "web",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "web",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "5LP1X5z6RB2aalWT9ei0l",
+ "type": "arrow",
+ "x": -10.191743174810625,
+ "y": 499.39166488690944,
+ "width": 312.55280910607644,
+ "height": 0.6826210288922425,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0z",
+ "roundness": null,
+ "seed": 607912455,
+ "version": 152,
+ "versionNonce": 885101511,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "K6RyM8pWTcSSez33shdEn"
+ }
+ ],
+ "updated": 1731232565518,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 156.27640455303813,
+ 0
+ ],
+ [
+ 156.27640455303813,
+ 0.6826210288922425
+ ],
+ [
+ 312.55280910607644,
+ 0.6826210288922425
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": {
+ "elementId": "vceXNWGdzljT9ZqfEBMvL",
+ "focus": -0.00024054415044388443,
+ "gap": 5.000000000000007,
+ "fixedPoint": [
+ 1.0415521895156565,
+ 0.4998797279247781
+ ]
+ },
+ "endBinding": {
+ "elementId": "CKMCt3HyNz7Gnpxj1D1dF",
+ "focus": 0.00024017453002184118,
+ "gap": 5.000000000000114,
+ "fixedPoint": [
+ -0.0041926419052197164,
+ 0.4998799127349891
+ ]
+ },
+ "startArrowhead": null,
+ "endArrowhead": "triangle",
+ "elbowed": true
+ },
+ {
+ "id": "K6RyM8pWTcSSez33shdEn",
+ "type": "text",
+ "x": 103.60259819593156,
+ "y": 479.224328978765,
+ "width": 176.23976111412048,
+ "height": 40,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b10",
+ "roundness": null,
+ "seed": 3199081,
+ "version": 58,
+ "versionNonce": 1486961449,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232549421,
+ "link": null,
+ "locked": false,
+ "text": "domain / ipv4 addr /\nipv6 addr",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "5LP1X5z6RB2aalWT9ei0l",
+ "originalText": "domain / ipv4 addr / ipv6 addr",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "qs2K8DtoGY_SVtKXOFZd8",
+ "type": "arrow",
+ "x": 1033.7418393547046,
+ "y": 313.1860383581939,
+ "width": 0.05157682453682355,
+ "height": 87.51576982280005,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 4,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b17",
+ "roundness": null,
+ "seed": 1161711474,
+ "version": 639,
+ "versionNonce": 1761949874,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "kmG4UT-WRv0dlwDysR6Pe"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0.05157682453682355,
+ 87.51576982280005
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": {
+ "elementId": "eGa6jMhupqqyTqSf1c4Vp",
+ "focus": -0.012930735115086384,
+ "gap": 3.160173189902025,
+ "fixedPoint": null
+ },
+ "endBinding": {
+ "elementId": "E_kwiFtlRqioM7mcOWGn7",
+ "focus": 0.012317501693059398,
+ "gap": 3.9907847284173386,
+ "fixedPoint": null
+ },
+ "startArrowhead": "bar",
+ "endArrowhead": "bar",
+ "elbowed": false
+ },
+ {
+ "id": "kmG4UT-WRv0dlwDysR6Pe",
+ "type": "text",
+ "x": 972.2545592715264,
+ "y": 371.8257499984128,
+ "width": 123.40783953666687,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 4,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b18",
+ "roundness": null,
+ "seed": 1433844398,
+ "version": 19,
+ "versionNonce": 1461810418,
+ "isDeleted": false,
+ "boundElements": null,
+ "updated": 1732807481799,
+ "link": null,
+ "locked": false,
+ "text": "container mode",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "qs2K8DtoGY_SVtKXOFZd8",
+ "originalText": "container mode",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "q1aFZZIw1PuMuAUysXiHL",
+ "type": "arrow",
+ "x": 1310.1552467271904,
+ "y": 313.2438139809639,
+ "width": 3.3301372618125242,
+ "height": 85.8502442779257,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 4,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b19",
+ "roundness": null,
+ "seed": 126174254,
+ "version": 532,
+ "versionNonce": 1266260850,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "suSaWTl4IH2ffRzu0yfkz"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 3.3301372618125242,
+ 85.8502442779257
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": {
+ "elementId": "Q4UqIB_UJkuB4HQyZdBu-",
+ "focus": 0.07825066820981601,
+ "gap": 1,
+ "fixedPoint": null
+ },
+ "endBinding": {
+ "elementId": "E_kwiFtlRqioM7mcOWGn7",
+ "focus": 0.7196438925888313,
+ "gap": 5.598534650521685,
+ "fixedPoint": null
+ },
+ "startArrowhead": "bar",
+ "endArrowhead": "bar",
+ "elbowed": false
+ },
+ {
+ "id": "suSaWTl4IH2ffRzu0yfkz",
+ "type": "text",
+ "x": 1250.459574542399,
+ "y": 369.2855585557687,
+ "width": 123.40783953666687,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 4,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b1A",
+ "roundness": null,
+ "seed": 1659407982,
+ "version": 24,
+ "versionNonce": 1032981294,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807481799,
+ "link": null,
+ "locked": false,
+ "text": "container mode",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "q1aFZZIw1PuMuAUysXiHL",
+ "originalText": "container mode",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "rQlz4Pp79b_1m_Mi2BEsC",
+ "type": "diamond",
+ "x": 880.323374915715,
+ "y": 242.0327557280478,
+ "width": 37.703125,
+ "height": 31.58203125,
+ "angle": 0,
+ "strokeColor": "#1971c2",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "8WzoSYeWk0DdDLpXR_px0",
+ "8_bjPGcX2IYpWYKHZk9As",
+ "_YKpNuHtvIUaG0b1029Jm",
+ "4kmIbgh-VkD7HY3ZqcPrc"
+ ],
+ "frameId": null,
+ "index": "b1C",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1808667374,
+ "version": 1571,
+ "versionNonce": 526684530,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807557458,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "IyMcXvqwrov2KVMPXWH6C",
+ "type": "text",
+ "x": 840.8762830286024,
+ "y": 248.79287112492298,
+ "width": 28.916445314884186,
+ "height": 49.22233362576761,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "8QUsYA7_SRpuI6SSN6dy9",
+ "QEtJKDXJL9pnQrRFBrDk4",
+ "w1jD_wa3LdYsC3Mlk6tfL",
+ "1pOZe_qQCWHFWsmGKcVTi"
+ ],
+ "frameId": null,
+ "index": "b1D",
+ "roundness": null,
+ "seed": 1093255474,
+ "version": 1547,
+ "versionNonce": 578351410,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807631041,
+ "link": null,
+ "locked": false,
+ "text": "80\n8081\n8444",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "80\n8081\n8444",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "hb1fBolYNCc0fzrjIStpn",
+ "type": "text",
+ "x": 931.1026168198915,
+ "y": 247.42647890553073,
+ "width": 28.916445314884186,
+ "height": 49.22233362576761,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "iQrY6kT1f4Ok9hOLRxehB",
+ "qJYhyhVoBW3E8TqmE21wT",
+ "ayCt_6aj6iHP9dCK_SAQ9",
+ "rgSY6L8sOikz6eNUQaIWD"
+ ],
+ "frameId": null,
+ "index": "b1F",
+ "roundness": null,
+ "seed": 273337582,
+ "version": 1575,
+ "versionNonce": 1918518002,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807628190,
+ "link": null,
+ "locked": false,
+ "text": "80\n8081\n8444",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "80\n8081\n8444",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "S0fGSdt3bAdiCGHA8oNef",
+ "type": "rectangle",
+ "x": 976.0145747988004,
+ "y": 278.8149105268659,
+ "width": 118.80193558682913,
+ "height": 30.613576472610134,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "cross-hatch",
+ "strokeWidth": 1,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b1G",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 1072041838,
+ "version": 141,
+ "versionNonce": 428918830,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "jq6FPUzRdWlZZ6-q438mj"
+ }
+ ],
+ "updated": 1732807700419,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "jq6FPUzRdWlZZ6-q438mj",
+ "type": "text",
+ "x": 986.8796045676941,
+ "y": 284.12169876317097,
+ "width": 97.07187604904175,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#d0bfff",
+ "fillStyle": "cross-hatch",
+ "strokeWidth": 1,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b1H",
+ "roundness": null,
+ "seed": 1023256882,
+ "version": 109,
+ "versionNonce": 1074420850,
+ "isDeleted": false,
+ "boundElements": null,
+ "updated": 1732807694990,
+ "link": null,
+ "locked": false,
+ "text": "bridge mode",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "S0fGSdt3bAdiCGHA8oNef",
+ "originalText": "bridge mode",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "6bBUg4xR6UT88Aen5T8bV",
+ "type": "text",
+ "x": 603.9731122917782,
+ "y": 205.49932756770806,
+ "width": 219.8798644542694,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#96f2d7",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "vteo9Bjeige-16NGFvieH"
+ ],
+ "frameId": null,
+ "index": "b1I",
+ "roundness": null,
+ "seed": 1813215470,
+ "version": 347,
+ "versionNonce": 362623086,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807815840,
+ "link": null,
+ "locked": false,
+ "text": "shared virtual network",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "shared virtual network",
+ "autoResize": true,
+ "lineHeight": 1.25
+ }
+ ],
+ "appState": {
+ "gridSize": 20,
+ "gridStep": 5,
+ "gridModeEnabled": false,
+ "viewBackgroundColor": "#ffffff"
+ },
+ "files": {}
+}
\ No newline at end of file
diff --git a/imgs/docker-bridge.svg b/imgs/docker-bridge.svg
new file mode 100644
index 0000000..6db7a2d
--- /dev/null
+++ b/imgs/docker-bridge.svg
@@ -0,0 +1,11 @@
+
\ No newline at end of file
diff --git a/imgs/docker-container.excalidraw b/imgs/docker-container.excalidraw
new file mode 100644
index 0000000..59cc9b1
--- /dev/null
+++ b/imgs/docker-container.excalidraw
@@ -0,0 +1,2947 @@
+{
+ "type": "excalidraw",
+ "version": 2,
+ "source": "https://excalidraw.com",
+ "elements": [
+ {
+ "id": "h5KVcWhtOmvNYpKKM60No",
+ "type": "rectangle",
+ "x": 549.3207291773347,
+ "y": 181.5078958439758,
+ "width": 900.1539748802556,
+ "height": 490.0548387416398,
+ "angle": 0,
+ "strokeColor": "#96f2d7",
+ "backgroundColor": "#ebfbee",
+ "fillStyle": "cross-hatch",
+ "strokeWidth": 1,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0J",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 30083886,
+ "version": 189,
+ "versionNonce": 522805486,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807835104,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "ObmMxiMvrqwEqQfrMJ6sQ",
+ "type": "rectangle",
+ "x": 431.5880371268839,
+ "y": 137.78789565102318,
+ "width": 1043.40234375,
+ "height": 536.3133713632769,
+ "angle": 0,
+ "strokeColor": "#1971c2",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0J2",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 131755879,
+ "version": 884,
+ "versionNonce": 1222058034,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792127,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "bsujuZnE0migXwc2713no",
+ "type": "text",
+ "x": 458.5704552631267,
+ "y": 157.41543921209262,
+ "width": 64.43995702266693,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0J4",
+ "roundness": null,
+ "seed": 1318096039,
+ "version": 271,
+ "versionNonce": 19417586,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792127,
+ "link": null,
+ "locked": false,
+ "text": "docker",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "docker",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "E_kwiFtlRqioM7mcOWGn7",
+ "type": "rectangle",
+ "x": 631.5706031778029,
+ "y": 404.6925929094113,
+ "width": 794.48828125,
+ "height": 190.53125000000006,
+ "angle": 0,
+ "strokeColor": "#4dabf7",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "_zNKuGHsIm4TFxrBs274F",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0JS",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 124659111,
+ "version": 1320,
+ "versionNonce": 1898855346,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "qs2K8DtoGY_SVtKXOFZd8",
+ "type": "arrow"
+ },
+ {
+ "id": "q1aFZZIw1PuMuAUysXiHL",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792127,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "zmkmfQ5WC6GG8x3SztTs6",
+ "type": "text",
+ "x": 648.2385719278029,
+ "y": 421.4621241594113,
+ "width": 164.3398675918579,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "_zNKuGHsIm4TFxrBs274F",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0JV",
+ "roundness": null,
+ "seed": 973658311,
+ "version": 919,
+ "versionNonce": 1218625778,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792127,
+ "link": null,
+ "locked": false,
+ "text": "oauth-server-lite",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "oauth-server-lite",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "GG1Q_QnP4IBvrDHJv5JtW",
+ "type": "rectangle",
+ "x": 1169.258884958465,
+ "y": 457.4894679094113,
+ "width": 212.65234375,
+ "height": 107.8046875,
+ "angle": 0,
+ "strokeColor": "#4dabf7",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "GSiHpJBWRivw6steyHsa_",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Jl",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 1728556007,
+ "version": 1311,
+ "versionNonce": 1883361970,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "_bW3I3e_Q7m3mKRCZBI8o",
+ "type": "arrow"
+ },
+ {
+ "id": "L5V1mppKIrdSJk6msfe-f",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792127,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "nwRR6E2l0L80tkAsV34Lb",
+ "type": "text",
+ "x": 1187.192478708465,
+ "y": 467.4504054094113,
+ "width": 104.7199227809906,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "GSiHpJBWRivw6steyHsa_",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Jn",
+ "roundness": null,
+ "seed": 1897371399,
+ "version": 1203,
+ "versionNonce": 2107157618,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "apereo-cas",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "apereo-cas",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "inXx_nl6tRFlsXoRqXaaB",
+ "type": "diamond",
+ "x": 1151.973728708465,
+ "y": 495.1066554094113,
+ "width": 37.703125,
+ "height": 31.58203125,
+ "angle": 0,
+ "strokeColor": "#1971c2",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "GSiHpJBWRivw6steyHsa_",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Jp",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 71114279,
+ "version": 1430,
+ "versionNonce": 1986940466,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "L5V1mppKIrdSJk6msfe-f",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "mW59uMx6695nqaCRdPEH_",
+ "type": "text",
+ "x": 1196.6503089289258,
+ "y": 504.6847804094113,
+ "width": 28.916445314884186,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "GSiHpJBWRivw6steyHsa_",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Jr",
+ "roundness": null,
+ "seed": 593805639,
+ "version": 1262,
+ "versionNonce": 262780914,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8444",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8444",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "WwTuoNAipiAjIBt7222yk",
+ "type": "text",
+ "x": 1114.0514874975274,
+ "y": 505.61777688845,
+ "width": 28.916445314884186,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "GSiHpJBWRivw6steyHsa_",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Jt",
+ "roundness": null,
+ "seed": 1072365671,
+ "version": 1294,
+ "versionNonce": 1230105010,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8444",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8444",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "bb7GorAvbKtx_-8YuYxe5",
+ "type": "text",
+ "x": 1196.8823590795587,
+ "y": 530.46543313845,
+ "width": 35.18228149414062,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "GSiHpJBWRivw6steyHsa_",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Jv",
+ "roundness": null,
+ "seed": 824874855,
+ "version": 1354,
+ "versionNonce": 177070962,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8080",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8080",
+ "autoResize": false,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "z8s43ybhnVYowCLBYluKP",
+ "type": "ellipse",
+ "x": 1274.0126081029962,
+ "y": 496.8996241594113,
+ "width": 90.5156250000001,
+ "height": 49,
+ "angle": 0,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "GSiHpJBWRivw6steyHsa_",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Jx",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1523587593,
+ "version": 1174,
+ "versionNonce": 1034200370,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "ewS8OZxi2jCNFxW0Rg8NC"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "ewS8OZxi2jCNFxW0Rg8NC",
+ "type": "text",
+ "x": 1292.6783292311502,
+ "y": 509.07550802034086,
+ "width": 53.179970502853394,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "GSiHpJBWRivw6steyHsa_",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0K",
+ "roundness": null,
+ "seed": 1753316135,
+ "version": 1197,
+ "versionNonce": 1811754738,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "sqlite",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "z8s43ybhnVYowCLBYluKP",
+ "originalText": "sqlite",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "LldGF3VFnMGbIVWxs5sKJ",
+ "type": "rectangle",
+ "x": 802.9756821952803,
+ "y": 458.4855616594113,
+ "width": 212.65234375,
+ "height": 107.8046875,
+ "angle": 0,
+ "strokeColor": "#4dabf7",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "lnPcJGNQb2eYI4W12C_oS",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0K4",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 1209120807,
+ "version": 1408,
+ "versionNonce": 1511948466,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "_bW3I3e_Q7m3mKRCZBI8o",
+ "type": "arrow"
+ },
+ {
+ "id": "L5V1mppKIrdSJk6msfe-f",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "VzkuuI7BQtpMXa1zfZ5dB",
+ "type": "text",
+ "x": 820.9092759452803,
+ "y": 468.4464991594113,
+ "width": 125.17991733551025,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "lnPcJGNQb2eYI4W12C_oS",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0K8",
+ "roundness": null,
+ "seed": 1972771655,
+ "version": 1306,
+ "versionNonce": 1467448370,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "oauth-server",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "oauth-server",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "ccF7TixQDB3FfDe5IvARw",
+ "type": "diamond",
+ "x": 785.6905259452803,
+ "y": 496.1027491594113,
+ "width": 37.703125,
+ "height": 31.58203125,
+ "angle": 0,
+ "strokeColor": "#1971c2",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "lnPcJGNQb2eYI4W12C_oS",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0KC",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 920722023,
+ "version": 1518,
+ "versionNonce": 324871666,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "KfO_O2QwVBws84bDpv4CN",
+ "type": "text",
+ "x": 830.3671061657412,
+ "y": 505.6808741594113,
+ "width": 28.916445314884186,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "lnPcJGNQb2eYI4W12C_oS",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0KG",
+ "roundness": null,
+ "seed": 280966535,
+ "version": 1358,
+ "versionNonce": 543659954,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8081",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8081",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "fk7gB889rOUWao856kpV0",
+ "type": "text",
+ "x": 747.7682847343428,
+ "y": 506.6138706384499,
+ "width": 28.916445314884186,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "lnPcJGNQb2eYI4W12C_oS",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0KK",
+ "roundness": null,
+ "seed": 980216999,
+ "version": 1388,
+ "versionNonce": 247320946,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8081",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8081",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "PN42MKgOMT4Ur1EtXQQOR",
+ "type": "ellipse",
+ "x": 907.7294053398116,
+ "y": 497.8957179094113,
+ "width": 90.5156250000001,
+ "height": 49,
+ "angle": 0,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "lnPcJGNQb2eYI4W12C_oS",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0KO",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1113140967,
+ "version": 1265,
+ "versionNonce": 1369887538,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "R-KPOeSjlspWzmpwW9fJ8"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "R-KPOeSjlspWzmpwW9fJ8",
+ "type": "text",
+ "x": 926.3951264679656,
+ "y": 510.07160177034086,
+ "width": 53.179970502853394,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#f08c00",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "lnPcJGNQb2eYI4W12C_oS",
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0KV",
+ "roundness": null,
+ "seed": 222345735,
+ "version": 1288,
+ "versionNonce": 1535745266,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "sqlite",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "PN42MKgOMT4Ur1EtXQQOR",
+ "originalText": "sqlite",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "_bW3I3e_Q7m3mKRCZBI8o",
+ "type": "arrow",
+ "x": 1022.0238924288878,
+ "y": 484.6127428300213,
+ "width": 147.5639217630777,
+ "height": 2.4865772264720363,
+ "angle": 0,
+ "strokeColor": "#343a40",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0KZ",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1469378727,
+ "version": 1326,
+ "versionNonce": 971845298,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 147.5639217630777,
+ 2.4865772264720363
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": "triangle",
+ "elbowed": false
+ },
+ {
+ "id": "ggK_2ImyH3jtFh6pCANZu",
+ "type": "text",
+ "x": 1034.1827063675596,
+ "y": 459.34953260345884,
+ "width": 110.6526780128479,
+ "height": 17.946257665140756,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Kd",
+ "roundness": null,
+ "seed": 1268840775,
+ "version": 700,
+ "versionNonce": 829982834,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "localhost:8444",
+ "fontSize": 14.357006132112604,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "localhost:8444",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "L5V1mppKIrdSJk6msfe-f",
+ "type": "arrow",
+ "x": 1165.0457202313733,
+ "y": 537.355677580558,
+ "width": 145.86318989156166,
+ "height": 0.9621084825225807,
+ "angle": 0,
+ "strokeColor": "#343a40",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Kh",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 841772615,
+ "version": 1432,
+ "versionNonce": 1312535086,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792168,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -145.86318989156166,
+ -0.9621084825225807
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": {
+ "elementId": "XiFp3cXXT0qge0XUWZfyk",
+ "focus": 2.0717902039550897,
+ "gap": 9.906441890812914,
+ "fixedPoint": null
+ },
+ "endBinding": {
+ "elementId": "LldGF3VFnMGbIVWxs5sKJ",
+ "focus": 0.42636137261614887,
+ "gap": 3.55450439453125,
+ "fixedPoint": null
+ },
+ "startArrowhead": null,
+ "endArrowhead": "triangle",
+ "elbowed": false
+ },
+ {
+ "id": "XiFp3cXXT0qge0XUWZfyk",
+ "type": "text",
+ "x": 1048.270580168079,
+ "y": 547.2621194713709,
+ "width": 110.04400797958446,
+ "height": 17.84278794067754,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "6xkSxRQtkTS42crOoESz4",
+ "mK9Wo0iTn_Tfu2LYoOikT",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Kl",
+ "roundness": null,
+ "seed": 2079863177,
+ "version": 681,
+ "versionNonce": 977441778,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "L5V1mppKIrdSJk6msfe-f",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "localhost:8081",
+ "fontSize": 14.27423035254203,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "localhost:8081",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "Eu7lMmWPEDEMeLReUHiqz",
+ "type": "diamond",
+ "x": 590.1373038954857,
+ "y": 659.5457460474637,
+ "width": 37.703125,
+ "height": 31.58203125,
+ "angle": 4.71238898038469,
+ "strokeColor": "#1971c2",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "4Q1XhLVCxUYTovc1t9DG2",
+ "o54l8ZnsIYvKH9rZEUCcP",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0LG",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1246592839,
+ "version": 1488,
+ "versionNonce": 295681906,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "LK9fNXPkTb8OWsSilsbAz",
+ "type": "text",
+ "x": 601.772878236306,
+ "y": 632.1724108360452,
+ "width": 14.431976318359375,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "sWC3N1DmftEYJp8dFHxUX",
+ "o54l8ZnsIYvKH9rZEUCcP",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0LO",
+ "roundness": null,
+ "seed": 830780713,
+ "version": 1314,
+ "versionNonce": 1041957170,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "80",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "80",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "FCd2vAM-KTdg0-sEwbW6p",
+ "type": "text",
+ "x": 601.772878236306,
+ "y": 702.9358026974713,
+ "width": 14.431976318359375,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "Sbt68FEHPrEhw2RF1Iqxy",
+ "o54l8ZnsIYvKH9rZEUCcP",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0LV",
+ "roundness": null,
+ "seed": 677189255,
+ "version": 1359,
+ "versionNonce": 1162349298,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "V6V11BvSn6bnT9jAg9c16",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "80",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "80",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "5KJCWBp2SqKvred-CgSm7",
+ "type": "diamond",
+ "x": 817.8463120517267,
+ "y": 660.4638978031068,
+ "width": 37.703125,
+ "height": 31.58203125,
+ "angle": 1.5707963267948966,
+ "strokeColor": "#1971c2",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "LWFmWXILANksJE28M4Rjg",
+ "C1wWuGiRK_6ZnbiwfK0Vt",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Ld",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 519127335,
+ "version": 1626,
+ "versionNonce": 1425241714,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "0mYPKco6DCUkwjZ9lZesj",
+ "type": "text",
+ "x": 822.2396518942846,
+ "y": 633.0905625916881,
+ "width": 28.916445314884186,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "aQXOS3o3FxLGtnKRdWBvM",
+ "C1wWuGiRK_6ZnbiwfK0Vt",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Ll",
+ "roundness": null,
+ "seed": 966558791,
+ "version": 1457,
+ "versionNonce": 1809831986,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8081",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8081",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "uPM4VovVOcTJr3YN82ZRE",
+ "type": "text",
+ "x": 822.2396518942846,
+ "y": 703.7398245664114,
+ "width": 28.916445314884186,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "TxKvmto1F4z4LRrbFox_A",
+ "C1wWuGiRK_6ZnbiwfK0Vt",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0M",
+ "roundness": null,
+ "seed": 1613914983,
+ "version": 1528,
+ "versionNonce": 844759538,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "zOfBHikVIsY0-pNT3O7AH",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8081",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8081",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "bcpbTFfJwt7lwwwgoHnAj",
+ "type": "diamond",
+ "x": 1045.5553202079673,
+ "y": 657.5683121291735,
+ "width": 37.703125,
+ "height": 31.58203125,
+ "angle": 1.5707963267948966,
+ "strokeColor": "#1971c2",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "dumEUFb2CY65s2tmjAXmq",
+ "rbFlF-hORygtq2JcjYcpZ",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0MG",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1216220969,
+ "version": 1669,
+ "versionNonce": 1093905778,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "l1EQaaqrR0GL0f-QmK-IU",
+ "type": "text",
+ "x": 1049.9486600505252,
+ "y": 630.1949769177548,
+ "width": 28.916445314884186,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "-IFkvIjdUPn1ryljMGgFU",
+ "rbFlF-hORygtq2JcjYcpZ",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0MV",
+ "roundness": null,
+ "seed": 170148361,
+ "version": 1504,
+ "versionNonce": 1895903026,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8444",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8444",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "2d-VsKbtwPr327OOSDsFQ",
+ "type": "text",
+ "x": 1049.9486600505252,
+ "y": 700.8442388924781,
+ "width": 28.916445314884186,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "tSsGD-4Vp01m0OkPH4BZR",
+ "rbFlF-hORygtq2JcjYcpZ",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Ml",
+ "roundness": null,
+ "seed": 1648433385,
+ "version": 1577,
+ "versionNonce": 1463318770,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "pCeFUAgzFQjeJDrWK_lHg",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "8444",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "8444",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "PpXJYR6C7EKu_ECiCDBTl",
+ "type": "diamond",
+ "x": 1273.1501984775055,
+ "y": 657.4284109777308,
+ "width": 37.703125,
+ "height": 31.58203125,
+ "angle": 1.5707963267948966,
+ "strokeColor": "#1971c2",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "RQZ7XU57WduOuW4jmvOGo",
+ "fhJJTPmf8EllHlHVZIfN_",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0N",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 632058791,
+ "version": 1839,
+ "versionNonce": 1008755826,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "GkxhQSjSHBKwLnIGNpdqx",
+ "type": "text",
+ "x": 1277.5435383200634,
+ "y": 630.0550757663121,
+ "width": 28.982045888900757,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "KMbJr-rBENubXVaV5X1K7",
+ "fhJJTPmf8EllHlHVZIfN_",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0NV",
+ "roundness": null,
+ "seed": 1464690375,
+ "version": 1678,
+ "versionNonce": 2067727922,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "6379",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "6379",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "bdFjG1_R6xjBuBo6F-fSw",
+ "type": "text",
+ "x": 1277.5435383200634,
+ "y": 700.7043377410354,
+ "width": 28.982045888900757,
+ "height": 16.407444541922537,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "850DVCPwXx3N7mN0OJKi1",
+ "fhJJTPmf8EllHlHVZIfN_",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0O",
+ "roundness": null,
+ "seed": 178451943,
+ "version": 1746,
+ "versionNonce": 698576882,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "6379",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "6379",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "Q4UqIB_UJkuB4HQyZdBu-",
+ "type": "rectangle",
+ "x": 1210.1831153486523,
+ "y": 204.43912648096392,
+ "width": 212.65234375,
+ "height": 107.8046875,
+ "angle": 0,
+ "strokeColor": "#4dabf7",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "EG0h7Rh3z6fOt0M10fSLg",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0OG",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 1781493833,
+ "version": 633,
+ "versionNonce": 1800708530,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "q1aFZZIw1PuMuAUysXiHL",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "1TGtG3IdCaRWqNq-8oabB",
+ "type": "text",
+ "x": 1228.1167090986523,
+ "y": 214.40006398096392,
+ "width": 47.09996455907822,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "EG0h7Rh3z6fOt0M10fSLg",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0OV",
+ "roundness": null,
+ "seed": 98806119,
+ "version": 516,
+ "versionNonce": 1482251570,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "redis",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "redis",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "eGa6jMhupqqyTqSf1c4Vp",
+ "type": "rectangle",
+ "x": 897.861909868243,
+ "y": 202.2211776682919,
+ "width": 268.22345220639744,
+ "height": 107.8046875,
+ "angle": 0,
+ "strokeColor": "#4dabf7",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "-Zw45RE9bOYyu5hTu1CYY",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0Q",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 1689693833,
+ "version": 1315,
+ "versionNonce": 1062921970,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "qs2K8DtoGY_SVtKXOFZd8",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "C5XTA4vTKgshDcC1PeY7o",
+ "type": "text",
+ "x": 915.795503618243,
+ "y": 212.2888960137647,
+ "width": 225.67986392974854,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "-Zw45RE9bOYyu5hTu1CYY",
+ "cRidVo41JW4E3hR7NV1Km"
+ ],
+ "frameId": null,
+ "index": "b0R",
+ "roundness": null,
+ "seed": 147977577,
+ "version": 1208,
+ "versionNonce": 352277106,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "text": "open-oauth2playground",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "open-oauth2playground",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "O104zgOAcpZ2c2_rqhM1M",
+ "type": "text",
+ "x": 336.0528602773585,
+ "y": 100.178017303198,
+ "width": 42.5999755859375,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0X",
+ "roundness": null,
+ "seed": 1534404489,
+ "version": 354,
+ "versionNonce": 888183593,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731231964842,
+ "link": null,
+ "locked": false,
+ "text": "local",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "local",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "CKMCt3HyNz7Gnpxj1D1dF",
+ "type": "rectangle",
+ "x": 307.36106593126567,
+ "y": 83.81040257259781,
+ "width": 1192.5654785291902,
+ "height": 832.7277666864078,
+ "angle": 0,
+ "strokeColor": "#846358",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0Y",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 485964327,
+ "version": 1155,
+ "versionNonce": 2080689198,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "5LP1X5z6RB2aalWT9ei0l",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807335163,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "jFV0SJeU5NzlFP3LQtbs4",
+ "type": "rectangle",
+ "x": 669.8963986948238,
+ "y": 825.265599847769,
+ "width": 338.882017224971,
+ "height": 59.7899413618012,
+ "angle": 0,
+ "strokeColor": "#846358",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "eQlhM4PbazZAQamDBYGRY"
+ ],
+ "frameId": null,
+ "index": "b0Z",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 1026495177,
+ "version": 613,
+ "versionNonce": 425306930,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "V6V11BvSn6bnT9jAg9c16",
+ "type": "arrow"
+ },
+ {
+ "id": "zOfBHikVIsY0-pNT3O7AH",
+ "type": "arrow"
+ },
+ {
+ "id": "pCeFUAgzFQjeJDrWK_lHg",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1732807481798,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "icc-jztJZkpSPXEZjJBxZ",
+ "type": "text",
+ "x": 694.8802514686246,
+ "y": 843.6511430491073,
+ "width": 285.5398010611534,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "eQlhM4PbazZAQamDBYGRY"
+ ],
+ "frameId": null,
+ "index": "b0a",
+ "roundness": null,
+ "seed": 595238889,
+ "version": 697,
+ "versionNonce": 445273385,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232472602,
+ "link": null,
+ "locked": false,
+ "text": "web - open-oauth2playground",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "web - open-oauth2playground",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "V6V11BvSn6bnT9jAg9c16",
+ "type": "arrow",
+ "x": 839.0187616014333,
+ "y": 820.265599847769,
+ "width": 231.49791346504674,
+ "height": 95.92235260837504,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0k",
+ "roundness": null,
+ "seed": 904645447,
+ "version": 201,
+ "versionNonce": 2108546226,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ -47.961176304187575
+ ],
+ [
+ -231.49791346504674,
+ -47.961176304187575
+ ],
+ [
+ -231.49791346504674,
+ -95.92235260837504
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": {
+ "elementId": "jFV0SJeU5NzlFP3LQtbs4",
+ "focus": 0.3485637488708198,
+ "gap": 5.3985047850430306,
+ "fixedPoint": [
+ 0.4990597149164618,
+ -0.08362610643392297
+ ]
+ },
+ "endBinding": {
+ "elementId": "FCd2vAM-KTdg0-sEwbW6p",
+ "focus": 0.9123861032990002,
+ "gap": 1.424144643301588,
+ "fixedPoint": [
+ 0.3982801643575564,
+ 1.3047397166100174
+ ]
+ },
+ "startArrowhead": null,
+ "endArrowhead": "triangle",
+ "elbowed": true
+ },
+ {
+ "id": "zOfBHikVIsY0-pNT3O7AH",
+ "type": "arrow",
+ "x": 838.820185291975,
+ "y": 820.265599847769,
+ "width": 0.7476238207182178,
+ "height": 95.11833073943501,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0l",
+ "roundness": null,
+ "seed": 1738742983,
+ "version": 179,
+ "versionNonce": 57209778,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ -47.55916536971745
+ ],
+ [
+ -0.7476238207182178,
+ -47.55916536971745
+ ],
+ [
+ -0.7476238207182178,
+ -95.11833073943501
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": {
+ "elementId": "jFV0SJeU5NzlFP3LQtbs4",
+ "focus": -0.00508203021282228,
+ "gap": 1.5147216163340431,
+ "fixedPoint": [
+ 0.4984737401542587,
+ -0.08362610643392297
+ ]
+ },
+ "endBinding": {
+ "elementId": "uPM4VovVOcTJr3YN82ZRE",
+ "focus": -0.10002072086324323,
+ "gap": 1,
+ "fixedPoint": [
+ 0.5475399691960917,
+ 1.3047397166100174
+ ]
+ },
+ "startArrowhead": null,
+ "endArrowhead": "triangle",
+ "elbowed": true
+ },
+ {
+ "id": "pCeFUAgzFQjeJDrWK_lHg",
+ "type": "arrow",
+ "x": 839.2081018034752,
+ "y": 820.265599847769,
+ "width": 231.52200549365205,
+ "height": 98.01391641336829,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0m",
+ "roundness": null,
+ "seed": 6131687,
+ "version": 174,
+ "versionNonce": 325094066,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ -49.0069582066842
+ ],
+ [
+ 231.52200549365205,
+ -49.0069582066842
+ ],
+ [
+ 231.52200549365205,
+ -98.01391641336829
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": {
+ "elementId": "jFV0SJeU5NzlFP3LQtbs4",
+ "focus": -0.3793177707463059,
+ "gap": 6.742358414168223,
+ "fixedPoint": [
+ 0.4996184350385631,
+ -0.08362610643392297
+ ]
+ },
+ "endBinding": {
+ "elementId": "2d-VsKbtwPr327OOSDsFQ",
+ "focus": -1.2233451558531079,
+ "gap": 6.314248995545313,
+ "fixedPoint": [
+ 0.718672264875697,
+ 1.3047397166100174
+ ]
+ },
+ "startArrowhead": null,
+ "endArrowhead": "triangle",
+ "elbowed": true
+ },
+ {
+ "id": "qZECMiSPYv5xtI2SdmWaF",
+ "type": "text",
+ "x": 857.2693098567693,
+ "y": 792.090696927015,
+ "width": 149.59979248046875,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0o",
+ "roundness": null,
+ "seed": 919696873,
+ "version": 54,
+ "versionNonce": 439616393,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232331990,
+ "link": null,
+ "locked": false,
+ "text": "localhost:${port}",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "localhost:${port}",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "i3ZfNQCXI3YM8xcsfaqQI",
+ "type": "rectangle",
+ "x": 81.46651927120627,
+ "y": 84.26010075734206,
+ "width": 120.33060250931145,
+ "height": 831.4481962291687,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dotted",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "X6Y974B7_qQeqQyAt6VE-"
+ ],
+ "frameId": null,
+ "index": "b0oG",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 2025404199,
+ "version": 220,
+ "versionNonce": 215592169,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232583651,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "_ZI6xSh1xNckXB8Y8U3di",
+ "type": "text",
+ "x": 93.55555599568652,
+ "y": 106.12855668423268,
+ "width": 96.79986572265625,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dotted",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "X6Y974B7_qQeqQyAt6VE-"
+ ],
+ "frameId": null,
+ "index": "b0oV",
+ "roundness": null,
+ "seed": 837775047,
+ "version": 103,
+ "versionNonce": 80095177,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232583651,
+ "link": null,
+ "locked": false,
+ "text": "middlewares",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "middlewares",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "hS4tZVE-j34JGD2eZv1Pr",
+ "type": "rectangle",
+ "x": 87.45459076936322,
+ "y": 166.73837699354343,
+ "width": 102.07944978908449,
+ "height": 41.65778569338423,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "X6Y974B7_qQeqQyAt6VE-"
+ ],
+ "frameId": null,
+ "index": "b0ol",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 972169289,
+ "version": 132,
+ "versionNonce": 52446889,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "JiO2fLU2CdfO7KZaKNr2g"
+ }
+ ],
+ "updated": 1731232583651,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "JiO2fLU2CdfO7KZaKNr2g",
+ "type": "text",
+ "x": 116.35833946857008,
+ "y": 177.56726984023555,
+ "width": 44.271952390670776,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "X6Y974B7_qQeqQyAt6VE-"
+ ],
+ "frameId": null,
+ "index": "b0p",
+ "roundness": null,
+ "seed": 1779170825,
+ "version": 82,
+ "versionNonce": 848529801,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232583651,
+ "link": null,
+ "locked": false,
+ "text": "nginx",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "hS4tZVE-j34JGD2eZv1Pr",
+ "originalText": "nginx",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "7yflbQghmnHCmgRi-PNmF",
+ "type": "rectangle",
+ "x": 88.1860480497744,
+ "y": 231.2524387352739,
+ "width": 102.07944978908449,
+ "height": 41.65778569338423,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "X6Y974B7_qQeqQyAt6VE-"
+ ],
+ "frameId": null,
+ "index": "b0pV",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 130766985,
+ "version": 156,
+ "versionNonce": 1549496425,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "1_z07xQvl9Q32ABYFQPRS"
+ }
+ ],
+ "updated": 1731232583651,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "1_z07xQvl9Q32ABYFQPRS",
+ "type": "text",
+ "x": 126.00978514276483,
+ "y": 242.08133158196603,
+ "width": 26.431975603103638,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "X6Y974B7_qQeqQyAt6VE-"
+ ],
+ "frameId": null,
+ "index": "b0q",
+ "roundness": null,
+ "seed": 2009161577,
+ "version": 110,
+ "versionNonce": 373521225,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232583651,
+ "link": null,
+ "locked": false,
+ "text": "...",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "7yflbQghmnHCmgRi-PNmF",
+ "originalText": "...",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "vceXNWGdzljT9ZqfEBMvL",
+ "type": "rectangle",
+ "x": -135.52234568412212,
+ "y": 83.7675667723251,
+ "width": 120.33060250931145,
+ "height": 831.4481962291687,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0v",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 816909959,
+ "version": 503,
+ "versionNonce": 23216295,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "5LP1X5z6RB2aalWT9ei0l",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1731232565518,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "-4ld7yicuN09NWzzlmwsL",
+ "type": "text",
+ "x": -116.79766994347722,
+ "y": 103.25301533741276,
+ "width": 66.17998164892197,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0w",
+ "roundness": null,
+ "seed": 1632418217,
+ "version": 587,
+ "versionNonce": 279201255,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232591920,
+ "link": null,
+ "locked": false,
+ "text": "remote",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "remote",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "oNZN6L3k1A2noJxLfBjTg",
+ "type": "rectangle",
+ "x": -120.59924207850622,
+ "y": 151.94446444272577,
+ "width": 85.83340768018998,
+ "height": 59.7899413618012,
+ "angle": 0,
+ "strokeColor": "#846358",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [
+ "08x_2b5P145Arwkv1trFC"
+ ],
+ "frameId": null,
+ "index": "b0x",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 1382850599,
+ "version": 954,
+ "versionNonce": 799960455,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232588933,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "QoRLi83c_yuTaw7uL5wm6",
+ "type": "text",
+ "x": -95.61538930470556,
+ "y": 170.33000764406412,
+ "width": 35.819975316524506,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "08x_2b5P145Arwkv1trFC"
+ ],
+ "frameId": null,
+ "index": "b0y",
+ "roundness": null,
+ "seed": 1146356551,
+ "version": 1021,
+ "versionNonce": 649405607,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232588933,
+ "link": null,
+ "locked": false,
+ "text": "web",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "web",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "5LP1X5z6RB2aalWT9ei0l",
+ "type": "arrow",
+ "x": -10.191743174810625,
+ "y": 499.39166488690944,
+ "width": 312.55280910607644,
+ "height": 0.6826210288922425,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b0z",
+ "roundness": null,
+ "seed": 607912455,
+ "version": 152,
+ "versionNonce": 885101511,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "K6RyM8pWTcSSez33shdEn"
+ }
+ ],
+ "updated": 1731232565518,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 156.27640455303813,
+ 0
+ ],
+ [
+ 156.27640455303813,
+ 0.6826210288922425
+ ],
+ [
+ 312.55280910607644,
+ 0.6826210288922425
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": {
+ "elementId": "vceXNWGdzljT9ZqfEBMvL",
+ "focus": -0.00024054415044388443,
+ "gap": 5.000000000000007,
+ "fixedPoint": [
+ 1.0415521895156565,
+ 0.4998797279247781
+ ]
+ },
+ "endBinding": {
+ "elementId": "CKMCt3HyNz7Gnpxj1D1dF",
+ "focus": 0.00024017453002184118,
+ "gap": 5.000000000000114,
+ "fixedPoint": [
+ -0.0041926419052197164,
+ 0.4998799127349891
+ ]
+ },
+ "startArrowhead": null,
+ "endArrowhead": "triangle",
+ "elbowed": true
+ },
+ {
+ "id": "K6RyM8pWTcSSez33shdEn",
+ "type": "text",
+ "x": 103.60259819593156,
+ "y": 479.224328978765,
+ "width": 176.23976111412048,
+ "height": 40,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b10",
+ "roundness": null,
+ "seed": 3199081,
+ "version": 58,
+ "versionNonce": 1486961449,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1731232549421,
+ "link": null,
+ "locked": false,
+ "text": "domain / ipv4 addr /\nipv6 addr",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "5LP1X5z6RB2aalWT9ei0l",
+ "originalText": "domain / ipv4 addr / ipv6 addr",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "qs2K8DtoGY_SVtKXOFZd8",
+ "type": "arrow",
+ "x": 1033.7418393547046,
+ "y": 313.1860383581939,
+ "width": 0.05157682453682355,
+ "height": 87.51576982280005,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 4,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b17",
+ "roundness": null,
+ "seed": 1161711474,
+ "version": 639,
+ "versionNonce": 1761949874,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "kmG4UT-WRv0dlwDysR6Pe"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0.05157682453682355,
+ 87.51576982280005
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": {
+ "elementId": "eGa6jMhupqqyTqSf1c4Vp",
+ "focus": -0.012930735115086384,
+ "gap": 3.160173189902025,
+ "fixedPoint": null
+ },
+ "endBinding": {
+ "elementId": "E_kwiFtlRqioM7mcOWGn7",
+ "focus": 0.012317501693059398,
+ "gap": 3.9907847284173386,
+ "fixedPoint": null
+ },
+ "startArrowhead": "bar",
+ "endArrowhead": "bar",
+ "elbowed": false
+ },
+ {
+ "id": "kmG4UT-WRv0dlwDysR6Pe",
+ "type": "text",
+ "x": 972.2545592715264,
+ "y": 371.8257499984128,
+ "width": 123.40783953666687,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 4,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b18",
+ "roundness": null,
+ "seed": 1433844398,
+ "version": 19,
+ "versionNonce": 1461810418,
+ "isDeleted": false,
+ "boundElements": null,
+ "updated": 1732807481799,
+ "link": null,
+ "locked": false,
+ "text": "container mode",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "qs2K8DtoGY_SVtKXOFZd8",
+ "originalText": "container mode",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "q1aFZZIw1PuMuAUysXiHL",
+ "type": "arrow",
+ "x": 1310.1552467271904,
+ "y": 313.2438139809639,
+ "width": 3.3301372618125242,
+ "height": 85.8502442779257,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 4,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b19",
+ "roundness": null,
+ "seed": 126174254,
+ "version": 532,
+ "versionNonce": 1266260850,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "suSaWTl4IH2ffRzu0yfkz"
+ }
+ ],
+ "updated": 1732807792128,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 3.3301372618125242,
+ 85.8502442779257
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": {
+ "elementId": "Q4UqIB_UJkuB4HQyZdBu-",
+ "focus": 0.07825066820981601,
+ "gap": 1,
+ "fixedPoint": null
+ },
+ "endBinding": {
+ "elementId": "E_kwiFtlRqioM7mcOWGn7",
+ "focus": 0.7196438925888313,
+ "gap": 5.598534650521685,
+ "fixedPoint": null
+ },
+ "startArrowhead": "bar",
+ "endArrowhead": "bar",
+ "elbowed": false
+ },
+ {
+ "id": "suSaWTl4IH2ffRzu0yfkz",
+ "type": "text",
+ "x": 1250.459574542399,
+ "y": 369.2855585557687,
+ "width": 123.40783953666687,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "solid",
+ "strokeWidth": 4,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b1A",
+ "roundness": null,
+ "seed": 1659407982,
+ "version": 24,
+ "versionNonce": 1032981294,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807481799,
+ "link": null,
+ "locked": false,
+ "text": "container mode",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "q1aFZZIw1PuMuAUysXiHL",
+ "originalText": "container mode",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "rQlz4Pp79b_1m_Mi2BEsC",
+ "type": "diamond",
+ "x": 880.323374915715,
+ "y": 242.0327557280478,
+ "width": 37.703125,
+ "height": 31.58203125,
+ "angle": 0,
+ "strokeColor": "#1971c2",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "8WzoSYeWk0DdDLpXR_px0",
+ "8_bjPGcX2IYpWYKHZk9As",
+ "_YKpNuHtvIUaG0b1029Jm",
+ "4kmIbgh-VkD7HY3ZqcPrc"
+ ],
+ "frameId": null,
+ "index": "b1C",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1808667374,
+ "version": 1571,
+ "versionNonce": 526684530,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807557458,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "IyMcXvqwrov2KVMPXWH6C",
+ "type": "text",
+ "x": 840.8762830286024,
+ "y": 248.79287112492298,
+ "width": 28.916445314884186,
+ "height": 49.22233362576761,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "8QUsYA7_SRpuI6SSN6dy9",
+ "QEtJKDXJL9pnQrRFBrDk4",
+ "w1jD_wa3LdYsC3Mlk6tfL",
+ "1pOZe_qQCWHFWsmGKcVTi"
+ ],
+ "frameId": null,
+ "index": "b1D",
+ "roundness": null,
+ "seed": 1093255474,
+ "version": 1547,
+ "versionNonce": 578351410,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807631041,
+ "link": null,
+ "locked": false,
+ "text": "80\n8081\n8444",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "80\n8081\n8444",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "hb1fBolYNCc0fzrjIStpn",
+ "type": "text",
+ "x": 931.1026168198915,
+ "y": 247.42647890553073,
+ "width": 28.916445314884186,
+ "height": 49.22233362576761,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "iQrY6kT1f4Ok9hOLRxehB",
+ "qJYhyhVoBW3E8TqmE21wT",
+ "ayCt_6aj6iHP9dCK_SAQ9",
+ "rgSY6L8sOikz6eNUQaIWD"
+ ],
+ "frameId": null,
+ "index": "b1F",
+ "roundness": null,
+ "seed": 273337582,
+ "version": 1575,
+ "versionNonce": 1918518002,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807628190,
+ "link": null,
+ "locked": false,
+ "text": "80\n8081\n8444",
+ "fontSize": 13.12595563353803,
+ "fontFamily": 8,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "80\n8081\n8444",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "S0fGSdt3bAdiCGHA8oNef",
+ "type": "rectangle",
+ "x": 976.0145747988004,
+ "y": 278.8149105268659,
+ "width": 118.80193558682913,
+ "height": 30.613576472610134,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#b2f2bb",
+ "fillStyle": "cross-hatch",
+ "strokeWidth": 1,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b1G",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 1072041838,
+ "version": 141,
+ "versionNonce": 428918830,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "jq6FPUzRdWlZZ6-q438mj"
+ }
+ ],
+ "updated": 1732807700419,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "jq6FPUzRdWlZZ6-q438mj",
+ "type": "text",
+ "x": 986.8796045676941,
+ "y": 284.12169876317097,
+ "width": 97.07187604904175,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#2f9e44",
+ "backgroundColor": "#d0bfff",
+ "fillStyle": "cross-hatch",
+ "strokeWidth": 1,
+ "strokeStyle": "dashed",
+ "roughness": 2,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b1H",
+ "roundness": null,
+ "seed": 1023256882,
+ "version": 109,
+ "versionNonce": 1074420850,
+ "isDeleted": false,
+ "boundElements": null,
+ "updated": 1732807694990,
+ "link": null,
+ "locked": false,
+ "text": "bridge mode",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "S0fGSdt3bAdiCGHA8oNef",
+ "originalText": "bridge mode",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "6bBUg4xR6UT88Aen5T8bV",
+ "type": "text",
+ "x": 603.9731122917782,
+ "y": 205.49932756770806,
+ "width": 219.8798644542694,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#96f2d7",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 2,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "vteo9Bjeige-16NGFvieH"
+ ],
+ "frameId": null,
+ "index": "b1I",
+ "roundness": null,
+ "seed": 1813215470,
+ "version": 347,
+ "versionNonce": 362623086,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1732807815840,
+ "link": null,
+ "locked": false,
+ "text": "shared virtual network",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "shared virtual network",
+ "autoResize": true,
+ "lineHeight": 1.25
+ }
+ ],
+ "appState": {
+ "gridSize": 20,
+ "gridStep": 5,
+ "gridModeEnabled": false,
+ "viewBackgroundColor": "#ffffff"
+ },
+ "files": {}
+}
\ No newline at end of file
diff --git a/imgs/docker-container.svg b/imgs/docker-container.svg
new file mode 100644
index 0000000..8ce09cb
--- /dev/null
+++ b/imgs/docker-container.svg
@@ -0,0 +1,11 @@
+
\ No newline at end of file
diff --git a/imgs/password.png b/imgs/password.png
new file mode 100644
index 0000000..58e5a4a
Binary files /dev/null and b/imgs/password.png differ
diff --git a/imgs/pkce.png b/imgs/pkce.png
new file mode 100644
index 0000000..6f2f710
Binary files /dev/null and b/imgs/pkce.png differ
diff --git a/start-services.sh b/start-services.sh
index 568f34d..570b290 100644
--- a/start-services.sh
+++ b/start-services.sh
@@ -44,7 +44,7 @@ configure_oauth2_playground() {
' "$PLAYGROUND_CONFIG_FILE" > "$PLAYGROUND_CONFIG_FILE.tmp" && mv "$PLAYGROUND_CONFIG_FILE.tmp" "$PLAYGROUND_CONFIG_FILE"
# 仅在 trust_domain 中不存在时追加新值
- jq --arg new_domain "${OAUTH_SERVER_URL}" '
+ jq --arg new_domain "${OAUTH_SERVER_HOST}:${OAUTH_SERVER_PORT}" '
if .trust_domain | index($new_domain) == null then
.trust_domain += [$new_domain]
else