From 09831894938f877ed6f00f7a280930a8d0164356 Mon Sep 17 00:00:00 2001
From: okxlin <61420215+okxlin@users.noreply.github.com>
Date: Thu, 3 Aug 2023 11:03:14 +0800
Subject: [PATCH] =?UTF-8?q?feat:=E6=B7=BB=E5=8A=A0ChatGPT=20Web=20(#274)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/chatgpt-web/README.md | 355 +++++++++++++++++++++
apps/chatgpt-web/data.yml | 20 ++
apps/chatgpt-web/latest/data.yml | 103 ++++++
apps/chatgpt-web/latest/docker-compose.yml | 29 ++
apps/chatgpt-web/logo.png | Bin 0 -> 20614 bytes
5 files changed, 507 insertions(+)
create mode 100644 apps/chatgpt-web/README.md
create mode 100644 apps/chatgpt-web/data.yml
create mode 100644 apps/chatgpt-web/latest/data.yml
create mode 100644 apps/chatgpt-web/latest/docker-compose.yml
create mode 100644 apps/chatgpt-web/logo.png
diff --git a/apps/chatgpt-web/README.md b/apps/chatgpt-web/README.md
new file mode 100644
index 00000000..5ada9b3b
--- /dev/null
+++ b/apps/chatgpt-web/README.md
@@ -0,0 +1,355 @@
+# ChatGPT Web
+
+> 声明:此项目只发布于 GitHub,基于 MIT 协议,免费且作为开源学习使用。并且不会有任何形式的卖号、付费服务、讨论群、讨论组等行为。谨防受骗。
+
+更多功能:[chatgpt-web-plus](https://github.com/Chanzhaoyu/chatgpt-web-plus)
+
+![cover](https://github.com/Chanzhaoyu/chatgpt-web/raw/main/docs/c1.png)
+![cover2](https://github.com/Chanzhaoyu/chatgpt-web/raw/main/docs/c2.png)
+
+- [ChatGPT Web](#chatgpt-web)
+ - [介绍](#介绍)
+ - [待实现路线](#待实现路线)
+ - [前置要求](#前置要求)
+ - [Node](#node)
+ - [PNPM](#pnpm)
+ - [填写密钥](#填写密钥)
+ - [安装依赖](#安装依赖)
+ - [后端](#后端)
+ - [前端](#前端)
+ - [测试环境运行](#测试环境运行)
+ - [后端服务](#后端服务)
+ - [前端网页](#前端网页)
+ - [环境变量](#环境变量)
+ - [打包](#打包)
+ - [使用 Docker](#使用-docker)
+ - [Docker 参数示例](#docker-参数示例)
+ - [Docker build \& Run](#docker-build--run)
+ - [Docker compose](#docker-compose)
+ - [防止爬虫抓取](#防止爬虫抓取)
+ - [使用 Railway 部署](#使用-railway-部署)
+ - [Railway 环境变量](#railway-环境变量)
+ - [手动打包](#手动打包)
+ - [后端服务](#后端服务-1)
+ - [前端网页](#前端网页-1)
+ - [常见问题](#常见问题)
+ - [参与贡献](#参与贡献)
+ - [赞助](#赞助)
+ - [License](#license)
+## 介绍
+
+支持双模型,提供了两种非官方 `ChatGPT API` 方法
+
+| 方式 | 免费? | 可靠性 | 质量 |
+| --------------------------------------------- | ------ | ---------- | ---- |
+| `ChatGPTAPI(gpt-3.5-turbo-0301)` | 否 | 可靠 | 相对较笨 |
+| `ChatGPTUnofficialProxyAPI(网页 accessToken)` | 是 | 相对不可靠 | 聪明 |
+
+对比:
+1. `ChatGPTAPI` 使用 `gpt-3.5-turbo` 通过 `OpenAI` 官方 `API` 调用 `ChatGPT`
+2. `ChatGPTUnofficialProxyAPI` 使用非官方代理服务器访问 `ChatGPT` 的后端`API`,绕过`Cloudflare`(依赖于第三方服务器,并且有速率限制)
+
+警告:
+1. 你应该首先使用 `API` 方式
+2. 使用 `API` 时,如果网络不通,那是国内被墙了,你需要自建代理,绝对不要使用别人的公开代理,那是危险的。
+3. 使用 `accessToken` 方式时反向代理将向第三方暴露您的访问令牌,这样做应该不会产生任何不良影响,但在使用这种方法之前请考虑风险。
+4. 使用 `accessToken` 时,不管你是国内还是国外的机器,都会使用代理。默认代理为 [pengzhile](https://github.com/pengzhile) 大佬的 `https://ai.fakeopen.com/api/conversation`,这不是后门也不是监听,除非你有能力自己翻过 `CF` 验证,用前请知悉。[社区代理](https://github.com/transitive-bullshit/chatgpt-api#reverse-proxy)(注意:只有这两个是推荐,其他第三方来源,请自行甄别)
+5. 把项目发布到公共网络时,你应该设置 `AUTH_SECRET_KEY` 变量添加你的密码访问权限,你也应该修改 `index.html` 中的 `title`,防止被关键词搜索到。
+
+切换方式:
+1. 进入 `service/.env.example` 文件,复制内容到 `service/.env` 文件
+2. 使用 `OpenAI API Key` 请填写 `OPENAI_API_KEY` 字段 [(获取 apiKey)](https://platform.openai.com/overview)
+3. 使用 `Web API` 请填写 `OPENAI_ACCESS_TOKEN` 字段 [(获取 accessToken)](https://chat.openai.com/api/auth/session)
+4. 同时存在时以 `OpenAI API Key` 优先
+
+环境变量:
+
+全部参数变量请查看或[这里](#环境变量)
+
+```
+/service/.env.example
+```
+
+## 待实现路线
+[✓] 双模型
+
+[✓] 多会话储存和上下文逻辑
+
+[✓] 对代码等消息类型的格式化美化处理
+
+[✓] 访问权限控制
+
+[✓] 数据导入、导出
+
+[✓] 保存消息到本地图片
+
+[✓] 界面多语言
+
+[✓] 界面主题
+
+[✗] More...
+
+## 前置要求
+
+### Node
+
+`node` 需要 `^16 || ^18 || ^19` 版本(`node >= 14` 需要安装 [fetch polyfill](https://github.com/developit/unfetch#usage-as-a-polyfill)),使用 [nvm](https://github.com/nvm-sh/nvm) 可管理本地多个 `node` 版本
+
+```shell
+node -v
+```
+
+### PNPM
+如果你没有安装过 `pnpm`
+```shell
+npm install pnpm -g
+```
+
+### 填写密钥
+获取 `Openai Api Key` 或 `accessToken` 并填写本地环境变量 [跳转](#介绍)
+
+```
+# service/.env 文件
+
+# OpenAI API Key - https://platform.openai.com/overview
+OPENAI_API_KEY=
+
+# change this to an `accessToken` extracted from the ChatGPT site's `https://chat.openai.com/api/auth/session` response
+OPENAI_ACCESS_TOKEN=
+```
+
+## 安装依赖
+
+> 为了简便 `后端开发人员` 的了解负担,所以并没有采用前端 `workspace` 模式,而是分文件夹存放。如果只需要前端页面做二次开发,删除 `service` 文件夹即可。
+
+### 后端
+
+进入文件夹 `/service` 运行以下命令
+
+```shell
+pnpm install
+```
+
+### 前端
+根目录下运行以下命令
+```shell
+pnpm bootstrap
+```
+
+## 测试环境运行
+### 后端服务
+
+进入文件夹 `/service` 运行以下命令
+
+```shell
+pnpm start
+```
+
+### 前端网页
+根目录下运行以下命令
+```shell
+pnpm dev
+```
+
+## 环境变量
+
+`API` 可用:
+
+- `OPENAI_API_KEY` 和 `OPENAI_ACCESS_TOKEN` 二选一
+- `OPENAI_API_MODEL` 设置模型,可选,默认:`gpt-3.5-turbo`
+- `OPENAI_API_BASE_URL` 设置接口地址,可选,默认:`https://api.openai.com`
+- `OPENAI_API_DISABLE_DEBUG` 设置接口关闭 debug 日志,可选,默认:empty 不关闭
+
+`ACCESS_TOKEN` 可用:
+
+- `OPENAI_ACCESS_TOKEN` 和 `OPENAI_API_KEY` 二选一,同时存在时,`OPENAI_API_KEY` 优先
+- `API_REVERSE_PROXY` 设置反向代理,可选,默认:`https://ai.fakeopen.com/api/conversation`,[社区](https://github.com/transitive-bullshit/chatgpt-api#reverse-proxy)(注意:只有这两个是推荐,其他第三方来源,请自行甄别)
+
+通用:
+
+- `AUTH_SECRET_KEY` 访问权限密钥,可选
+- `MAX_REQUEST_PER_HOUR` 每小时最大请求次数,可选,默认无限
+- `TIMEOUT_MS` 超时,单位毫秒,可选
+- `SOCKS_PROXY_HOST` 和 `SOCKS_PROXY_PORT` 一起时生效,可选
+- `SOCKS_PROXY_PORT` 和 `SOCKS_PROXY_HOST` 一起时生效,可选
+- `HTTPS_PROXY` 支持 `http`,`https`, `socks5`,可选
+- `ALL_PROXY` 支持 `http`,`https`, `socks5`,可选
+
+## 打包
+
+### 使用 Docker
+
+#### Docker 参数示例
+
+![docker](https://github.com/Chanzhaoyu/chatgpt-web/raw/main/docs/docker.png)
+
+#### Docker build & Run
+
+```bash
+docker build -t chatgpt-web .
+
+# 前台运行
+docker run --name chatgpt-web --rm -it -p 127.0.0.1:3002:3002 --env OPENAI_API_KEY=your_api_key chatgpt-web
+
+# 后台运行
+docker run --name chatgpt-web -d -p 127.0.0.1:3002:3002 --env OPENAI_API_KEY=your_api_key chatgpt-web
+
+# 运行地址
+http://localhost:3002/
+```
+
+#### Docker compose
+
+[Hub 地址](https://hub.docker.com/repository/docker/chenzhaoyu94/chatgpt-web/general)
+
+```yml
+version: '3'
+
+services:
+ app:
+ image: chenzhaoyu94/chatgpt-web # 总是使用 latest ,更新时重新 pull 该 tag 镜像即可
+ ports:
+ - 127.0.0.1:3002:3002
+ environment:
+ # 二选一
+ OPENAI_API_KEY: sk-xxx
+ # 二选一
+ OPENAI_ACCESS_TOKEN: xxx
+ # API接口地址,可选,设置 OPENAI_API_KEY 时可用
+ OPENAI_API_BASE_URL: xxx
+ # API模型,可选,设置 OPENAI_API_KEY 时可用,https://platform.openai.com/docs/models
+ # gpt-4, gpt-4-0314, gpt-4-0613, gpt-4-32k, gpt-4-32k-0314, gpt-4-32k-0613, gpt-3.5-turbo-16k, gpt-3.5-turbo-16k-0613, gpt-3.5-turbo, gpt-3.5-turbo-0301, gpt-3.5-turbo-0613, text-davinci-003, text-davinci-002, code-davinci-002
+ OPENAI_API_MODEL: xxx
+ # 反向代理,可选
+ API_REVERSE_PROXY: xxx
+ # 访问权限密钥,可选
+ AUTH_SECRET_KEY: xxx
+ # 每小时最大请求次数,可选,默认无限
+ MAX_REQUEST_PER_HOUR: 0
+ # 超时,单位毫秒,可选
+ TIMEOUT_MS: 60000
+ # Socks代理,可选,和 SOCKS_PROXY_PORT 一起时生效
+ SOCKS_PROXY_HOST: xxx
+ # Socks代理端口,可选,和 SOCKS_PROXY_HOST 一起时生效
+ SOCKS_PROXY_PORT: xxx
+ # HTTPS 代理,可选,支持 http,https,socks5
+ HTTPS_PROXY: http://xxx:7890
+```
+- `OPENAI_API_BASE_URL` 可选,设置 `OPENAI_API_KEY` 时可用
+- `OPENAI_API_MODEL` 可选,设置 `OPENAI_API_KEY` 时可用
+
+#### 防止爬虫抓取
+
+**nginx**
+
+将下面配置填入nginx配置文件中,可以参考 `docker-compose/nginx/nginx.conf` 文件中添加反爬虫的方法
+
+```
+ # 防止爬虫抓取
+ if ($http_user_agent ~* "360Spider|JikeSpider|Spider|spider|bot|Bot|2345Explorer|curl|wget|webZIP|qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot|NSPlayer|bingbot")
+ {
+ return 403;
+ }
+```
+
+### 使用 Railway 部署
+
+[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template/yytmgc)
+
+#### Railway 环境变量
+
+| 环境变量名称 | 必填 | 备注 |
+| --------------------- | ---------------------- | -------------------------------------------------------------------------------------------------- |
+| `PORT` | 必填 | 默认 `3002`
+| `AUTH_SECRET_KEY` | 可选 | 访问权限密钥 |
+| `MAX_REQUEST_PER_HOUR` | 可选 | 每小时最大请求次数,可选,默认无限 |
+| `TIMEOUT_MS` | 可选 | 超时时间,单位毫秒 |
+| `OPENAI_API_KEY` | `OpenAI API` 二选一 | 使用 `OpenAI API` 所需的 `apiKey` [(获取 apiKey)](https://platform.openai.com/overview) |
+| `OPENAI_ACCESS_TOKEN` | `Web API` 二选一 | 使用 `Web API` 所需的 `accessToken` [(获取 accessToken)](https://chat.openai.com/api/auth/session) |
+| `OPENAI_API_BASE_URL` | 可选,`OpenAI API` 时可用 | `API`接口地址 |
+| `OPENAI_API_MODEL` | 可选,`OpenAI API` 时可用 | `API`模型 |
+| `API_REVERSE_PROXY` | 可选,`Web API` 时可用 | `Web API` 反向代理地址 [详情](https://github.com/transitive-bullshit/chatgpt-api#reverse-proxy) |
+| `SOCKS_PROXY_HOST` | 可选,和 `SOCKS_PROXY_PORT` 一起时生效 | Socks代理 |
+| `SOCKS_PROXY_PORT` | 可选,和 `SOCKS_PROXY_HOST` 一起时生效 | Socks代理端口 |
+| `SOCKS_PROXY_USERNAME` | 可选,和 `SOCKS_PROXY_HOST` 一起时生效 | Socks代理用户名 |
+| `SOCKS_PROXY_PASSWORD` | 可选,和 `SOCKS_PROXY_HOST` 一起时生效 | Socks代理密码 |
+| `HTTPS_PROXY` | 可选 | HTTPS 代理,支持 http,https, socks5 |
+| `ALL_PROXY` | 可选 | 所有代理 代理,支持 http,https, socks5 |
+
+> 注意: `Railway` 修改环境变量会重新 `Deploy`
+
+### 手动打包
+#### 后端服务
+> 如果你不需要本项目的 `node` 接口,可以省略如下操作
+
+复制 `service` 文件夹到你有 `node` 服务环境的服务器上。
+
+```shell
+# 安装
+pnpm install
+
+# 打包
+pnpm build
+
+# 运行
+pnpm prod
+```
+
+PS: 不进行打包,直接在服务器上运行 `pnpm start` 也可
+
+#### 前端网页
+
+1、修改根目录下 `.env` 文件中的 `VITE_GLOB_API_URL` 为你的实际后端接口地址
+
+2、根目录下运行以下命令,然后将 `dist` 文件夹内的文件复制到你网站服务的根目录下
+
+[参考信息](https://cn.vitejs.dev/guide/static-deploy.html#building-the-app)
+
+```shell
+pnpm build
+```
+
+## 常见问题
+Q: 为什么 `Git` 提交总是报错?
+
+A: 因为有提交信息验证,请遵循 [Commit 指南](https://github.com/Chanzhaoyu/chatgpt-web/blob/main/CONTRIBUTING.md)
+
+Q: 如果只使用前端页面,在哪里改请求接口?
+
+A: 根目录下 `.env` 文件中的 `VITE_GLOB_API_URL` 字段。
+
+Q: 文件保存时全部爆红?
+
+A: `vscode` 请安装项目推荐插件,或手动安装 `Eslint` 插件。
+
+Q: 前端没有打字机效果?
+
+A: 一种可能原因是经过 Nginx 反向代理,开启了 buffer,则 Nginx 会尝试从后端缓冲一定大小的数据再发送给浏览器。请尝试在反代参数后添加 `proxy_buffering off;`,然后重载 Nginx。其他 web server 配置同理。
+
+## 参与贡献
+
+贡献之前请先阅读 [贡献指南](https://github.com/Chanzhaoyu/chatgpt-web/blob/main/CONTRIBUTING.md)
+
+感谢所有做过贡献的人!
+
+
+
+
+
+## 赞助
+
+如果你觉得这个项目对你有帮助,并且情况允许的话,可以给我一点点支持,总之非常感谢支持~
+
+
+
+
+
WeChat Pay
+
+
+
+
Alipay
+
+
+
+## License
+MIT © [ChenZhaoYu](https://github.com/Chanzhaoyu/chatgpt-web/blob/main/license)
diff --git a/apps/chatgpt-web/data.yml b/apps/chatgpt-web/data.yml
new file mode 100644
index 00000000..b8afa85c
--- /dev/null
+++ b/apps/chatgpt-web/data.yml
@@ -0,0 +1,20 @@
+name: ChatGPT Web
+tags:
+ - 工具
+title: 使用express和vue3搭建的支持ChatGPT双模型演示网页
+type: 工具
+description: 使用express和vue3搭建的支持ChatGPT双模型演示网页
+additionalProperties:
+ key: chatgpt-web
+ name: ChatGPT Web
+ tags:
+ - Tool
+ shortDescZh: 使用express和vue3搭建的支持ChatGPT双模型演示网页
+ shortDescEn: ChatGPT-enabled dual-model demo page built with express and vue3
+ type: tool
+ crossVersionUpdate: true
+ limit: 0
+ recommend: 0
+ website: https://github.com/Chanzhaoyu/chatgpt-web
+ github: https://github.com/Chanzhaoyu/chatgpt-web
+ document: https://github.com/Chanzhaoyu/chatgpt-web
diff --git a/apps/chatgpt-web/latest/data.yml b/apps/chatgpt-web/latest/data.yml
new file mode 100644
index 00000000..8a8d6fec
--- /dev/null
+++ b/apps/chatgpt-web/latest/data.yml
@@ -0,0 +1,103 @@
+additionalProperties:
+ formFields:
+ - default: 40021
+ edit: true
+ envKey: PANEL_APP_PORT_HTTP
+ labelEn: WebUI Port
+ labelZh: 网页端口
+ required: true
+ rule: paramPort
+ type: number
+ - default: ''
+ edit: true
+ envKey: ACCESS_TOKEN
+ labelEn: OPENAI ACCESS TOKEN (fill in at least one with OPENAI API KEY)(https://chat.openai.com/api/auth/session)
+ labelZh: OPENAI ACCESS TOKEN(与OPENAI API KEY至少填一个)(https://chat.openai.com/api/auth/session)
+ required: false
+ type: text
+ - default: https://bypass.duti.tech/api/conversation
+ edit: true
+ envKey: REVERSE_PROXY
+ labelEn: API reverse proxy, optional (enabled by default when OPENAI ACCESS TOKEN, need to pay attention to availability)
+ labelZh: API反向代理,可选(OPENAI ACCESS TOKEN时默认启用,需要注意可用性)
+ required: false
+ type: text
+ - default: ''
+ edit: true
+ envKey: API_KEY
+ labelEn: OPENAI API KEY (fill in at least one with OPENAI ACCESS TOKEN)
+ labelZh: OPENAI API KEY(与OPENAI ACCESS TOKEN至少填一个)
+ required: false
+ type: text
+ - default: gpt-3.5-turbo
+ edit: true
+ envKey: API_MODEL
+ labelEn: API model, optional, available when setting OPENAI API KEY(https://platform.openai.com/docs/models)
+ labelZh: API模型,可选,设置OPENAI API KEY时可用(https://platform.openai.com/docs/models)
+ required: false
+ type: text
+ - default: https://api.openai.com
+ edit: true
+ envKey: API_BASE_URL
+ labelEn: API interface address, optional, available when setting OPENAI API KEY
+ labelZh: API接口地址,可选,设置OPENAI API KEY时可用
+ required: false
+ type: text
+ - default: chatgptweb
+ edit: true
+ envKey: SECRET_KEY
+ labelEn: Access rights key, optional (recommended)
+ labelZh: 访问权限密钥,可选(强烈建议填写)
+ random: true
+ required: false
+ rule: paramComplexity
+ type: password
+ - default: '0'
+ edit: true
+ envKey: REQUEST_LIMIT
+ labelEn: Maximum number of requests per hour, optional, default unlimited
+ labelZh: 每小时最大请求次数,可选,默认无限
+ required: false
+ type: text
+ - default: '60000'
+ edit: true
+ envKey: TIMEOUT
+ labelEn: Timeout, in milliseconds, optional
+ labelZh: 超时,单位毫秒,可选
+ required: false
+ type: text
+ - default: ''
+ edit: true
+ envKey: PROXY_HOST
+ labelEn: Socks proxy address, optional, effective when combined with Socks proxy port
+ labelZh: Socks代理地址,可选,和Socks代理端口一起时生效
+ required: false
+ type: text
+ - default: ''
+ edit: true
+ envKey: PROXY_PORT
+ labelEn: Socks proxy port, optional, effective when combined with Socks proxy address
+ labelZh: Socks代理端口,可选,和Socks代理地址一起时生效
+ required: false
+ type: text
+ - default: ''
+ edit: true
+ envKey: PROXY_USERNAME
+ labelEn: Socks proxy user name, optional, effective when combined with Socks proxy address
+ labelZh: Socks代理用户名,可选,和Socks代理地址一起时生效
+ required: false
+ type: text
+ - default: ''
+ edit: true
+ envKey: PROXY_PASSWORD
+ labelEn: Socks proxy password, optional, effective when combined with Socks proxy address
+ labelZh: Socks代理密码,可选,和Socks代理地址一起时生效
+ required: false
+ type: text
+ - default: ''
+ edit: true
+ envKey: HTTPS_PROXY
+ labelEn: HTTPS proxy, optional, supports http, https, socks5
+ labelZh: HTTPS代理,可选,支持http,https,socks5
+ required: false
+ type: text
diff --git a/apps/chatgpt-web/latest/docker-compose.yml b/apps/chatgpt-web/latest/docker-compose.yml
new file mode 100644
index 00000000..ec251a23
--- /dev/null
+++ b/apps/chatgpt-web/latest/docker-compose.yml
@@ -0,0 +1,29 @@
+version: "3"
+services:
+ chatgpt-web:
+ container_name: ${CONTAINER_NAME}
+ restart: always
+ networks:
+ - 1panel-network
+ ports:
+ - "${PANEL_APP_PORT_HTTP}:3002"
+ environment:
+ OPENAI_API_KEY: "${API_KEY}"
+ OPENAI_ACCESS_TOKEN: "${ACCESS_TOKEN}"
+ OPENAI_API_BASE_URL: "${API_BASE_URL}"
+ OPENAI_API_MODEL: "${API_MODEL}"
+ API_REVERSE_PROXY: "${REVERSE_PROXY}"
+ AUTH_SECRET_KEY: "${SECRET_KEY}"
+ MAX_REQUEST_PER_HOUR: "${REQUEST_LIMIT}"
+ TIMEOUT_MS: "${TIMEOUT}"
+ SOCKS_PROXY_HOST: "${PROXY_HOST}"
+ SOCKS_PROXY_PORT: "${PROXY_PORT}"
+ SOCKS_PROXY_USERNAME: "${PROXY_USERNAME}"
+ SOCKS_PROXY_PASSWORD: "${PROXY_PASSWORD}"
+ HTTPS_PROXY: "${HTTPS_PROXY}"
+ image: chenzhaoyu94/chatgpt-web:latest
+ labels:
+ createdBy: "Apps"
+networks:
+ 1panel-network:
+ external: true
diff --git a/apps/chatgpt-web/logo.png b/apps/chatgpt-web/logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..75961719d188d72dced0aaec4ec49fcadd24f054
GIT binary patch
literal 20614
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
g)vy9|ec(#Ft@&4*&oF07*qoM6N<$f?Kzj9{>OV
literal 0
KcmV+b0RR6000031