diff --git a/.dockerignore b/.dockerignore index 6c65cef..64eaf08 100644 --- a/.dockerignore +++ b/.dockerignore @@ -12,7 +12,8 @@ node_modules .env.*.local *.log -# Deployment templates and operator documentation are not runtime inputs. -deploy +# Only the static Web server config is a runtime build input. +deploy/* +!deploy/nginx.conf docs .project-docs diff --git a/.gitignore b/.gitignore index f404130..b7d7bb2 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ .env .env.local .env.*.local +/deploy/ack/secrets.production.yaml *.log .DS_Store node_modules/ diff --git a/.project-docs/10-decisions/proposals/20260816-static-frontend-go-api-4f8c2a7d__static-web-go-api.md b/.project-docs/10-decisions/proposals/20260816-static-frontend-go-api-4f8c2a7d__static-web-go-api.md new file mode 100644 index 0000000..51ed82a --- /dev/null +++ b/.project-docs/10-decisions/proposals/20260816-static-frontend-go-api-4f8c2a7d__static-web-go-api.md @@ -0,0 +1,58 @@ +# Proposal: Static Web With Go-Only Runtime APIs + +## Source + +- Task: `20260816-static-frontend-go-api-4f8c2a7d` +- User confirmation: the frontend must be a static page set and every API must + be provided by Go. + +## Proposed Decision + +Replace ADR-003's retained Next.js SSR responsibility with a stricter runtime +boundary: + +- Next.js is a build tool. Its production output is the static `out/` tree. +- An unprivileged Nginx workload serves pages and static assets only. +- The browser calls same-origin `/api`, `/uploads`, and `/generated-results`; + Ingress routes those paths directly to the Go modular monolith. +- Go exclusively owns authentication, authorization, Cookie signing and + validation, PostgreSQL, billing, providers, storage, Webhooks, health, + readiness, and the embedded WorkerLoop. +- Client route guards are presentation behavior only and never an + authorization boundary. +- The Web workload receives no runtime ConfigMap, session Secret, database + credential, provider Secret, or internal Go URL. + +## Evidence + +- Clean `next build` exports every application route as static content. +- Static architecture tests fail if Next Route Handlers, Middleware, server + page imports, image optimization, or a non-same-origin auth seam return. +- The checked-in Go route surface covers every browser request; the single + discovered billing response casing defect was corrected and regression + tested. +- Full Vitest, TypeScript, Go, and ACK assertion suites pass. + +## Future Impact + +- Production Web availability is independent of PostgreSQL, Go internal DNS, + and session-secret injection; API failures become visible client errors + rather than fatal RSC rendering errors. +- New business endpoints must be implemented in Go. Reintroducing Next Route + Handlers, Middleware authentication, or SSR Cookie access violates the + accepted boundary. +- Schema creation remains an operator/CI concern until a dedicated migration + image is justified; it must not reuse the static Web image. + +## Semantic Conflicts + +- ADR-003 currently says Next serves SSR and that static export is a future + choice. +- Canonical current-state and architecture documents still describe the + internal Next-to-Go auth bridge, retained Next Route Handlers, a Migration + Job artifact, and local Node Worker behavior as part of the supported shape. + +## Human Confirmation + +No further confirmation is required. The user explicitly selected this pure +static frontend and Go-only API architecture in the source task. diff --git a/.project-docs/30-worklog/tasks/20260816-static-frontend-go-api-4f8c2a7d.md b/.project-docs/30-worklog/tasks/20260816-static-frontend-go-api-4f8c2a7d.md new file mode 100644 index 0000000..b3eb398 --- /dev/null +++ b/.project-docs/30-worklog/tasks/20260816-static-frontend-go-api-4f8c2a7d.md @@ -0,0 +1,104 @@ +# Task: Convert production frontend to static output backed only by Go APIs + +## Identity + +- Task ID: 20260816-static-frontend-go-api-4f8c2a7d +- Mode: Feature +- Branch: main +- Worktree: D:\Datas\OthersProjects\NianAIGC +- Base commit: 763d2f06486493b77db27aa164a9a2cbbc14a8cf +- Owner: codex +- Status: Ready for Integration + +## Scope + +- Convert the Next.js application to static export with no production SSR, + Middleware, or Route Handler runtime. +- Replace server-rendered authentication/page authorization with a browser + auth module that consumes the same-origin Go `/api/auth/me` contract. +- Keep every existing browser business request on same-origin `/api`, + `/uploads`, and `/generated-results` routes owned by the Go service. +- Serve the exported frontend from an unprivileged Nginx container and update + ACK Web Service, probes, Ingress commentary, and deployment assertions. +- Preserve Go-side authorization, session-version revocation, and HttpOnly + Cookie semantics as the security boundary. + +## Intent And Constraints + +- The user explicitly selected a pure static frontend after the production SSR + login bridge remained operationally fragile. +- The Web workload must have no database credentials, session secret, Go + internal URL, or server-side runtime configuration. +- Browser requests stay same-origin so no CORS or JavaScript token storage is + introduced. +- Client-side route guards are presentation only; Go remains authoritative for + every protected API. +- Existing API response shapes must remain compatible unless a verified Go + parity gap requires a focused backend change. +- Feature mode may update this task record and implementation/deployment docs; + ADR-003 and canonical architecture/current-state promotion require a later + Integration task. + +## Outcome + +- Next.js now emits only a static `out/` site. The production Root Layout and + pages no longer read request Cookies, invoke server authorization, or depend + on Middleware/Route Handlers. +- Added a browser auth Module around same-origin `GET /api/auth/me`; it owns + response validation, safe post-login navigation, shell identity state, and + client-only presentation guards. Go remains the authorization boundary. +- Removed `middleware.ts`, all `app/api/**` handlers, and the dynamic + `/uploads` and `/generated-results` Next handlers. Existing browser fetch + paths remain unchanged and are routed to Go by Ingress. +- Fixed the sole verified browser/Go parity defect: billing adjustment results + now serialize lowercase `wallet` and `entry` fields. +- Replaced the Node production runner with unprivileged Nginx serving `out/`. + The Web Pod has no runtime ConfigMap, session Secret, database credential, or + Go internal URL; it exposes only `/healthz` for workload probes. +- Removed deprecated Node Worker and Node migration ACK manifests that could no + longer run inside the static Web image. Go embeds the WorkerLoop; first schema + creation remains the documented manual SQL operation. +- Renamed the first-deployment session Secret owner from `zhinian-web-auth` to + `zhinian-go-auth` because only Go signs and validates the Cookie. + +## Verification + +- `npm test`: PASS, 53 files / 158 tests. +- `npx tsc --noEmit --incremental false`: PASS. +- Clean `npm run build` after deleting generated `.next` and `out`: PASS, 14/14 + static pages generated and exported; all 12 application routes are static. +- `go test ./...` from `backend/`: PASS for all packages. +- `npm run deploy:check`: PASS, 7 ACK YAML manifests plus static-runtime + assertions. +- `npm run info`: PASS during deployment implementation. +- `git check-ignore -v deploy/ack/secrets.production.yaml`: PASS; the real + first-deployment Secret file is protected by an exact repository rule. +- `git diff --check`: PASS after final implementation and documentation. +- Mandatory read-only `sol_reviewer` result: PASS after three review rounds; + all reported authentication, first-deployment, documentation, storage-risk, + and Secret-ignore blockers were fixed and reverified. +- Docker image construction was not executed because the local Docker daemon + is unavailable. The Dockerfile pins the official unprivileged Nginx + `1.30.4-alpine` runner and its build inputs are covered by deployment checks. + +## Follow-ups + +- Build and smoke the Web image in CI or another host with a Docker daemon. +- Deploy new Web and Go images plus the ACK manifests, then verify anonymous + login, authenticated `/create`, logout, administrator pages, static + `/healthz`, Go `/api/health`, and Go `/api/ready` on the public origin. +- Use a new immutable image tag/digest so `IfNotPresent` cannot retain the old + SSR Web image. +- Unreferenced legacy TypeScript server adapters may be removed in a separate + cleanup after confirming no operator scripts still consume them; they are not + present in the production `out/` image. + +## Promotion Candidates + +- Amend or supersede ADR-003: the accepted frontend responsibility is static + files only, not Next SSR; browser-to-Go same-origin HTTP is the sole runtime + application seam. Human confirmation is already present in this task. +- Update `decision-index.md`, `current-state.md`, `system-overview.md`, + `module-map.md`, and `data-flow.md` to record Nginx static Web, Go-only API + ownership, browser `/api/auth/me`, Go-only session Secret ownership, and + removal of the Node Worker/migration Job manifests. diff --git a/Dockerfile b/Dockerfile index 31fc589..ebcc7c0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,26 +22,14 @@ ENV NEXT_TELEMETRY_DISABLED=1 COPY --from=deps /app/node_modules ./node_modules COPY . . -RUN npm run build && npm prune --omit=dev +RUN npm run build -FROM node:22-alpine AS runner -WORKDIR /app +FROM nginxinc/nginx-unprivileged:1.30.4-alpine AS runner -ENV NODE_ENV=production -ENV NEXT_TELEMETRY_DISABLED=1 -ENV PORT=3000 -ENV ZHINIAN_RUNTIME_DIR=/app/.runtime - -COPY --from=builder /app/package.json /app/package-lock.json ./ -COPY --from=builder /app/node_modules ./node_modules -COPY --from=builder /app/.next ./.next -COPY --from=builder /app/public ./public -COPY --from=builder /app/scripts ./scripts -COPY --from=builder /app/database ./database -COPY --from=builder /app/next.config.ts ./next.config.ts - -RUN mkdir -p /app/.runtime/data /app/.runtime/uploads /app/.runtime/generated-results +COPY deploy/nginx.conf /etc/nginx/nginx.conf +COPY --from=builder /app/out /usr/share/nginx/html EXPOSE 3000 -CMD ["sh", "-c", "npx next start --hostname 0.0.0.0 --port ${PORT:-3000}"] +ENTRYPOINT [] +CMD ["nginx", "-g", "daemon off;"] diff --git a/README.md b/README.md index 938662c..a841339 100644 --- a/README.md +++ b/README.md @@ -16,12 +16,6 @@ Use `/api/health` for process liveness and `/api/ready` for database-backed read ## 启动 -服务器一键部署: - -```bash -bash scripts/deploy.sh -``` - 开发环境: ```bash @@ -39,18 +33,14 @@ http://127.0.0.1:3000 常用命令: ```bash -npm start -npm run start:server -npm run worker npm run build npm test -npm run health -npm run info +npm run deploy:check ``` -`npm start` 会自动先执行一次生产构建,再启动 `http://127.0.0.1:3000`;开发调试建议继续使用 `npm run dev`。 - -Docker 部署默认使用 `docker-compose.yml` 同时启动 Web 服务和 `zhinian-worker` 任务 Worker,访问 `http://服务器IP:3000`。如需修改端口,调整 `.env.local` 中的 `APP_PORT` 和 `NEXT_PUBLIC_APP_URL` 后重新执行 `bash scripts/deploy.sh`。 +`npm run build` 输出纯静态 `out/`。生产镜像使用非 root Nginx 托管该目录,不运行 +Next.js 服务端;浏览器通过同域 `/api` 调用 Go 后端。ACK 发布步骤见 +[`docs/DEPLOYMENT.md`](./docs/DEPLOYMENT.md)。 ## Web MVP 信息架构 @@ -237,7 +227,7 @@ cp .env.example .env.local - `DATABASE_URL`:仅服务端读取的 PostgreSQL 连接串 - `DATABASE_URL` 的 `sslmode` / `sslrootcert`:在同一个连接串中配置 RDS TLS;默认使用 `sslmode=verify-full` -当 `ZHINIAN_DATA_BACKEND=local` 时,应用使用 `.runtime/data/web-app-state.json` 作为单实例开发数据层。生产 `postgres` 模式缺少连接配置会直接失败,不会静默写入本地 JSON。如果 OSS 未配置,上传和 mock 结果会保存到 `.runtime/uploads` 和 `.runtime/generated-results`,并通过 Web 路由提供访问。 +当 `ZHINIAN_DATA_BACKEND=local` 时,应用使用 `.runtime/data/web-app-state.json` 作为单实例开发数据层。生产 `postgres` 模式缺少连接配置会直接失败,不会静默写入本地 JSON。如果 OSS 未配置,上传和 mock 结果会保存到 `.runtime/uploads` 和 `.runtime/generated-results`,并通过 Go 路由提供访问。 ## 数据库 @@ -260,7 +250,9 @@ database/migrations/ ## 任务管理与开放 API -平台支持服务端任务管理:页面和 `/api/v1` 创建任务后只入队,Worker 统一提交供应商、轮询、转存结果、失败重试和 Webhook 回调。生产部署使用 PostgreSQL;本地开发可继续使用 `.runtime/data/web-app-state.json`。 +平台支持服务端任务管理:页面和 `/api/v1` 创建任务后只入队,由 Go 内嵌 WorkerLoop +统一提交供应商、轮询、转存结果、失败重试和 Webhook 回调。生产部署使用 PostgreSQL; +本地开发可继续使用 `.runtime/data/web-app-state.json`。 开放 API 使用 API Key: @@ -282,7 +274,8 @@ ZHINIAN_INTERNAL_WORKER_TOKEN=change-me-worker-token - `POST /api/v1/jobs/[id]/cancel` - `GET /api/v1/openapi.json` -任务创建支持 `Idempotency-Key` 幂等键和 `webhookUrl` 完成回调。Worker 可用 `npm run worker` 常驻运行,或 `npm run worker:once` 单次处理。 +任务创建支持 `Idempotency-Key` 幂等键和 `webhookUrl` 完成回调。后台任务由 Go API +内嵌的 WorkerLoop 处理,不再启动独立 Node Worker。 ## API @@ -319,7 +312,6 @@ ZHINIAN_INTERNAL_WORKER_TOKEN=change-me-worker-token ```bash npm test npm run build -npm run health npm run go:test npm run go:build ``` diff --git a/README.zh-CN.md b/README.zh-CN.md index ec48675..b75082b 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -29,7 +29,7 @@ ## 技术栈 -- Next.js 15(前端:页面、静态资源、SSR) +- Next.js 15(构建期静态导出,生产由 Nginx 托管) - Go 1.21(生产后端:独占 `/api`、`/uploads`、`/generated-results`,内嵌 WorkerLoop,见 `backend/` 与 [`docs/DEPLOYMENT.md`](./docs/DEPLOYMENT.md)) - React 19 - TypeScript @@ -54,77 +54,27 @@ npm run dev -- --hostname 127.0.0.1 --port 3000 http://127.0.0.1:3000 ``` -生产模式: +静态生产构建: ```bash -npm start -``` - -`npm start` 会先执行 `next build`,再启动 `127.0.0.1:3000`。 - -## 服务器一键部署 - -服务器推荐使用 Docker Compose: - -```bash -git clone <你的仓库地址> -cd NianAIGC -bash scripts/deploy.sh -``` - -脚本会自动完成: - -- 创建 `.env.local` -- 创建 `.runtime/data`、`.runtime/uploads`、`.runtime/generated-results` -- 创建 `.runtime/logs` -- 构建 Docker 镜像 -- 使用 `docker compose up -d --build` 后台启动 Web 服务和 Worker 服务 - -默认访问: - -```text -http://服务器IP:3000 -``` - -如果要换端口,可以编辑 `.env.local`: - -```env -APP_PORT=8080 -NEXT_PUBLIC_APP_URL=http://你的服务器IP:8080 -``` - -然后重新执行: - -```bash -bash scripts/deploy.sh -``` - -常用 Docker 命令: - -```bash -docker compose ps -docker compose logs -f zhinian-aigc -docker compose logs -f zhinian-worker -docker compose restart -docker compose down -``` - -如果服务器不用 Docker,也可以用 Node 直接部署: - -```bash -npm ci npm run build -npm run start:server ``` -另开一个进程运行任务 Worker: +构建结果位于 `out/`。生产不运行 Node Web 进程;仓库 Dockerfile +使用非 root Nginx 托管静态文件,浏览器通过同域 `/api` 调用 Go。 + +## 生产部署 + +生产推荐使用 ACK 路径分流: ```bash -npm run worker +docker build -t REGISTRY/PROJECT/zhinian-aigc:TAG . +npm run deploy:check ``` -生产环境建议把 `NEXT_PUBLIC_APP_URL` 设置成真实域名或公网地址,配置 `ZHINIAN_INTERNAL_WORKER_TOKEN`,并把 `.runtime/` 做定期备份。 -部署后如果页面或接口报错,登录后台访问 `/logs` 查看最近错误、请求路径、状态码和错误栈。日志文件默认在 `.runtime/logs/server-events.jsonl`。 +Ingress 将 `/api`、`/uploads`、`/generated-results` 转发给 Go,其余请求转发给 +静态 Web。Web 不接收数据库、会话密钥或其他运行时配置。完整的 RDS、Secret、迁移和 +发布步骤见 [`docs/DEPLOYMENT.md`](./docs/DEPLOYMENT.md)。 ## 常用命令 @@ -132,8 +82,6 @@ npm run worker npm run dev -- --hostname 127.0.0.1 --port 3000 npm test npm run build -npm run health -npm run worker:once npm run info ``` @@ -336,9 +284,10 @@ cp .env.example .env.local ## 项目结构 ```text -app/ Next.js App Router 页面与 API +app/ Next.js App Router 静态页面 +backend/ Go API、持久化与内嵌 WorkerLoop components/ 前端组件 -lib/ 业务逻辑、服务端适配器、接口客户端 +lib/ 前端共享逻辑与浏览器接口客户端 lib/ui/motion.ts GSAP 动效工具层 public/logo/ 品牌 Logo scripts/ 启动、健康检查与信息脚本 @@ -355,8 +304,6 @@ docker-compose.yml 服务器部署编排 ```bash npm test npm run build -npm run health -npm run worker:once ``` 如果本地 dev server 正在运行,建议先停止后再执行生产构建,避免 Next.js dev 缓存与生产构建互相影响。 diff --git a/app/accounts/page.tsx b/app/accounts/page.tsx index bc621df..28c358e 100644 --- a/app/accounts/page.tsx +++ b/app/accounts/page.tsx @@ -1,10 +1,13 @@ +"use client"; + import { AccountManager } from "@/components/account-manager"; -import { hasAdminSessionAccess } from "@/lib/auth/permissions"; -import { requireAppSession } from "@/lib/server/auth/current-user"; +import { BrowserAuthGuard, useBrowserAuth } from "@/components/browser-auth"; -export const dynamic = "force-dynamic"; - -export default async function AccountsPage() { - const session = await requireAppSession(); - return ; +export default function AccountsPage() { + return ; +} + +function AccountsContent() { + const { isAdmin } = useBrowserAuth(); + return ; } diff --git a/app/api/admin/accounts/groups/route.ts b/app/api/admin/accounts/groups/route.ts deleted file mode 100644 index bfe0236..0000000 --- a/app/api/admin/accounts/groups/route.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { jsonError } from "@/lib/server/api"; - -export const runtime = "nodejs"; - -export async function POST() { - return jsonError(Object.assign(new Error("平台账号体系不再使用外部部门接口,请直接管理组织。"), { status: 410 }), 410); -} diff --git a/app/api/admin/accounts/password/route.ts b/app/api/admin/accounts/password/route.ts deleted file mode 100644 index 163267e..0000000 --- a/app/api/admin/accounts/password/route.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api"; -import { requireAdminSession } from "@/lib/server/auth/current-user"; -import { AccountStoreError, getPlatformUserById, updatePlatformUser } from "@/lib/server/account-store"; -import { hasSuperAdminAccess } from "@/lib/auth/permissions"; - -export const runtime = "nodejs"; -export const dynamic = "force-dynamic"; - -export async function POST(request: Request) { - try { - const session = await requireAdminSession(); - const body = await readJsonBody>(request); - const userId = requiredString(body.userId, "账号 ID"); - const target = await getPlatformUserById(userId, { includeDisabled: true }); - if (!target) throw new AccountStoreError("账号不存在。", 404); - if (!hasSuperAdminAccess(session.user) && (session.user.role !== "organization_admin" || target.role !== "user" || target.organizationId !== session.user.organizationId)) { - throw new AccountStoreError("组织管理员只能重置本组织普通用户密码。", 403); - } - const newPassword = requiredString(body.newPassword, "新密码"); - if (newPassword.length < 8) throw new AccountStoreError("新密码至少需要 8 位。", 400); - const user = await updatePlatformUser(userId, { password: newPassword, clearLoginLock: true }); - return jsonOk({ ok: true, userId: user.id }); - } catch (error) { - return jsonError(error, 500, { request, source: "api.admin.accounts.password", logClientErrors: true }); - } -} - -function requiredString(value: unknown, label: string): string { - if (typeof value === "string" && value.trim()) return value.trim(); - throw new AccountStoreError(`${label}不能为空。`, 400); -} diff --git a/app/api/admin/accounts/route.ts b/app/api/admin/accounts/route.ts deleted file mode 100644 index f927af6..0000000 --- a/app/api/admin/accounts/route.ts +++ /dev/null @@ -1,187 +0,0 @@ -import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api"; -import { requireAdminSession } from "@/lib/server/auth/current-user"; -import { - AccountStoreError, - createPlatformUser, - deletePlatformUser, - getPlatformUserById, - listPlatformOrganizations, - listPlatformUsers, - updatePlatformUser, - type PlatformUserFilters -} from "@/lib/server/account-store"; -import { hasSuperAdminAccess } from "@/lib/auth/permissions"; -import type { AuthUser } from "@/lib/auth/session"; -import type { PlatformRole } from "@/lib/types"; - -export const runtime = "nodejs"; -export const dynamic = "force-dynamic"; - -export async function GET(request: Request) { - try { - const session = await requireAdminSession(); - const url = new URL(request.url); - const isSuperAdmin = hasSuperAdminAccess(session.user); - const organizationId = isSuperAdmin - ? optionalString(url.searchParams.get("organizationId")) - : requiredOrganizationId(session.user.organizationId); - const filters: PlatformUserFilters = { organizationId, includeDisabled: true, role: isSuperAdmin ? undefined : "user" }; - const [members, organizations] = await Promise.all([ - listPlatformUsers(filters), - listPlatformOrganizations({ includeDisabled: isSuperAdmin }) - ]); - return jsonOk({ - configured: true, - currentOrganizationId: organizationId || null, - organizations: isSuperAdmin ? organizations.map(publicOrganization) : organizations.filter((item) => item.id === organizationId).map(publicOrganization), - members: members.map(publicUser), - canManageOrganizations: isSuperAdmin, - canAssignOrganizationAdmin: isSuperAdmin, - canCreateSuperAdmin: isSuperAdmin - }); - } catch (error) { - return jsonError(error, 500, { request, source: "api.admin.accounts", logClientErrors: true }); - } -} - -export async function POST(request: Request) { - try { - const session = await requireAdminSession(); - const body = await readJsonBody>(request); - const isSuperAdmin = hasSuperAdminAccess(session.user); - const role = parseRole(body.role, isSuperAdmin ? "user" : "user"); - if (!isSuperAdmin && role !== "user") throw new AccountStoreError("组织管理员只能创建普通用户。", 403); - const organizationId = role === "super_admin" - ? optionalString(body.organizationId) - : isSuperAdmin - ? requiredString(body.organizationId, "组织") - : requiredOrganizationId(session.user.organizationId); - const user = await createPlatformUser({ - phone: requiredString(body.phone, "手机号"), - displayName: requiredString(body.displayName, "显示名称"), - password: requiredString(body.password, "初始密码"), - role, - organizationId, - legacySubject: optionalString(body.legacySubject) - }); - return jsonOk({ ok: true, user: publicUser(user) }, { status: 201 }); - } catch (error) { - return jsonError(error, 500, { request, source: "api.admin.accounts", logClientErrors: true }); - } -} - -export async function PATCH(request: Request) { - try { - const session = await requireAdminSession(); - const body = await readJsonBody>(request); - const target = await getTarget(body); - assertCanManageTarget(session.user, target, "修改"); - const isSuperAdmin = hasSuperAdminAccess(session.user); - const role = body.role === undefined ? undefined : parseRole(body.role, target.role); - if (!isSuperAdmin && role !== undefined && role !== target.role) { - throw new AccountStoreError("组织管理员不能修改账号角色。", 403); - } - if (!isSuperAdmin && body.organizationId !== undefined) { - throw new AccountStoreError("组织管理员不能修改账号归属。", 403); - } - const user = await updatePlatformUser(target.id, { - displayName: optionalString(body.displayName), - role, - organizationId: isSuperAdmin && body.organizationId !== undefined ? optionalString(body.organizationId) : undefined, - status: parseStatus(body.status), - clearLoginLock: body.clearLoginLock === true - }); - return jsonOk({ ok: true, user: publicUser(user) }); - } catch (error) { - return jsonError(error, 500, { request, source: "api.admin.accounts", logClientErrors: true }); - } -} - -export async function PUT(request: Request) { - try { - const session = await requireAdminSession(); - const body = await readJsonBody>(request); - const target = await getTarget(body); - assertCanManageTarget(session.user, target, "变更状态"); - const status = parseStatus(requiredString(body.status, "账号状态")); - if (!status) throw new AccountStoreError("账号状态只能是 active 或 disabled。", 400); - if (target.id === session.user.id && status === "disabled") throw new AccountStoreError("不能停用当前登录账号。", 400); - const user = await updatePlatformUser(target.id, { status, clearLoginLock: status === "active" }); - return jsonOk({ ok: true, user: publicUser(user) }); - } catch (error) { - return jsonError(error, 500, { request, source: "api.admin.accounts", logClientErrors: true }); - } -} - -export async function DELETE(request: Request) { - try { - const session = await requireAdminSession(); - const body = await readJsonBody>(request); - const target = await getTarget(body); - assertCanManageTarget(session.user, target, "删除"); - if (target.id === session.user.id) throw new AccountStoreError("不能删除当前登录账号。", 400); - await deletePlatformUser(target.id); - return jsonOk({ ok: true, archivedOwnerId: target.organizationId ? `archive:${target.organizationId}` : "archive:global" }); - } catch (error) { - return jsonError(error, 500, { request, source: "api.admin.accounts", logClientErrors: true }); - } -} - -async function getTarget(body: Record) { - const id = requiredString(body.userId, "账号 ID"); - const user = await getPlatformUserById(id, { includeDisabled: true }); - if (!user) throw new AccountStoreError("账号不存在。", 404); - return user; -} - -function assertCanManageTarget(actor: AuthUser, target: { id: string; role: PlatformRole; organizationId?: string }, action: string) { - if (hasSuperAdminAccess(actor)) return; - if (actor.role !== "organization_admin" || target.role !== "user" || actor.organizationId !== target.organizationId) { - throw new AccountStoreError(`组织管理员不能${action}该账号。`, 403); - } -} - -function publicOrganization(organization: { id: string; name: string; status: string }) { - return { id: organization.id, name: organization.name, status: organization.status }; -} - -function publicUser(user: { id: string; phone: string; displayName: string; role: PlatformRole; organizationId?: string; status: string; createdAt: string; lastLoginAt?: string; lockedUntil?: string }) { - return { - id: user.id, - phone: user.phone, - displayName: user.displayName, - role: user.role, - organizationId: user.organizationId || null, - status: user.status, - createdAt: user.createdAt, - lastLoginAt: user.lastLoginAt || null, - lockedUntil: user.lockedUntil || null - }; -} - -function parseRole(value: unknown, fallback: PlatformRole): PlatformRole { - if (value === undefined || value === null || value === "") return fallback; - if (value === "super_admin" || value === "organization_admin" || value === "user") return value; - throw new AccountStoreError("账号角色不正确。", 400); -} - -function parseStatus(value: unknown): "active" | "disabled" | undefined { - if (value === undefined || value === null || value === "") return undefined; - if (value === "active" || value === "disabled") return value; - throw new AccountStoreError("账号状态不正确。", 400); -} - -function requiredString(value: unknown, label: string): string { - const normalized = optionalString(value); - if (!normalized) throw new AccountStoreError(`${label}不能为空。`, 400); - return normalized; -} - -function requiredOrganizationId(value: string | undefined): string { - if (!value) throw new AccountStoreError("当前账号没有组织归属。", 403); - return value; -} - -function optionalString(value: unknown): string | undefined { - return typeof value === "string" && value.trim() ? value.trim() : undefined; -} diff --git a/app/api/admin/billing/account/route.ts b/app/api/admin/billing/account/route.ts deleted file mode 100644 index d715752..0000000 --- a/app/api/admin/billing/account/route.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api"; -import { requireSuperAdminUser } from "@/lib/server/auth/current-user"; -import { getBillingAccountConfig } from "@/lib/server/billing-service"; -import { saveApiSettings } from "@/lib/server/app-settings"; - -export const runtime = "nodejs"; - -export async function PATCH(request: Request) { - try { - await requireSuperAdminUser(); - const body = await readJsonBody>(request); - const values = { - ZHINIAN_BILLING_ACCOUNT_NAME: normalize(body.accountName), - ZHINIAN_BILLING_ACCOUNT_BANK: normalize(body.bankName), - ZHINIAN_BILLING_ACCOUNT_NUMBER: normalize(body.accountNumber), - ZHINIAN_BILLING_CONTACT: normalize(body.contact) - }; - await saveApiSettings(values); - return jsonOk({ billingAccount: getBillingAccountConfig() }); - } catch (error) { - return jsonError(error, 500, { request, source: "api.admin.billing.account" }); - } -} - -function normalize(value: unknown): string { - return typeof value === "string" ? value.trim() : ""; -} diff --git a/app/api/admin/billing/adjustments/route.ts b/app/api/admin/billing/adjustments/route.ts deleted file mode 100644 index 36dd53f..0000000 --- a/app/api/admin/billing/adjustments/route.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api"; -import { requireSuperAdminUser } from "@/lib/server/auth/current-user"; -import { getPlatformOrganization } from "@/lib/server/account-store"; -import { postOrganizationTopUp } from "@/lib/server/billing-service"; -import { postWalletEntry } from "@/lib/server/billing-store"; -import { createId } from "@/lib/server/ids"; - -export const runtime = "nodejs"; - -export async function POST(request: Request) { - try { - const operator = await requireSuperAdminUser(); - const body = await readJsonBody>(request); - const organizationId = requiredString(body.organizationId, "组织"); - const organization = await getPlatformOrganization(organizationId); - if (!organization) throw badRequest("组织不存在。"); - - const amountFen = parseAmountFen(body.amountFen, body.amountYuan); - if (amountFen <= 0) throw badRequest("请输入大于 0 的金额。"); - const direction = body.direction === "debit" ? "debit" : body.direction === "credit" ? "credit" : null; - if (!direction) throw badRequest("余额变动方向无效。"); - - const note = requiredString(body.note, "备注"); - const amountLabel = (amountFen / 100).toFixed(2); - const idempotencyKey = `manual-adjustment:${createId("entry")}`; - const metadata = { - operation: direction === "credit" ? "admin_top_up" : "manual_adjustment", - direction, - note, - operatorId: operator.id, - amountYuan: amountLabel - }; - const result = direction === "credit" - ? await postOrganizationTopUp({ - organizationId, - amountFen, - idempotencyKey, - description: `管理员上账 · ${note}`, - metadata - }) - : await postWalletEntry({ - organizationId, - kind: "adjustment", - deltaFen: -amountFen, - idempotencyKey, - description: `管理员扣减 · ${note}`, - metadata - }); - return jsonOk({ wallet: result.wallet, entry: result.entry }); - } catch (error) { - return jsonError(error, 500, { request, source: "api.admin.billing.adjustments" }); - } -} - -function parseAmountFen(amountFen: unknown, amountYuan: unknown): number { - const fen = Number(amountFen); - if (Number.isFinite(fen) && fen > 0) return Math.round(fen); - const yuan = Number(amountYuan); - if (!Number.isFinite(yuan) || yuan <= 0) return 0; - return Math.round(yuan * 100); -} - -function requiredString(value: unknown, label: string): string { - const normalized = optionalString(value); - if (!normalized) throw badRequest(`${label}不能为空。`); - return normalized; -} - -function optionalString(value: unknown): string | undefined { - return typeof value === "string" && value.trim() ? value.trim() : undefined; -} - -function badRequest(message: string): Error & { status: number } { - return Object.assign(new Error(message), { status: 400 }); -} diff --git a/app/api/admin/billing/prices/[id]/route.ts b/app/api/admin/billing/prices/[id]/route.ts deleted file mode 100644 index 6bf9fb0..0000000 --- a/app/api/admin/billing/prices/[id]/route.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api"; -import { requireSuperAdminSession } from "@/lib/server/auth/current-user"; -import { getBillingPriceRule, updateBillingPriceRule, updateBillingPriceTierMultiplier } from "@/lib/server/billing-store"; - -export const runtime = "nodejs"; - -export async function PATCH(request: Request, context: { params: Promise<{ id: string }> }) { - try { - await requireSuperAdminSession(); - const { id } = await context.params; - const body = await readJsonBody>(request); - const unsupportedFields = Object.keys(body).filter((key) => !["markupMultiplier", "dimensionKey", "tierValue"].includes(key)); - if (unsupportedFields.length) throw badRequest("平台标准价格与参数由系统维护,超管仅可调整上浮倍率。"); - const multiplier = Number(body.markupMultiplier); - if (!Number.isFinite(multiplier) || multiplier < 1 || multiplier > 1000) { - throw badRequest("上浮倍率必须在 1.00 至 1000.00 之间。"); - } - const dimensionKey = typeof body.dimensionKey === "string" ? body.dimensionKey.trim() : ""; - const tierValue = typeof body.tierValue === "string" ? body.tierValue : ""; - if ((dimensionKey && !tierValue) || (!dimensionKey && tierValue)) { - throw badRequest("参数档位倍率更新必须同时提供参数维度和档位。"); - } - const existing = await getBillingPriceRule(id); - if (!existing) return jsonError("计费规则不存在", 404); - if (!dimensionKey && existing.parameterDimensions?.length) { - throw badRequest("当前服务包含参数档位,请指定要调整的参数档位倍率。"); - } - const rule = dimensionKey || tierValue - ? await updateBillingPriceTierMultiplier({ - ruleId: id, - dimensionKey, - tierValue, - markupMultiplier: Number(multiplier.toFixed(4)) - }) - : await updateBillingPriceRule(id, { markupMultiplier: Number(multiplier.toFixed(4)) }); - if (!rule) return jsonError("计费规则不存在", 404); - return jsonOk({ rule }); - } catch (error) { - return jsonError(error, 500, { request, source: "api.admin.billing.prices.updateMultiplier" }); - } -} - -function badRequest(message: string): Error & { status: number } { - return Object.assign(new Error(message), { status: 400 }); -} diff --git a/app/api/admin/billing/prices/route.ts b/app/api/admin/billing/prices/route.ts deleted file mode 100644 index 1e1c953..0000000 --- a/app/api/admin/billing/prices/route.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { jsonError, jsonOk } from "@/lib/server/api"; -import { requireSuperAdminSession } from "@/lib/server/auth/current-user"; -import { listBillingPriceRules } from "@/lib/server/billing-store"; -import { ensureDefaultBillingPriceRules } from "@/lib/server/billing-catalog"; - -export const runtime = "nodejs"; - -export async function GET() { - try { - await requireSuperAdminSession(); - await ensureDefaultBillingPriceRules(); - return jsonOk({ priceRules: await listBillingPriceRules({ includeDisabled: true }) }); - } catch (error) { - return jsonError(error, 500, { source: "api.admin.billing.prices" }); - } -} diff --git a/app/api/admin/billing/route.ts b/app/api/admin/billing/route.ts deleted file mode 100644 index edc8cd1..0000000 --- a/app/api/admin/billing/route.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { jsonError, jsonOk } from "@/lib/server/api"; -import { requireSuperAdminSession } from "@/lib/server/auth/current-user"; -import { listPlatformOrganizations, listPlatformUsers } from "@/lib/server/account-store"; -import { listBillingLedgerEntries, listBillingPriceRules, listOrganizationWallets } from "@/lib/server/billing-store"; -import { ensureDefaultBillingPriceRules } from "@/lib/server/billing-catalog"; -import { getBillingAccountConfig } from "@/lib/server/billing-service"; - -export const runtime = "nodejs"; -export const dynamic = "force-dynamic"; - -export async function GET() { - try { - await requireSuperAdminSession(); - await ensureDefaultBillingPriceRules(); - const [organizations, wallets, members, ledger, priceRules] = await Promise.all([ - listPlatformOrganizations({ includeDisabled: true }), - listOrganizationWallets(), - listPlatformUsers({ includeDisabled: true }), - listBillingLedgerEntries({ limit: 500 }), - listBillingPriceRules({ includeDisabled: true }) - ]); - const walletByOrganization = new Map(wallets.map((wallet) => [wallet.organizationId, wallet])); - return jsonOk({ - billingAccount: getBillingAccountConfig(), - organizations: organizations.map((organization) => ({ - ...organization, - wallet: walletByOrganization.get(organization.id) || { - organizationId: organization.id, - balanceFen: 0, - totalRechargedFen: 0, - totalChargedFen: 0, - updatedAt: organization.updatedAt - } - })), - members: members.map((member) => ({ - id: member.id, - displayName: member.displayName, - phone: member.phone, - role: member.role, - organizationId: member.organizationId || null, - status: member.status - })), - ledger, - priceRules - }); - } catch (error) { - return jsonError(error, 500, { source: "api.admin.billing" }); - } -} diff --git a/app/api/admin/organizations/route.ts b/app/api/admin/organizations/route.ts deleted file mode 100644 index 59a718a..0000000 --- a/app/api/admin/organizations/route.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api"; -import { requireAdminSession } from "@/lib/server/auth/current-user"; -import { - AccountStoreError, - createPlatformOrganization, - deletePlatformOrganization, - listPlatformOrganizations, - updatePlatformOrganization -} from "@/lib/server/account-store"; -import { hasSuperAdminAccess } from "@/lib/auth/permissions"; -import type { AuthUser } from "@/lib/auth/session"; - -export const runtime = "nodejs"; -export const dynamic = "force-dynamic"; - -export async function GET() { - try { - const session = await requireAdminSession(); - const organizations = await listPlatformOrganizations({ includeDisabled: hasSuperAdminAccess(session.user) }); - return jsonOk({ organizations: organizations - .filter((organization) => hasSuperAdminAccess(session.user) || organization.id === session.user.organizationId) - .map((organization) => ({ id: organization.id, name: organization.name, status: organization.status })) }); - } catch (error) { - return jsonError(error, 500, { source: "api.admin.organizations" }); - } -} - -export async function POST(request: Request) { - try { - const session = await requireAdminSession(); - requireSuperAdmin(session.user); - const body = await readJsonBody>(request); - const organization = await createPlatformOrganization(requiredString(body.name, "组织名称")); - return jsonOk({ ok: true, organization: publicOrganization(organization) }, { status: 201 }); - } catch (error) { - return jsonError(error, 500, { request, source: "api.admin.organizations", logClientErrors: true }); - } -} - -export async function PATCH(request: Request) { - try { - const session = await requireAdminSession(); - requireSuperAdmin(session.user); - const body = await readJsonBody>(request); - const organization = await updatePlatformOrganization(requiredString(body.organizationId, "组织 ID"), { - name: optionalString(body.name), - status: parseStatus(body.status) - }); - return jsonOk({ ok: true, organization: publicOrganization(organization) }); - } catch (error) { - return jsonError(error, 500, { request, source: "api.admin.organizations", logClientErrors: true }); - } -} - -export async function DELETE(request: Request) { - try { - const session = await requireAdminSession(); - requireSuperAdmin(session.user); - const body = await readJsonBody>(request); - await deletePlatformOrganization(requiredString(body.organizationId, "组织 ID")); - return jsonOk({ ok: true }); - } catch (error) { - return jsonError(error, 500, { request, source: "api.admin.organizations", logClientErrors: true }); - } -} - -function requireSuperAdmin(user: AuthUser) { - if (!hasSuperAdminAccess(user)) throw new AccountStoreError("需要超级管理员权限。", 403); -} - -function publicOrganization(organization: { id: string; name: string; status: string }) { - return { id: organization.id, name: organization.name, status: organization.status }; -} - -function requiredString(value: unknown, label: string): string { - const normalized = optionalString(value); - if (!normalized) throw new AccountStoreError(`${label}不能为空。`, 400); - return normalized; -} - -function optionalString(value: unknown): string | undefined { - return typeof value === "string" && value.trim() ? value.trim() : undefined; -} - -function parseStatus(value: unknown): "active" | "disabled" | undefined { - if (value === undefined || value === null || value === "") return undefined; - if (value === "active" || value === "disabled") return value; - throw new AccountStoreError("组织状态不正确。", 400); -} diff --git a/app/api/admin/usage/route.ts b/app/api/admin/usage/route.ts deleted file mode 100644 index 8f46608..0000000 --- a/app/api/admin/usage/route.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { jsonError, jsonOk } from "@/lib/server/api"; -import { requireAdminSession } from "@/lib/server/auth/current-user"; -import { listPlatformOrganizations } from "@/lib/server/account-store"; -import { hasSuperAdminAccess } from "@/lib/auth/permissions"; -import { getAdminUsageReport } from "@/lib/server/usage-service"; -import type { GenerationCapability, GenerationProvider } from "@/lib/types"; - -export const runtime = "nodejs"; -export const dynamic = "force-dynamic"; - -export async function GET(request: Request) { - try { - const session = await requireAdminSession(); - const url = new URL(request.url); - const isSuperAdmin = hasSuperAdminAccess(session.user); - const organizations = (await listPlatformOrganizations({ includeDisabled: isSuperAdmin })) - .filter((organization) => isSuperAdmin || organization.id === session.user.organizationId) - .map((organization) => ({ organizationId: organization.id, organizationName: organization.name })); - const report = await getAdminUsageReport({ - startDate: optionalParam(url, "startDate"), - endDate: optionalParam(url, "endDate"), - organizationId: isSuperAdmin ? optionalParam(url, "organizationId") : session.user.organizationId, - ownerId: isSuperAdmin ? optionalParam(url, "ownerId") : undefined, - capability: parseCapability(optionalParam(url, "capability")), - provider: parseProvider(optionalParam(url, "provider")) - }, organizations); - if (isSuperAdmin) return jsonOk(report); - return jsonOk({ - ...report, - accounts: [], - recent: [], - options: { ...report.options, accounts: [] } - }); - } catch (error) { - return jsonError(error, 500, { request, source: "api.admin.usage", logClientErrors: true }); - } -} - -function optionalParam(url: URL, name: string): string | undefined { - return url.searchParams.get(name)?.trim() || undefined; -} - -function parseCapability(value?: string): GenerationCapability | undefined { - if (!value) return undefined; - if (value === "image.generate" || value === "video.generate") { - return value; - } - throw badRequest("不支持的功能类型。"); -} - -function parseProvider(value?: string): GenerationProvider | undefined { - if (!value) return undefined; - if (value === "volcengine-visual" || value === "evolink" || value === "seedance" || value === "bailian") { - return value; - } - throw badRequest("不支持的服务商。"); -} - -function badRequest(message: string): Error & { status: number } { - return Object.assign(new Error(message), { status: 400 }); -} diff --git a/app/api/assets/[id]/download/route.ts b/app/api/assets/[id]/download/route.ts deleted file mode 100644 index 125e4ed..0000000 --- a/app/api/assets/[id]/download/route.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { getAsset } from "@/lib/server/data-store"; -import { jsonError } from "@/lib/server/api"; -import { requireAppUser } from "@/lib/server/auth/current-user"; -import { readAssetForDownload } from "@/lib/server/storage"; - -export const runtime = "nodejs"; - -export async function GET(_request: Request, context: { params: Promise<{ id: string }> }) { - try { - const user = await requireAppUser(); - const { id } = await context.params; - const asset = await getAsset(id); - if (!asset || asset.ownerId !== user.id) return jsonError("资产不存在", 404); - const file = await readAssetForDownload(asset); - if (!file) return jsonError("资产文件不可下载", 404); - return new Response(new Uint8Array(file.bytes), { - headers: { - "Content-Type": file.contentType, - "Content-Length": String(file.bytes.length), - "Content-Disposition": contentDisposition(asset.name || `${asset.id}${extensionForContentType(file.contentType)}`), - "Cache-Control": "private, no-store" - } - }); - } catch (error) { - return jsonError(error, 500); - } -} - -function contentDisposition(fileName: string): string { - const clean = fileName.replace(/[\r\n/\\]/g, "_").trim() || "download"; - const ascii = clean.replace(/[^\x20-\x7E]/g, "_").replace(/"/g, "_"); - return `attachment; filename="${ascii}"; filename*=UTF-8''${encodeURIComponent(clean)}`; -} - -function extensionForContentType(contentType: string): string { - const normalized = contentType.split(";")[0]?.trim().toLowerCase(); - if (normalized === "image/png") return ".png"; - if (normalized === "image/jpeg") return ".jpg"; - if (normalized === "image/webp") return ".webp"; - if (normalized === "image/svg+xml") return ".svg"; - if (normalized === "video/mp4") return ".mp4"; - if (normalized === "audio/mpeg") return ".mp3"; - return ""; -} diff --git a/app/api/assets/[id]/route.ts b/app/api/assets/[id]/route.ts deleted file mode 100644 index f613281..0000000 --- a/app/api/assets/[id]/route.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { deleteAsset, getAsset } from "@/lib/server/data-store"; -import { jsonError, jsonOk } from "@/lib/server/api"; -import { requireAppUser } from "@/lib/server/auth/current-user"; -import { deleteStoredAsset } from "@/lib/server/storage"; - -export const runtime = "nodejs"; - -export async function DELETE(_request: Request, context: { params: Promise<{ id: string }> }) { - try { - const user = await requireAppUser(); - const { id } = await context.params; - const asset = await getAsset(id); - if (!asset || asset.ownerId !== user.id) return jsonError("资产不存在", 404); - await deleteStoredAsset(asset); - await deleteAsset(id); - return jsonOk({ ok: true, deletedAssetId: id }); - } catch (error) { - return jsonError(error, 500); - } -} diff --git a/app/api/assets/route.ts b/app/api/assets/route.ts deleted file mode 100644 index c4b6aff..0000000 --- a/app/api/assets/route.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { createAsset, listAssets } from "@/lib/server/data-store"; -import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api"; -import { requireAppUser } from "@/lib/server/auth/current-user"; -import type { AssetKind } from "@/lib/types"; - -export const runtime = "nodejs"; - -export async function GET() { - try { - const user = await requireAppUser(); - return jsonOk({ assets: await listAssets(user.id) }); - } catch (error) { - return jsonError(error, 500); - } -} - -export async function POST(request: Request) { - try { - const body = await readJsonBody<{ - url?: string; - name?: string; - kind?: AssetKind; - tags?: string[]; - source?: "upload" | "generated" | "external" | "seed"; - }>(request); - const user = await requireAppUser(); - if (!body.url) throw new Error("url is required"); - const asset = await createAsset({ - ownerId: user.id, - kind: body.kind || "image", - name: body.name || "外部图片", - url: body.url, - source: body.source || "external", - tags: body.tags || ["external"], - metadata: { - registeredFrom: "api" - } - }); - return jsonOk({ asset }, { status: 201 }); - } catch (error) { - return jsonError(error); - } -} diff --git a/app/api/assets/upload/route.ts b/app/api/assets/upload/route.ts deleted file mode 100644 index 2868f0b..0000000 --- a/app/api/assets/upload/route.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { jsonError, jsonOk } from "@/lib/server/api"; -import { requireAppUser } from "@/lib/server/auth/current-user"; -import { requestOrigin } from "@/lib/server/runtime"; -import { saveUploadAsset } from "@/lib/server/storage"; - -export const runtime = "nodejs"; - -export async function POST(request: Request) { - try { - const user = await requireAppUser(); - const form = await request.formData(); - const files = form.getAll("files").filter((item): item is File => item instanceof File); - if (!files.length) throw new Error("No files uploaded."); - const assets = await Promise.all(files.map(async (file) => { - return saveUploadAsset({ - ownerId: user.id, - bytes: Buffer.from(await file.arrayBuffer()), - fileName: file.name, - contentType: file.type || "application/octet-stream", - origin: requestOrigin(request), - tags: ["upload"] - }); - })); - return jsonOk({ assets }, { status: 201 }); - } catch (error) { - return jsonError(error); - } -} diff --git a/app/api/auth/callback/route.ts b/app/api/auth/callback/route.ts deleted file mode 100644 index f7418a6..0000000 --- a/app/api/auth/callback/route.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { NextResponse } from "next/server"; - -export async function GET(request: Request) { - return NextResponse.redirect(new URL("/auth/login?error=callback_failed", request.url)); -} diff --git a/app/api/auth/captcha/route.ts b/app/api/auth/captcha/route.ts deleted file mode 100644 index eda4aa3..0000000 --- a/app/api/auth/captcha/route.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { jsonOk } from "@/lib/server/api"; - -export const runtime = "nodejs"; - -export async function GET() { - return jsonOk({ enabled: false, message: "平台账号登录不使用外部验证码。" }); -} diff --git a/app/api/auth/login/route.ts b/app/api/auth/login/route.ts deleted file mode 100644 index 6ac8fb2..0000000 --- a/app/api/auth/login/route.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { NextResponse } from "next/server"; - -export async function GET(request: Request) { - return NextResponse.redirect(new URL("/auth/login", request.url)); -} diff --git a/app/api/auth/logout/route.ts b/app/api/auth/logout/route.ts deleted file mode 100644 index 50065e4..0000000 --- a/app/api/auth/logout/route.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { NextResponse } from "next/server"; -import { clearPlatformSessionCookies } from "@/lib/server/auth/local"; - -export const runtime = "nodejs"; - -export async function GET(request: Request) { - return logoutResponse(request); -} - -export async function POST(request: Request) { - return logoutResponse(request); -} - -function logoutResponse(request: Request) { - const response = NextResponse.redirect(new URL("/auth/login?loggedOut=1", request.url)); - clearPlatformSessionCookies(response, request.url); - return response; -} diff --git a/app/api/auth/me/route.ts b/app/api/auth/me/route.ts deleted file mode 100644 index 43435f9..0000000 --- a/app/api/auth/me/route.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { getAuthRuntimeConfig } from "@/lib/auth/config"; -import { jsonOk } from "@/lib/server/api"; -import { getOptionalAuthSession } from "@/lib/server/auth/current-user"; - -export const runtime = "nodejs"; - -export async function GET() { - const config = getAuthRuntimeConfig(); - const session = await getOptionalAuthSession(); - return jsonOk({ - authenticated: Boolean(session), - authRequired: config.required, - authConfigured: config.configured, - authMode: session?.authMode || null, - user: session?.user || null - }); -} diff --git a/app/api/auth/password/change/route.ts b/app/api/auth/password/change/route.ts deleted file mode 100644 index 193e168..0000000 --- a/app/api/auth/password/change/route.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api"; -import { requireAppSession } from "@/lib/server/auth/current-user"; -import { changeOwnPassword } from "@/lib/server/account-store"; -import { createPlatformSession, setPlatformSessionCookie } from "@/lib/server/auth/local"; - -export const runtime = "nodejs"; - -export async function POST(request: Request) { - try { - const session = await requireAppSession(); - const body = await readJsonBody>(request); - const currentPassword = requiredString(body.currentPassword, "当前密码"); - const newPassword = requiredString(body.newPassword, "新密码"); - const confirmPassword = requiredString(body.confirmPassword, "确认密码"); - if (newPassword !== confirmPassword) throw Object.assign(new Error("两次输入的新密码不一致。"), { status: 400 }); - const user = await changeOwnPassword(session.user.id, currentPassword, newPassword); - const nextSession = await createPlatformSession(user); - const response = jsonOk({ ok: true, user: nextSession.user }); - await setPlatformSessionCookie(response, request.url, nextSession); - return response; - } catch (error) { - return jsonError(error, 400, { request, source: "api.auth.password.change" }); - } -} - -function requiredString(value: unknown, label: string): string { - if (typeof value === "string" && value.trim()) return value.trim(); - throw Object.assign(new Error(`${label}不能为空。`), { status: 400 }); -} diff --git a/app/api/auth/password/route.ts b/app/api/auth/password/route.ts deleted file mode 100644 index 5a0be9a..0000000 --- a/app/api/auth/password/route.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { getAuthRuntimeConfig, safeNextPath } from "@/lib/auth/config"; -import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api"; -import { authenticatePlatformUser } from "@/lib/server/account-store"; -import { - checkIpLoginRateLimit, - clearIpLoginRateLimit, - clientIpFromRequest, - createPlatformSession, - setPlatformSessionCookie -} from "@/lib/server/auth/local"; - -export const runtime = "nodejs"; -export const dynamic = "force-dynamic"; - -export async function POST(request: Request) { - const ip = clientIpFromRequest(request); - try { - const config = getAuthRuntimeConfig(); - if (!config.configured || !config.sessionSecret) { - throw Object.assign(new Error(`账号认证配置不完整:${config.missing.join(", ") || "ZHINIAN_AUTH_SESSION_SECRET"}`), { status: 503 }); - } - checkIpLoginRateLimit(ip); - const body = await readJsonBody>(request); - const phone = stringValue(body.phone) || stringValue(body.username); - const password = stringValue(body.password); - if (!phone || !password) throw Object.assign(new Error("手机号和密码不能为空。"), { status: 400 }); - const user = await authenticatePlatformUser(phone, password); - clearIpLoginRateLimit(ip); - const session = await createPlatformSession(user); - const response = jsonOk({ - ok: true, - redirectTo: safeNextPath(stringValue(body.next)), - user: session.user, - authMode: session.authMode - }); - await setPlatformSessionCookie(response, request.url, session); - return response; - } catch (error) { - return jsonError(error, 401, { request, source: "api.auth.password", logClientErrors: false }); - } -} - -function stringValue(value: unknown): string | undefined { - return typeof value === "string" && value.trim() ? value.trim() : undefined; -} diff --git a/app/api/billing/quote/route.ts b/app/api/billing/quote/route.ts deleted file mode 100644 index da0e115..0000000 --- a/app/api/billing/quote/route.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api"; -import { requireAppSession } from "@/lib/server/auth/current-user"; -import { requestOrigin } from "@/lib/server/runtime"; -import { resolvePlatformUsageContext } from "@/lib/server/usage-context"; -import { quoteImageGeneration, type SubmitImageJobInput } from "@/lib/server/generation-service"; -import { quoteVideoGeneration, type SubmitVideoJobInput } from "@/lib/server/video-generation-service"; - -export const runtime = "nodejs"; - -export async function POST(request: Request) { - try { - const session = await requireAppSession(); - const body = await readJsonBody>(request); - const usageContext = await resolvePlatformUsageContext(session); - const kind = body.kind === "video" || body.capability === "video.generate" ? "video" : "image"; - const quote = kind === "video" - ? await quoteVideoGeneration({ ...body, ownerId: session.user.id, usageContext } as SubmitVideoJobInput, requestOrigin(request)) - : await quoteImageGeneration({ ...body, capability: "image.generate", ownerId: session.user.id, usageContext } as SubmitImageJobInput, requestOrigin(request)); - return jsonOk({ quote }); - } catch (error) { - return jsonError(error, 500, { request, source: "api.billing.quote" }); - } -} diff --git a/app/api/billing/route.ts b/app/api/billing/route.ts deleted file mode 100644 index 471245e..0000000 --- a/app/api/billing/route.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { jsonError, jsonOk } from "@/lib/server/api"; -import { requireAppSession } from "@/lib/server/auth/current-user"; -import { getBillingOverview } from "@/lib/server/billing-service"; - -export const runtime = "nodejs"; -export const dynamic = "force-dynamic"; - -export async function GET() { - try { - const session = await requireAppSession(); - const organizationId = session.user.organizationId; - if (!organizationId) throw Object.assign(new Error("当前账号未绑定组织。"), { status: 422 }); - const overview = await getBillingOverview({ organizationId, accountId: session.user.id }); - return jsonOk({ - organization: { - id: organizationId, - name: session.user.organizationName || organizationId - }, - ...overview - }); - } catch (error) { - return jsonError(error, 500, { source: "api.billing" }); - } -} diff --git a/app/api/generations/image/[id]/retry/route.ts b/app/api/generations/image/[id]/retry/route.ts deleted file mode 100644 index 339b9ec..0000000 --- a/app/api/generations/image/[id]/retry/route.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { jsonError, jsonOk } from "@/lib/server/api"; -import { requireAppSession } from "@/lib/server/auth/current-user"; -import { requestOrigin } from "@/lib/server/runtime"; -import { retryImageJob } from "@/lib/server/generation-service"; -import { resolvePlatformUsageContext } from "@/lib/server/usage-context"; - -export const runtime = "nodejs"; - -export async function POST(request: Request, context: { params: Promise<{ id: string }> }) { - try { - const session = await requireAppSession(); - const user = session.user; - const { id } = await context.params; - const usageContext = await resolvePlatformUsageContext(session); - const job = await retryImageJob(id, requestOrigin(request), user.id, usageContext); - return jsonOk({ job }, { status: 202 }); - } catch (error) { - return jsonError(error); - } -} diff --git a/app/api/generations/image/[id]/route.ts b/app/api/generations/image/[id]/route.ts deleted file mode 100644 index 5928cb8..0000000 --- a/app/api/generations/image/[id]/route.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { deleteAsset, deleteGenerationJob, getAsset, getGenerationJob, updateGenerationJob } from "@/lib/server/data-store"; -import { jsonError, jsonOk } from "@/lib/server/api"; -import { requireAppUser } from "@/lib/server/auth/current-user"; -import { deleteStoredAsset } from "@/lib/server/storage"; -import { refundGenerationCharge } from "@/lib/server/billing-service"; - -export const runtime = "nodejs"; - -export async function GET(_request: Request, context: { params: Promise<{ id: string }> }) { - try { - const user = await requireAppUser(); - const { id } = await context.params; - const job = await getGenerationJob(id); - if (!job || job.ownerId !== user.id) return jsonError(new Error("Generation job not found."), 404); - return jsonOk({ job }); - } catch (error) { - return jsonError(error, 500); - } -} - -export async function DELETE(_request: Request, context: { params: Promise<{ id: string }> }) { - try { - const user = await requireAppUser(); - const { id } = await context.params; - const job = await getGenerationJob(id); - if (!job || job.ownerId !== user.id || job.capability === "video.generate") return jsonError("任务不存在", 404); - const deletedAssetIds: string[] = []; - for (const assetId of job.outputAssetIds) { - const asset = await getAsset(assetId); - if (!asset) continue; - await deleteStoredAsset(asset); - await deleteAsset(asset.id); - deletedAssetIds.push(asset.id); - } - const cancellableJob = ["queued", "running"].includes(job.status) - ? await updateGenerationJob(job.id, { status: "cancelled", completedAt: new Date().toISOString() }) - : job; - await refundGenerationCharge(cancellableJob, "任务已删除"); - await deleteGenerationJob(id); - return jsonOk({ ok: true, deletedJobId: id, deletedAssetIds }); - } catch (error) { - return jsonError(error, 500); - } -} diff --git a/app/api/generations/image/route.ts b/app/api/generations/image/route.ts deleted file mode 100644 index 08edccd..0000000 --- a/app/api/generations/image/route.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { getGenerationJob, listGenerationJobs } from "@/lib/server/data-store"; -import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api"; -import { requireAppSession, requireAppUser } from "@/lib/server/auth/current-user"; -import { requestOrigin } from "@/lib/server/runtime"; -import { submitImageJob } from "@/lib/server/generation-service"; -import { assemblePrompt, type PromptAssemblyInput, type PromptMaterial } from "@/lib/prompt/assembler"; -import type { EnabledImageCapability } from "@/lib/types"; -import type { ImageCreationEngine } from "@/lib/evolink/image-client"; -import { resolvePlatformUsageContext } from "@/lib/server/usage-context"; - -export const runtime = "nodejs"; - -export async function GET() { - try { - const user = await requireAppUser(); - const jobs = (await listGenerationJobs(user.id)).filter((job) => job.capability !== "video.generate"); - return jsonOk({ jobs }); - } catch (error) { - return jsonError(error, 500); - } -} - -export async function POST(request: Request) { - try { - const session = await requireAppSession(); - const user = session.user; - const usageContext = await resolvePlatformUsageContext(session); - const body = await readJsonBody<{ - capability?: EnabledImageCapability; - engine?: ImageCreationEngine; - prompt?: string; - imageUrls?: string[]; - materials?: PromptMaterial[]; - promptAssembly?: PromptAssemblyInput; - inputAssetIds?: string[]; - scale?: number; - width?: number; - height?: number; - min_ratio?: number; - max_ratio?: number; - force_single?: boolean; - quality?: string; - }>(request); - const capability = body.capability || "image.generate"; - const assembled = body.promptAssembly - ? assemblePrompt({ ...body.promptAssembly, mode: "image", materials: body.materials || body.promptAssembly.materials || [] }) - : undefined; - const materialImages = (body.materials || assembled?.materials || []) - .filter((material) => material.type === "image") - .map((material) => material.url); - const job = await submitImageJob({ - ownerId: user.id, - capability, - engine: body.engine, - prompt: body.prompt || assembled?.prompt, - imageUrls: body.imageUrls || materialImages, - inputAssetIds: body.inputAssetIds || (body.materials || []).map((material) => material.id).filter(Boolean) as string[], - scale: asNumber(body.scale), - width: asNumber(body.width), - height: asNumber(body.height), - min_ratio: asNumber(body.min_ratio), - max_ratio: asNumber(body.max_ratio), - force_single: Boolean(body.force_single), - quality: typeof body.quality === "string" ? body.quality : undefined, - usageContext - }, requestOrigin(request)); - return jsonOk({ job: await getGenerationJob(job.id) }, { status: 202 }); - } catch (error) { - return jsonError(error); - } -} - -function asNumber(value: unknown): number | undefined { - if (value === undefined || value === null || value === "") return undefined; - const parsed = Number(value); - return Number.isFinite(parsed) ? parsed : undefined; -} diff --git a/app/api/generations/video/[id]/route.ts b/app/api/generations/video/[id]/route.ts deleted file mode 100644 index feb27c5..0000000 --- a/app/api/generations/video/[id]/route.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { deleteAsset, deleteGenerationJob, getAsset, getGenerationJob, updateGenerationJob } from "@/lib/server/data-store"; -import { jsonError, jsonOk } from "@/lib/server/api"; -import { requireAppUser } from "@/lib/server/auth/current-user"; -import { deleteStoredAsset } from "@/lib/server/storage"; -import { refundGenerationCharge } from "@/lib/server/billing-service"; - -export const runtime = "nodejs"; - -export async function GET(_request: Request, context: { params: Promise<{ id: string }> }) { - try { - const user = await requireAppUser(); - const { id } = await context.params; - const job = await getGenerationJob(id); - if (!job || job.ownerId !== user.id) return jsonError(new Error("Generation job not found."), 404); - return jsonOk({ job }); - } catch (error) { - return jsonError(error, 500); - } -} - -export async function DELETE(_request: Request, context: { params: Promise<{ id: string }> }) { - try { - const user = await requireAppUser(); - const { id } = await context.params; - const job = await getGenerationJob(id); - if (!job || job.ownerId !== user.id || job.capability !== "video.generate") return jsonError("任务不存在", 404); - const deletedAssetIds: string[] = []; - for (const assetId of job.outputAssetIds) { - const asset = await getAsset(assetId); - if (!asset) continue; - await deleteStoredAsset(asset); - await deleteAsset(asset.id); - deletedAssetIds.push(asset.id); - } - const cancellableJob = ["queued", "running"].includes(job.status) - ? await updateGenerationJob(job.id, { status: "cancelled", completedAt: new Date().toISOString() }) - : job; - await refundGenerationCharge(cancellableJob, "任务已删除"); - await deleteGenerationJob(id); - return jsonOk({ ok: true, deletedJobId: id, deletedAssetIds }); - } catch (error) { - return jsonError(error, 500); - } -} diff --git a/app/api/generations/video/route.ts b/app/api/generations/video/route.ts deleted file mode 100644 index 5912c19..0000000 --- a/app/api/generations/video/route.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { listGenerationJobs } from "@/lib/server/data-store"; -import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api"; -import { requireAppSession, requireAppUser } from "@/lib/server/auth/current-user"; -import { requestOrigin } from "@/lib/server/runtime"; -import { submitVideoJob, type SubmitVideoJobInput } from "@/lib/server/video-generation-service"; -import { resolvePlatformUsageContext } from "@/lib/server/usage-context"; - -export const runtime = "nodejs"; - -export async function GET() { - try { - const user = await requireAppUser(); - const jobs = (await listGenerationJobs(user.id)).filter((job) => job.capability === "video.generate"); - return jsonOk({ jobs }); - } catch (error) { - return jsonError(error, 500); - } -} - -export async function POST(request: Request) { - try { - const session = await requireAppSession(); - const user = session.user; - const body = await readJsonBody>(request); - const usageContext = await resolvePlatformUsageContext(session); - const job = await submitVideoJob({ ...body, ownerId: user.id, usageContext }, requestOrigin(request)); - return jsonOk({ job }, { status: 202 }); - } catch (error) { - return jsonError(error); - } -} diff --git a/app/api/health/route.ts b/app/api/health/route.ts deleted file mode 100644 index ee3b24e..0000000 --- a/app/api/health/route.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { jsonOk } from "@/lib/server/api"; -import { authConfigSummary, getAuthRuntimeConfig } from "@/lib/auth/config"; -import { getEffectiveImageEngine, getEvolinkImageSettings, shouldMockEvolinkApi } from "@/lib/evolink/image-client"; -import { getVisibleImageCapabilities } from "@/lib/jimeng/capabilities"; -import { shouldMockVisualApi } from "@/lib/volcengine/visual-client"; -import { getSeedanceConfig, shouldMockSeedance } from "@/lib/seedance/client"; -import { getBailianConfig, shouldMockBailian } from "@/lib/bailian/client"; -import { getDatabaseStatus } from "@/lib/server/database"; - -export const runtime = "nodejs"; - -export async function GET() { - const evolink = getEvolinkImageSettings(); - const auth = getAuthRuntimeConfig(); - const bailian = getBailianConfig(); - let database: { backend: "local" | "postgres" | "invalid"; configured: boolean }; - try { - database = getDatabaseStatus(); - } catch { - database = { backend: "invalid", configured: false }; - } - return jsonOk({ - ok: true, - appId: "zhinian-web-studio", - webOnly: true, - visualApiMode: shouldMockVisualApi() ? "mock" : "volcengine", - evolinkMode: shouldMockEvolinkApi() ? "mock" : "evolink", - seedanceMode: shouldMockSeedance() ? "mock" : "seedance", - bailianMode: shouldMockBailian() ? "mock" : bailian.apiKey ? "bailian" : "missing", - authMode: authConfigSummary(auth), - database, - capabilities: [ - ...getVisibleImageCapabilities().map((capability) => { - const engine = getEffectiveImageEngine(capability.id); - return { - id: capability.id, - label: capability.label, - engine, - engineLabel: engine === "evolink" ? "EvoLink" : engine === "bailian" ? "阿里云百炼" : "即梦", - reqKey: engine === "bailian" ? bailian.imageModel : engine === "evolink" ? evolink.model : capability.reqKey - }; - }), - { - id: "video.generate", - label: "Seedance 视频生成", - engine: "seedance", - engineLabel: "Seedance", - reqKey: getSeedanceConfig().model - } - ] - }); -} diff --git a/app/api/image-templates/[id]/route.ts b/app/api/image-templates/[id]/route.ts deleted file mode 100644 index 5b684c7..0000000 --- a/app/api/image-templates/[id]/route.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { deleteImageTemplate, updateImageTemplate } from "@/lib/server/data-store"; -import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api"; -import { requireAppUser } from "@/lib/server/auth/current-user"; -import { normalizeImageTemplateUpdate } from "@/lib/server/image-template-input"; - -export const runtime = "nodejs"; - -type RouteContext = { - params: Promise<{ id: string }>; -}; - -export async function PATCH(request: Request, context: RouteContext) { - try { - const user = await requireAppUser(); - const { id } = await context.params; - const body = await readJsonBody(request); - const template = await updateImageTemplate(id, user.id, normalizeImageTemplateUpdate(body)); - if (!template) return jsonError(new Error("模板不存在"), 404); - return jsonOk({ template }); - } catch (error) { - return jsonError(error); - } -} - -export async function DELETE(_request: Request, context: RouteContext) { - try { - const user = await requireAppUser(); - const { id } = await context.params; - const template = await deleteImageTemplate(id, user.id); - if (!template) return jsonError(new Error("模板不存在"), 404); - return jsonOk({ template }); - } catch (error) { - return jsonError(error); - } -} diff --git a/app/api/image-templates/route.ts b/app/api/image-templates/route.ts deleted file mode 100644 index be6d26b..0000000 --- a/app/api/image-templates/route.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { createImageTemplate, listImageTemplates } from "@/lib/server/data-store"; -import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api"; -import { requireAppUser } from "@/lib/server/auth/current-user"; -import { normalizeImageTemplateCreate } from "@/lib/server/image-template-input"; - -export const runtime = "nodejs"; - -export async function GET() { - try { - const user = await requireAppUser(); - return jsonOk({ templates: await listImageTemplates(user.id) }); - } catch (error) { - return jsonError(error, 500); - } -} - -export async function POST(request: Request) { - try { - const user = await requireAppUser(); - const body = await readJsonBody(request); - const template = await createImageTemplate({ - ownerId: user.id, - ...normalizeImageTemplateCreate(body) - }); - return jsonOk({ template }, { status: 201 }); - } catch (error) { - return jsonError(error); - } -} diff --git a/app/api/internal/worker/tick/route.ts b/app/api/internal/worker/tick/route.ts deleted file mode 100644 index e7811f4..0000000 --- a/app/api/internal/worker/tick/route.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api"; -import { assertInternalWorkerToken, PublicApiAuthError } from "@/lib/server/public-api-auth"; -import { runWorkerTick } from "@/lib/server/task-manager"; - -export const runtime = "nodejs"; - -export async function POST(request: Request) { - try { - assertInternalWorkerToken(request); - const body = await readJsonBody<{ - workerId?: string; - limit?: number; - }>(request); - const result = await runWorkerTick({ - request, - workerId: body.workerId, - limit: typeof body.limit === "number" ? body.limit : undefined - }); - return jsonOk(result); - } catch (error) { - if (error instanceof PublicApiAuthError) return jsonError(error.message, error.status); - return jsonError(error, 500); - } -} diff --git a/app/api/logs/route.ts b/app/api/logs/route.ts deleted file mode 100644 index b7acef1..0000000 --- a/app/api/logs/route.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { jsonError, jsonOk } from "@/lib/server/api"; -import { requireSuperAdminUser } from "@/lib/server/auth/current-user"; -import { clearAppLogs, listAppLogs, type AppLogLevel } from "@/lib/server/log-manager"; - -export const runtime = "nodejs"; -export const dynamic = "force-dynamic"; - -export async function GET(request: Request) { - try { - await requireSuperAdminUser(); - const url = new URL(request.url); - const level = parseLevel(url.searchParams.get("level")); - const q = url.searchParams.get("q") || undefined; - const limit = Number(url.searchParams.get("limit") || 100); - const entries = await listAppLogs({ - level, - q, - limit: Number.isFinite(limit) ? limit : 100 - }); - return jsonOk({ entries }); - } catch (error) { - return jsonError(error, 500, { request, source: "api.logs" }); - } -} - -export async function DELETE(request: Request) { - try { - await requireSuperAdminUser(); - await clearAppLogs(); - return jsonOk({ ok: true }); - } catch (error) { - return jsonError(error, 500, { request, source: "api.logs" }); - } -} - -function parseLevel(value: string | null): AppLogLevel | "all" { - if (value === "info" || value === "warning" || value === "error") return value; - return "all"; -} diff --git a/app/api/prompt/assemble/route.ts b/app/api/prompt/assemble/route.ts deleted file mode 100644 index 20779fd..0000000 --- a/app/api/prompt/assemble/route.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { assemblePrompt, type PromptAssemblyInput } from "@/lib/prompt/assembler"; -import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api"; -import { requireAppUser } from "@/lib/server/auth/current-user"; - -export const runtime = "nodejs"; - -export async function POST(request: Request) { - try { - await requireAppUser(); - const body = await readJsonBody>(request); - return jsonOk(assemblePrompt(body)); - } catch (error) { - return jsonError(error); - } -} diff --git a/app/api/ready/route.ts b/app/api/ready/route.ts deleted file mode 100644 index aa5ffa2..0000000 --- a/app/api/ready/route.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { NextResponse } from "next/server"; -import { checkDatabaseReadiness, getDatabaseStatus } from "@/lib/server/database"; - -export const runtime = "nodejs"; - -const READINESS_TIMEOUT_MS = 3_000; - -export async function GET() { - let database: { backend: "local" | "postgres" | "invalid"; configured: boolean }; - try { - database = getDatabaseStatus(); - } catch { - database = { backend: "invalid", configured: false }; - return NextResponse.json({ ok: false, database }, { status: 503 }); - } - - let timeout: ReturnType | undefined; - try { - await Promise.race([ - checkDatabaseReadiness(), - new Promise((_, reject) => { - timeout = setTimeout(() => reject(new Error("Database readiness timed out")), READINESS_TIMEOUT_MS); - }) - ]); - return NextResponse.json({ ok: true, database }); - } catch { - return NextResponse.json({ ok: false, database }, { status: 503 }); - } finally { - if (timeout) clearTimeout(timeout); - } -} diff --git a/app/api/settings/route.ts b/app/api/settings/route.ts deleted file mode 100644 index ab9f35d..0000000 --- a/app/api/settings/route.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { getApiSettings, saveApiSettings } from "@/lib/server/app-settings"; -import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api"; -import { requireSuperAdminUser } from "@/lib/server/auth/current-user"; - -export const runtime = "nodejs"; - -export async function GET() { - try { - await requireSuperAdminUser(); - return jsonOk(await getApiSettings()); - } catch (error) { - return jsonError(error, 500); - } -} - -export async function POST(request: Request) { - try { - await requireSuperAdminUser(); - const body = await readJsonBody<{ values?: Record }>(request); - return jsonOk(await saveApiSettings(body.values || {})); - } catch (error) { - return jsonError(error, 500); - } -} diff --git a/app/api/usage/route.ts b/app/api/usage/route.ts deleted file mode 100644 index 5e30bd2..0000000 --- a/app/api/usage/route.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { jsonError, jsonOk } from "@/lib/server/api"; -import { requireAppUser } from "@/lib/server/auth/current-user"; -import { getPersonalUsageReport } from "@/lib/server/usage-service"; -import type { UsagePreset } from "@/lib/usage"; - -export const runtime = "nodejs"; -export const dynamic = "force-dynamic"; - -export async function GET(request: Request) { - try { - const user = await requireAppUser(); - const preset = parsePreset(new URL(request.url).searchParams.get("preset")); - return jsonOk(await getPersonalUsageReport(user.id, preset)); - } catch (error) { - return jsonError(error, 500, { request, source: "api.usage" }); - } -} - -function parsePreset(value: string | null): UsagePreset { - if (value === "today" || value === "7d" || value === "30d" || value === "month") return value; - return "month"; -} diff --git a/app/api/v1/assets/[id]/download/route.ts b/app/api/v1/assets/[id]/download/route.ts deleted file mode 100644 index 0c81966..0000000 --- a/app/api/v1/assets/[id]/download/route.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { jsonError } from "@/lib/server/api"; -import { authenticatePublicApiRequest } from "@/lib/server/public-api-auth"; -import { getPublicApiAsset } from "@/lib/server/public-api-assets"; -import { publicApiError } from "@/lib/server/public-api-response"; -import { readAssetForDownload } from "@/lib/server/storage"; - -export const runtime = "nodejs"; - -export async function GET(request: Request, context: { params: Promise<{ id: string }> }) { - try { - const client = authenticatePublicApiRequest(request); - const { id } = await context.params; - const asset = await getPublicApiAsset(client.id, id); - if (!asset) return jsonError("Asset not found.", 404); - const file = await readAssetForDownload(asset); - if (!file) return jsonError("Asset file is not downloadable.", 404); - return new Response(new Uint8Array(file.bytes), { - headers: { - "Content-Type": file.contentType, - "Content-Length": String(file.bytes.length), - "Content-Disposition": contentDisposition(asset.name), - "Cache-Control": "private, no-store" - } - }); - } catch (error) { - return publicApiError(error); - } -} - -function contentDisposition(fileName: string): string { - const clean = fileName.replace(/[\r\n/\\]/g, "_").trim() || "download"; - const ascii = clean.replace(/[^\x20-\x7E]/g, "_").replace(/"/g, "_"); - return `attachment; filename="${ascii}"; filename*=UTF-8''${encodeURIComponent(clean)}`; -} diff --git a/app/api/v1/assets/[id]/route.ts b/app/api/v1/assets/[id]/route.ts deleted file mode 100644 index 268b4bc..0000000 --- a/app/api/v1/assets/[id]/route.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { jsonError, jsonOk } from "@/lib/server/api"; -import { authenticatePublicApiRequest } from "@/lib/server/public-api-auth"; -import { getPublicApiAsset } from "@/lib/server/public-api-assets"; -import { publicApiError } from "@/lib/server/public-api-response"; - -export const runtime = "nodejs"; - -export async function GET(request: Request, context: { params: Promise<{ id: string }> }) { - try { - const client = authenticatePublicApiRequest(request); - const { id } = await context.params; - const asset = await getPublicApiAsset(client.id, id); - if (!asset) return jsonError("Asset not found.", 404); - return jsonOk({ asset }); - } catch (error) { - return publicApiError(error); - } -} diff --git a/app/api/v1/assets/route.ts b/app/api/v1/assets/route.ts deleted file mode 100644 index aab4756..0000000 --- a/app/api/v1/assets/route.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { createAsset } from "@/lib/server/data-store"; -import { jsonOk, readJsonBody } from "@/lib/server/api"; -import { authenticatePublicApiRequest, publicApiOwnerId } from "@/lib/server/public-api-auth"; -import { listPublicApiAssets } from "@/lib/server/public-api-assets"; -import { publicApiError } from "@/lib/server/public-api-response"; -import { requestOrigin } from "@/lib/server/runtime"; -import { saveUploadAsset } from "@/lib/server/storage"; -import type { AssetKind } from "@/lib/types"; - -export const runtime = "nodejs"; - -export async function GET(request: Request) { - try { - const client = authenticatePublicApiRequest(request); - return jsonOk({ assets: await listPublicApiAssets(client.id) }); - } catch (error) { - return publicApiError(error); - } -} - -export async function POST(request: Request) { - try { - const client = authenticatePublicApiRequest(request); - const ownerId = publicApiOwnerId(client); - const contentType = request.headers.get("content-type") || ""; - if (contentType.includes("multipart/form-data")) { - const form = await request.formData(); - const files = form.getAll("files").filter((item): item is File => item instanceof File); - if (!files.length) throw new Error("No files uploaded."); - const assets = await Promise.all(files.map(async (file) => saveUploadAsset({ - ownerId, - bytes: await awaitFileBytes(file), - fileName: file.name, - contentType: file.type || "application/octet-stream", - origin: requestOrigin(request), - tags: ["upload", "public-api", `api-client:${client.id}`] - }))); - return jsonOk({ assets }, { status: 201 }); - } - - const body = await readJsonBody<{ - url?: string; - name?: string; - kind?: AssetKind; - tags?: string[]; - }>(request); - if (!body.url) throw new Error("url is required"); - const asset = await createAsset({ - ownerId, - kind: body.kind || "image", - name: body.name || "外部素材", - url: body.url, - source: "external", - tags: [...(body.tags || []), "external", "public-api", `api-client:${client.id}`], - metadata: { - registeredFrom: "public-api", - externalClientId: client.id - } - }); - return jsonOk({ asset }, { status: 201 }); - } catch (error) { - return publicApiError(error); - } -} - -async function awaitFileBytes(file: File): Promise { - return Buffer.from(await file.arrayBuffer()); -} diff --git a/app/api/v1/capabilities/route.ts b/app/api/v1/capabilities/route.ts deleted file mode 100644 index 8eafe17..0000000 --- a/app/api/v1/capabilities/route.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { getEffectiveImageEngine, getEvolinkImageSettings } from "@/lib/evolink/image-client"; -import { getVisibleImageCapabilities } from "@/lib/jimeng/capabilities"; -import { jsonOk } from "@/lib/server/api"; -import { authenticatePublicApiRequest } from "@/lib/server/public-api-auth"; -import { publicApiError } from "@/lib/server/public-api-response"; -import { getSeedanceConfig } from "@/lib/seedance/client"; -import { getBailianConfig } from "@/lib/bailian/client"; - -export const runtime = "nodejs"; - -export async function GET(request: Request) { - try { - authenticatePublicApiRequest(request); - const evolink = getEvolinkImageSettings(); - const bailian = getBailianConfig(); - return jsonOk({ - capabilities: [ - ...getVisibleImageCapabilities().map((capability) => { - const engine = getEffectiveImageEngine(capability.id); - return { - id: capability.id, - label: capability.label, - kind: "image", - engine, - provider: engine === "bailian" ? "bailian" : engine === "evolink" ? "evolink" : "volcengine-visual", - reqKey: engine === "bailian" ? bailian.imageModel : engine === "evolink" ? evolink.model : capability.reqKey - }; - }), - { - id: "video.generate", - label: "Seedance 视频生成", - kind: "video", - engine: "seedance", - provider: "seedance", - reqKey: getSeedanceConfig().model, - limits: { - durationSeconds: { min: 4, max: 15 }, - ratios: ["16:9", "4:3", "1:1", "3:4", "9:16", "21:9", "adaptive"], - resolutions: ["480p", "720p", "1080p"] - } - }, - { - id: "video.generate.bailian", - label: "百炼图生视频", - kind: "video", - engine: "bailian", - provider: "bailian", - reqKey: bailian.videoModel, - limits: { - inputImages: { min: 1, max: 2 }, - durationSeconds: { min: 2, max: 15 }, - resolutions: ["720P", "1080P"] - } - } - ] - }); - } catch (error) { - return publicApiError(error); - } -} diff --git a/app/api/v1/jobs/[id]/cancel/route.ts b/app/api/v1/jobs/[id]/cancel/route.ts deleted file mode 100644 index 9a1ff3b..0000000 --- a/app/api/v1/jobs/[id]/cancel/route.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { clearGenerationJobLock, getGenerationJob, updateGenerationJob } from "@/lib/server/data-store"; -import { jsonError, jsonOk } from "@/lib/server/api"; -import { authenticatePublicApiRequest, publicApiOwnerId } from "@/lib/server/public-api-auth"; -import { publicApiError } from "@/lib/server/public-api-response"; -import { refundGenerationCharge } from "@/lib/server/billing-service"; - -export const runtime = "nodejs"; - -export async function POST(request: Request, context: { params: Promise<{ id: string }> }) { - try { - const client = authenticatePublicApiRequest(request); - const { id } = await context.params; - const job = await getGenerationJob(id); - if (!job || job.ownerId !== publicApiOwnerId(client) || job.externalClientId !== client.id) { - return jsonError("Job not found.", 404); - } - if (["succeeded", "failed", "expired", "cancelled"].includes(job.status)) { - return jsonOk({ job }); - } - const cancelled = await updateGenerationJob(id, { - status: "cancelled", - completedAt: new Date().toISOString() - }); - const refunded = await refundGenerationCharge(cancelled, "任务已取消") || cancelled; - return jsonOk({ job: await clearGenerationJobLock(refunded.id) }); - } catch (error) { - return publicApiError(error); - } -} diff --git a/app/api/v1/jobs/[id]/route.ts b/app/api/v1/jobs/[id]/route.ts deleted file mode 100644 index 49149c5..0000000 --- a/app/api/v1/jobs/[id]/route.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { getGenerationJob } from "@/lib/server/data-store"; -import { jsonError, jsonOk } from "@/lib/server/api"; -import { authenticatePublicApiRequest, publicApiOwnerId } from "@/lib/server/public-api-auth"; -import { publicApiError } from "@/lib/server/public-api-response"; - -export const runtime = "nodejs"; - -export async function GET(request: Request, context: { params: Promise<{ id: string }> }) { - try { - const client = authenticatePublicApiRequest(request); - const { id } = await context.params; - const job = await getGenerationJob(id); - if (!job || job.ownerId !== publicApiOwnerId(client) || job.externalClientId !== client.id) { - return jsonError("Job not found.", 404); - } - return jsonOk({ job }); - } catch (error) { - return publicApiError(error); - } -} diff --git a/app/api/v1/jobs/route.ts b/app/api/v1/jobs/route.ts deleted file mode 100644 index 1613568..0000000 --- a/app/api/v1/jobs/route.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { listGenerationJobsFiltered } from "@/lib/server/data-store"; -import { jsonOk, readJsonBody } from "@/lib/server/api"; -import { authenticatePublicApiRequest, publicApiOwnerId } from "@/lib/server/public-api-auth"; -import { createPublicGenerationJob, type PublicJobCreateBody } from "@/lib/server/public-api-jobs"; -import { publicApiError } from "@/lib/server/public-api-response"; -import { requestOrigin } from "@/lib/server/runtime"; -import type { GenerationCapability, GenerationStatus } from "@/lib/types"; - -export const runtime = "nodejs"; - -export async function GET(request: Request) { - try { - const client = authenticatePublicApiRequest(request); - const url = new URL(request.url); - const jobs = await listGenerationJobsFiltered({ - ownerId: publicApiOwnerId(client), - externalClientId: client.id, - status: parseStatus(url.searchParams.get("status")), - capability: parseCapability(url.searchParams.get("capability")), - limit: parseLimit(url.searchParams.get("limit")), - before: url.searchParams.get("before") || undefined - }); - return jsonOk({ jobs }); - } catch (error) { - return publicApiError(error); - } -} - -export async function POST(request: Request) { - try { - const client = authenticatePublicApiRequest(request); - const body = await readJsonBody(request); - const result = await createPublicGenerationJob({ - client, - body, - request, - origin: requestOrigin(request) - }); - return jsonOk({ job: result.job, reused: result.reused }, { status: result.reused ? 200 : 202 }); - } catch (error) { - return publicApiError(error); - } -} - -function parseStatus(value: string | null): GenerationStatus | undefined { - if (!value) return undefined; - if (["queued", "running", "succeeded", "failed", "expired", "cancelled"].includes(value)) { - return value as GenerationStatus; - } - throw new Error(`Unsupported status filter: ${value}`); -} - -function parseCapability(value: string | null): GenerationCapability | undefined { - if (!value) return undefined; - if (["image.generate", "video.generate"].includes(value)) { - return value as GenerationCapability; - } - throw new Error(`Unsupported capability filter: ${value}`); -} - -function parseLimit(value: string | null): number { - const parsed = Number(value || 50); - if (!Number.isFinite(parsed)) return 50; - return Math.max(1, Math.min(200, Math.trunc(parsed))); -} diff --git a/app/api/v1/openapi.json/route.ts b/app/api/v1/openapi.json/route.ts deleted file mode 100644 index 3c7916f..0000000 --- a/app/api/v1/openapi.json/route.ts +++ /dev/null @@ -1,366 +0,0 @@ -import { jsonOk } from "@/lib/server/api"; -import { requestOrigin } from "@/lib/server/runtime"; - -export const runtime = "nodejs"; - -export async function GET(request: Request) { - return jsonOk({ - openapi: "3.1.0", - info: { - title: "智念AIGC平台 Public API", - version: "1.0.0", - description: "Public server-to-server API for uploading assets, creating image/video generation jobs, polling job status, downloading outputs, and receiving webhooks." - }, - servers: [ - { url: requestOrigin(request), description: "Current deployment" } - ], - security: [{ bearerApiKey: [] }, { headerApiKey: [] }], - components: { - securitySchemes: { - bearerApiKey: { type: "http", scheme: "bearer" }, - headerApiKey: { type: "apiKey", in: "header", name: "X-Zhinian-Api-Key" } - }, - schemas: { - ErrorResponse: { - type: "object", - required: ["error"], - properties: { - error: { type: "string" } - } - }, - Asset: { - type: "object", - required: ["id", "kind", "name", "url", "source", "createdAt"], - properties: { - id: { type: "string", example: "asset_mpqe9g85_12635f8cd8" }, - ownerId: { type: "string" }, - kind: { type: "string", enum: ["image", "video", "mask", "reference", "other"] }, - name: { type: "string", example: "result.png" }, - url: { type: "string", format: "uri" }, - storagePath: { type: "string" }, - source: { type: "string", enum: ["upload", "generated", "external", "seed"] }, - tags: { type: "array", items: { type: "string" } }, - metadata: { type: "object", additionalProperties: true }, - createdAt: { type: "string", format: "date-time" }, - updatedAt: { type: "string", format: "date-time" } - } - }, - GenerationJob: { - type: "object", - required: ["id", "capability", "provider", "status", "createdAt", "updatedAt"], - properties: { - id: { type: "string", example: "job_mpqe3wtt_12ed738079" }, - ownerId: { type: "string", example: "api:partner-a" }, - externalClientId: { type: "string" }, - capability: { $ref: "#/components/schemas/GenerationCapability" }, - provider: { type: "string", enum: ["volcengine-visual", "evolink", "seedance", "bailian", "mock"] }, - reqKey: { type: "string" }, - status: { $ref: "#/components/schemas/GenerationStatus" }, - prompt: { type: "string" }, - inputAssetIds: { type: "array", items: { type: "string" } }, - inputUrls: { type: "array", items: { type: "string", format: "uri" } }, - outputAssetIds: { type: "array", items: { type: "string" } }, - providerTaskId: { type: "string" }, - error: { - type: "object", - properties: { - code: { oneOf: [{ type: "string" }, { type: "number" }] }, - message: { type: "string" }, - retryable: { type: "boolean" } - } - }, - idempotencyKey: { type: "string" }, - priority: { type: "integer" }, - attempts: { type: "integer" }, - scheduledAt: { type: "string", format: "date-time" }, - completedAt: { type: "string", format: "date-time" }, - webhookUrl: { type: "string", format: "uri" }, - webhookAttempts: { type: "integer" }, - webhookLastStatus: { type: "object", additionalProperties: true }, - createdAt: { type: "string", format: "date-time" }, - updatedAt: { type: "string", format: "date-time" } - } - }, - GenerationCapability: { - type: "string", - enum: ["image.generate", "video.generate"] - }, - GenerationStatus: { - type: "string", - enum: ["queued", "running", "succeeded", "failed", "expired", "cancelled"] - }, - PromptMaterial: { - type: "object", - properties: { - id: { type: "string" }, - url: { type: "string", format: "uri" }, - type: { type: "string", enum: ["image", "video", "audio"] }, - role: { type: "string" }, - label: { type: "string" }, - name: { type: "string" } - } - }, - CreateJobRequest: { - type: "object", - required: ["capability"], - properties: { - capability: { $ref: "#/components/schemas/GenerationCapability" }, - prompt: { type: "string", description: "Prompt text. Required for image.generate unless promptAssembly is supplied." }, - inputUrls: { type: "array", items: { type: "string", format: "uri" }, description: "Reference image URLs for image capabilities." }, - imageUrls: { type: "array", items: { type: "string", format: "uri" }, description: "Alias for image input URLs." }, - inputAssetIds: { type: "array", items: { type: "string" } }, - materials: { type: "array", items: { $ref: "#/components/schemas/PromptMaterial" } }, - settings: { - type: "object", - description: "Video settings for video.generate.", - properties: { - ratio: { type: "string", enum: ["16:9", "4:3", "1:1", "3:4", "9:16", "21:9", "adaptive"] }, - duration: { type: "integer", minimum: 4, maximum: 15 }, - resolution: { type: "string", enum: ["480p", "720p", "1080p"] } - } - }, - width: { type: "integer", example: 1440 }, - height: { type: "integer", example: 2560 }, - scale: { type: "number", minimum: 1, maximum: 100, description: "Jimeng text influence for image.generate." }, - force_single: { type: "boolean" }, - quality: { type: "string", enum: ["low", "medium", "high"], description: "EvoLink image quality for image.generate." }, - priority: { type: "integer", minimum: -100, maximum: 100 }, - webhookUrl: { type: "string", format: "uri" }, - idempotencyKey: { type: "string", description: "Optional body-level idempotency key. Header Idempotency-Key is preferred." } - } - }, - RegisterAssetRequest: { - type: "object", - required: ["url"], - properties: { - url: { type: "string", format: "uri" }, - name: { type: "string" }, - kind: { type: "string", enum: ["image", "video", "mask", "reference", "other"] }, - tags: { type: "array", items: { type: "string" } } - } - }, - WebhookPayload: { - type: "object", - required: ["jobId", "status", "capability", "outputAssetIds", "updatedAt"], - properties: { - jobId: { type: "string", example: "job_mpqe3wtt_12ed738079" }, - status: { $ref: "#/components/schemas/GenerationStatus" }, - capability: { $ref: "#/components/schemas/GenerationCapability" }, - outputAssetIds: { type: "array", items: { type: "string" } }, - error: { - type: "object", - properties: { - code: { oneOf: [{ type: "string" }, { type: "number" }] }, - message: { type: "string" }, - retryable: { type: "boolean" } - } - }, - updatedAt: { type: "string", format: "date-time" } - } - } - } - }, - paths: { - "/api/v1/capabilities": { - get: { - summary: "List generation capabilities", - responses: { - "200": jsonResponse("Capabilities and active providers") - } - } - }, - "/api/v1/assets": { - get: { - summary: "List assets visible to the authenticated API client", - responses: { - "200": jsonResponse("Assets", { - type: "object", - properties: { - assets: { type: "array", items: { $ref: "#/components/schemas/Asset" } } - } - }) - } - }, - post: { - summary: "Upload files or register an external asset URL", - requestBody: { - required: true, - content: { - "application/json": { schema: { $ref: "#/components/schemas/RegisterAssetRequest" } }, - "multipart/form-data": { - schema: { - type: "object", - properties: { - files: { type: "array", items: { type: "string", format: "binary" } } - } - } - } - } - }, - responses: { - "201": jsonResponse("Created asset"), - "400": errorResponse(), - "401": errorResponse() - } - } - }, - "/api/v1/assets/{id}": { - get: { - summary: "Get one asset visible to the authenticated API client", - parameters: [pathId()], - responses: { - "200": jsonResponse("Asset", { - type: "object", - properties: { - asset: { $ref: "#/components/schemas/Asset" } - } - }), - "404": errorResponse() - } - } - }, - "/api/v1/assets/{id}/download": { - get: { - summary: "Download an output or uploaded asset", - parameters: [pathId()], - responses: { - "200": { - description: "Binary file", - headers: { - "Content-Disposition": { schema: { type: "string" } }, - "Content-Length": { schema: { type: "string" } } - }, - content: { - "application/octet-stream": { schema: { type: "string", format: "binary" } }, - "image/png": { schema: { type: "string", format: "binary" } }, - "image/jpeg": { schema: { type: "string", format: "binary" } }, - "video/mp4": { schema: { type: "string", format: "binary" } } - } - }, - "404": errorResponse() - } - } - }, - "/api/v1/jobs": { - get: { - summary: "List jobs for the authenticated API client", - parameters: [ - queryParam("status", { $ref: "#/components/schemas/GenerationStatus" }), - queryParam("capability", { $ref: "#/components/schemas/GenerationCapability" }), - queryParam("limit", { type: "integer", minimum: 1, maximum: 200 }), - queryParam("before", { type: "string", format: "date-time" }) - ], - responses: { - "200": jsonResponse("Jobs", { - type: "object", - properties: { - jobs: { type: "array", items: { $ref: "#/components/schemas/GenerationJob" } } - } - }) - } - }, - post: { - summary: "Create a queued generation job", - parameters: [ - { - name: "Idempotency-Key", - in: "header", - required: false, - schema: { type: "string" }, - description: "Reuse the same key for safe retries with the same request body." - } - ], - requestBody: { - required: true, - content: { - "application/json": { - schema: { $ref: "#/components/schemas/CreateJobRequest" }, - examples: { - imageGenerate: { - summary: "Image generation", - value: { - capability: "image.generate", - prompt: "生成一张专业产品主图", - width: 1440, - height: 2560, - webhookUrl: "https://example.com/zhinian/webhook" - } - }, - videoGenerate: { - summary: "Video generation", - value: { - capability: "video.generate", - prompt: "生成一条 9:16 品牌短视频", - settings: { ratio: "9:16", duration: 5, resolution: "720p" } - } - } - } - } - } - }, - responses: { - "202": jsonResponse("Queued job", { - type: "object", - properties: { - job: { $ref: "#/components/schemas/GenerationJob" }, - reused: { type: "boolean" } - } - }), - "409": errorResponse() - } - } - }, - "/api/v1/jobs/{id}": { - get: { - summary: "Get one job", - parameters: [pathId()], - responses: { - "200": jsonResponse("Job", { - type: "object", - properties: { - job: { $ref: "#/components/schemas/GenerationJob" } - } - }), - "404": errorResponse() - } - } - }, - "/api/v1/jobs/{id}/cancel": { - post: { - summary: "Cancel a queued or running job", - parameters: [pathId()], - responses: { - "200": jsonResponse("Cancelled job", { - type: "object", - properties: { - job: { $ref: "#/components/schemas/GenerationJob" } - } - }), - "404": errorResponse() - } - } - } - } - }); -} - -function pathId() { - return { name: "id", in: "path", required: true, schema: { type: "string" } }; -} - -function queryParam(name: string, schema: Record) { - return { name, in: "query", required: false, schema }; -} - -function jsonResponse(description: string, schema: Record = { type: "object", additionalProperties: true }) { - return { - description, - content: { - "application/json": { schema } - } - }; -} - -function errorResponse() { - return jsonResponse("Error", { $ref: "#/components/schemas/ErrorResponse" }); -} diff --git a/app/assets/page.tsx b/app/assets/page.tsx index 9f92fdd..7c556e3 100644 --- a/app/assets/page.tsx +++ b/app/assets/page.tsx @@ -1,7 +1,5 @@ -import { redirect } from "next/navigation"; - -export const dynamic = "force-dynamic"; +import { ClientRedirect } from "@/components/browser-auth"; export default function AssetsPage() { - redirect("/create"); + return ; } diff --git a/app/auth/admin-login/page.tsx b/app/auth/admin-login/page.tsx index d36d432..fcea41e 100644 --- a/app/auth/admin-login/page.tsx +++ b/app/auth/admin-login/page.tsx @@ -1,11 +1,5 @@ -import { redirect } from "next/navigation"; +import { ClientRedirect } from "@/components/browser-auth"; -export default async function AdminLoginPage({ - searchParams -}: { - searchParams?: Promise>; -}) { - const params = await searchParams; - const next = Array.isArray(params?.next) ? params?.next[0] : params?.next; - redirect(next ? `/auth/login?next=${encodeURIComponent(next)}` : "/auth/login"); +export default function AdminLoginPage() { + return ; } diff --git a/app/auth/login/page.tsx b/app/auth/login/page.tsx index d6d2a5d..df79419 100644 --- a/app/auth/login/page.tsx +++ b/app/auth/login/page.tsx @@ -1,38 +1,4 @@ -import { redirect } from "next/navigation"; import { AuthLoginPanel } from "@/components/auth-login-panel"; -import { getAuthRuntimeConfig, safeNextPath } from "@/lib/auth/config"; -import { getOptionalAuthSession } from "@/lib/server/auth/current-user"; - -const errorMessages: Record = { - auth_not_configured: "账号认证配置不完整,请联系管理员。", - callback_failed: "登录失败,请重新登录。", - state_invalid: "登录状态已失效,请重新登录。" -}; - -export default async function LoginPage({ - searchParams -}: { - searchParams?: Promise>; -}) { - const params = await searchParams; - const next = safeNextPath(singleParam(params?.next)); - const session = await getOptionalAuthSession(); - if (session) redirect(next); - - const config = getAuthRuntimeConfig(); - const errorCode = singleParam(params?.error); - const message = errorCode ? errorMessages[errorCode] || "登录失败,请重新登录。" : null; - - return ( - - ); -} - -function singleParam(value: string | string[] | undefined): string | undefined { - return Array.isArray(value) ? value[0] : value; +export default function LoginPage() { + return ; } diff --git a/app/billing/page.tsx b/app/billing/page.tsx index eab93ff..f0a0567 100644 --- a/app/billing/page.tsx +++ b/app/billing/page.tsx @@ -1,10 +1,13 @@ +"use client"; + import { BillingManager } from "@/components/billing-manager"; -import { hasSuperAdminAccess } from "@/lib/auth/permissions"; -import { requireAppSession } from "@/lib/server/auth/current-user"; +import { BrowserAuthGuard, useBrowserAuth } from "@/components/browser-auth"; -export const dynamic = "force-dynamic"; - -export default async function BillingPage() { - const session = await requireAppSession(); - return ; +export default function BillingPage() { + return ; +} + +function BillingContent() { + const { isSuperAdmin } = useBrowserAuth(); + return ; } diff --git a/app/create/page.tsx b/app/create/page.tsx index 04a8ef6..7a9d858 100644 --- a/app/create/page.tsx +++ b/app/create/page.tsx @@ -1,12 +1,19 @@ -import { CreateStudio } from "@/components/create-studio"; +"use client"; -export default async function CreatePage({ - searchParams -}: { - searchParams?: Promise>; -}) { - const params = await searchParams; - const modeParam = Array.isArray(params?.mode) ? params?.mode[0] : params?.mode; - const initialMode = modeParam === "video" ? "video" : "image"; - return ; +import { useEffect, useState } from "react"; +import { CreateStudio } from "@/components/create-studio"; +import { BrowserAuthGuard } from "@/components/browser-auth"; + +export default function CreatePage() { + const [initialMode, setInitialMode] = useState<"image" | "video" | null>(null); + + useEffect(() => { + setInitialMode(new URLSearchParams(window.location.search).get("mode") === "video" ? "video" : "image"); + }, []); + + return ( + + {initialMode ? :

正在加载创作台…

} +
+ ); } diff --git a/app/generated-results/[...path]/route.ts b/app/generated-results/[...path]/route.ts deleted file mode 100644 index 639ff06..0000000 --- a/app/generated-results/[...path]/route.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { getAssetByStoragePath } from "@/lib/server/data-store"; -import { requireAppUser } from "@/lib/server/auth/current-user"; -import { readLocalServedFile } from "@/lib/server/storage"; - -export const runtime = "nodejs"; - -export async function GET(_request: Request, context: { params: Promise<{ path: string[] }> }) { - const user = await requireAppUser(); - const { path } = await context.params; - const asset = await getAssetByStoragePath(["generated-results", ...path].join("/")); - if (!asset || asset.ownerId !== user.id) return new Response("Not found", { status: 404 }); - const file = await readLocalServedFile("generated-results", path); - if (!file) return new Response("Not found", { status: 404 }); - return new Response(new Uint8Array(file.bytes), { - headers: { - "Content-Type": file.contentType, - "Cache-Control": "public, max-age=31536000, immutable" - } - }); -} diff --git a/app/image-edit/page.tsx b/app/image-edit/page.tsx index 3775762..21ede43 100644 --- a/app/image-edit/page.tsx +++ b/app/image-edit/page.tsx @@ -1,5 +1,5 @@ -import { redirect } from "next/navigation"; +import { ClientRedirect } from "@/components/browser-auth"; export default function ImageEditPage() { - redirect("/create"); + return ; } diff --git a/app/layout.tsx b/app/layout.tsx index 35c12df..81bfa1b 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,8 +1,8 @@ import type { Metadata } from "next"; import Script from "next/script"; import { AppShell } from "@/components/app-shell"; +import { BrowserAuthProvider } from "@/components/browser-auth"; import { randomUUIDPolyfillScript } from "@/lib/client/random-uuid-polyfill"; -import { getShellAuthState } from "@/lib/server/auth/current-user"; import "./globals.css"; export const metadata: Metadata = { @@ -10,8 +10,7 @@ export const metadata: Metadata = { description: "智念AIGC平台:统一创作图片与视频。" }; -export default async function RootLayout({ children }: { children: React.ReactNode }) { - const auth = await getShellAuthState(); +export default function RootLayout({ children }: { children: React.ReactNode }) { return ( @@ -20,7 +19,9 @@ export default async function RootLayout({ children }: { children: React.ReactNo strategy="beforeInteractive" dangerouslySetInnerHTML={{ __html: randomUUIDPolyfillScript }} /> - {children} + + {children} + ); diff --git a/app/logs/page.tsx b/app/logs/page.tsx index f1be42c..0b78fcf 100644 --- a/app/logs/page.tsx +++ b/app/logs/page.tsx @@ -1,9 +1,6 @@ import { LogManager } from "@/components/log-manager"; -import { requireSuperAdminUser } from "@/lib/server/auth/current-user"; +import { BrowserAuthGuard } from "@/components/browser-auth"; -export const dynamic = "force-dynamic"; - -export default async function LogsPage() { - await requireSuperAdminUser(); - return ; +export default function LogsPage() { + return ; } diff --git a/app/page.tsx b/app/page.tsx index 28b5130..b7a2f74 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,5 +1,5 @@ -import { redirect } from "next/navigation"; +import { ClientRedirect } from "@/components/browser-auth"; export default function HomePage() { - redirect("/create"); + return ; } diff --git a/app/settings/page.tsx b/app/settings/page.tsx index cc1105e..3b0b313 100644 --- a/app/settings/page.tsx +++ b/app/settings/page.tsx @@ -1,14 +1,17 @@ +"use client"; + import { SettingsPanel } from "@/components/settings-panel"; -import { hasSuperAdminAccess } from "@/lib/auth/permissions"; -import { requireAppSession } from "@/lib/server/auth/current-user"; +import { BrowserAuthGuard, useBrowserAuth } from "@/components/browser-auth"; -export const dynamic = "force-dynamic"; +export default function SettingsPage() { + return ; +} -export default async function SettingsPage() { - const session = await requireAppSession(); +function SettingsContent() { + const { isSuperAdmin } = useBrowserAuth(); return (
- {hasSuperAdminAccess(session.user) ? : ( + {isSuperAdmin ? : (

系统设置

系统配置仅由超级管理员维护。

diff --git a/app/uploads/[...path]/route.ts b/app/uploads/[...path]/route.ts deleted file mode 100644 index 6086675..0000000 --- a/app/uploads/[...path]/route.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { getAssetByStoragePath } from "@/lib/server/data-store"; -import { requireAppUser } from "@/lib/server/auth/current-user"; -import { readLocalServedFile } from "@/lib/server/storage"; - -export const runtime = "nodejs"; - -export async function GET(_request: Request, context: { params: Promise<{ path: string[] }> }) { - const user = await requireAppUser(); - const { path } = await context.params; - const asset = await getAssetByStoragePath(["uploads", ...path].join("/")); - if (!asset || asset.ownerId !== user.id) return new Response("Not found", { status: 404 }); - const file = await readLocalServedFile("uploads", path); - if (!file) return new Response("Not found", { status: 404 }); - return new Response(new Uint8Array(file.bytes), { - headers: { - "Content-Type": file.contentType, - "Cache-Control": "public, max-age=31536000, immutable" - } - }); -} diff --git a/app/usage/page.tsx b/app/usage/page.tsx index 9b8ed8e..ee3e9c6 100644 --- a/app/usage/page.tsx +++ b/app/usage/page.tsx @@ -1,10 +1,13 @@ +"use client"; + import { UsageManager } from "@/components/usage-manager"; -import { hasSuperAdminAccess } from "@/lib/auth/permissions"; -import { requireAdminSession } from "@/lib/server/auth/current-user"; +import { BrowserAuthGuard, useBrowserAuth } from "@/components/browser-auth"; -export const dynamic = "force-dynamic"; - -export default async function UsagePage() { - const session = await requireAdminSession(); - return ; +export default function UsagePage() { + return ; +} + +function UsageContent() { + const { isSuperAdmin } = useBrowserAuth(); + return ; } diff --git a/backend/README.md b/backend/README.md index 5348387..899a490 100644 --- a/backend/README.md +++ b/backend/README.md @@ -1,10 +1,10 @@ # Go modular backend -This directory contains the separately runnable Go implementation of ADR-003. -It now owns the checked-in compatibility implementation for all 66 explicit -HTTP method/path entries, but it is **not** the current production traffic -owner: Next.js, the Node Worker, Docker Compose, and the ACK manifests remain -unchanged until a later, explicit cutover. +This directory contains the production application backend. Go is the sole +runtime owner of `/api`, `/uploads`, and `/generated-results`, including browser +sessions, authorization, persistence, provider calls, and the embedded +WorkerLoop. The frontend is a static Next.js export served by Nginx and calls +these Go routes through the public same-origin Ingress. Implemented Modules: @@ -76,8 +76,8 @@ docker build -f backend/Dockerfile.runtime \ ``` The runner defaults to `CGO_ENABLED=0` for reproducible cross-platform builds. -To exercise the local foundation manually without changing the existing Next -server, use a different port: +To exercise the backend locally, listen on port 8080 and route browser API +requests there with a same-origin development proxy: ```bash ZHINIAN_DATA_BACKEND=local GO_BACKEND_PORT=8080 ./backend/zhinian-api @@ -85,8 +85,7 @@ ZHINIAN_DATA_BACKEND=local GO_BACKEND_PORT=8080 ./backend/zhinian-api In local mode, persistent business data is process-local and is discarded on restart; it is intended only for development and contract smoke tests. The -default demo identity is the same optional-auth super administrator used by the -current Next development flow. +default demo identity supports the optional-auth frontend development flow. ## First super administrator @@ -105,7 +104,8 @@ process startup so a misconfigured bootstrap is visible instead of silently missing. Local development mode keeps the seeded demo administrator and never bootstrap-creates accounts. -No Ingress, Docker, ACK, Secret, or Worker ownership has moved to Go yet, so -Next.js remains the deployed owner of every route. Real RDS/CA, OSS, provider, -Webhook, Worker drain/recovery, and rollback validation are mandatory before -that route ownership changes. +Production routing, Secret ownership, probes, and rollout commands are defined +in [`../docs/DEPLOYMENT.md`](../docs/DEPLOYMENT.md) and `../deploy/ack/`. Go owns +the session signing Secret and backend runtime configuration; the static Web +workload receives neither. Validate RDS/CA, OSS, providers, Webhooks, embedded +Worker recovery, and rollback behavior for each production release. diff --git a/backend/internal/application/application_test.go b/backend/internal/application/application_test.go index f41c8d4..c4be03d 100644 --- a/backend/internal/application/application_test.go +++ b/backend/internal/application/application_test.go @@ -93,7 +93,7 @@ func TestProductionLocalBackendNeverGrantsAnonymousAdministrator(t *testing.T) { } } -func TestApplicationDerivesNextCompatibleMethodMatrixBeforeAuthentication(t *testing.T) { +func TestApplicationDerivesLegacyCompatibleMethodMatrixBeforeAuthentication(t *testing.T) { app, err := application.New(application.Options{Getenv: applicationEnv(map[string]string{ "NODE_ENV": "production", "ZHINIAN_DATA_BACKEND": "local", diff --git a/backend/internal/billing/http_service.go b/backend/internal/billing/http_service.go index f9451e3..e1a7ca3 100644 --- a/backend/internal/billing/http_service.go +++ b/backend/internal/billing/http_service.go @@ -92,8 +92,8 @@ type AdjustmentCommand struct { AmountFen, DeltaFen int64 } type AdjustmentResult struct { - Wallet Wallet - Entry LedgerEntry + Wallet Wallet `json:"wallet"` + Entry LedgerEntry `json:"entry"` } type AccountConfigStore interface { diff --git a/backend/internal/httpapi/billing_test.go b/backend/internal/httpapi/billing_test.go index 5e05c96..97c799f 100644 --- a/backend/internal/httpapi/billing_test.go +++ b/backend/internal/httpapi/billing_test.go @@ -74,9 +74,26 @@ func TestBillingAdminRoutesRequireSuperAdminAndValidateWrites(t *testing.T) { if got := serveJSON(t, super, http.MethodPatch, "/api/admin/billing/account", map[string]any{"accountName": " Acme ", "bankName": " Bank ", "accountNumber": " 123 ", "contact": " Ops "}); got.Code != 200 || account.saved.AccountName != "Acme" { t.Fatalf("account status=%d saved=%+v body=%s", got.Code, account.saved, got.Body.String()) } - if got := serveJSON(t, super, http.MethodPost, "/api/admin/billing/adjustments", map[string]any{"organizationId": "org", "amountYuan": 1.235, "direction": "debit", "note": " correction "}); got.Code != 200 || service.adjustment.AmountFen != 124 || service.adjustment.DeltaFen != -124 || service.adjustment.OperatorID != "root" { + got := serveJSON(t, super, http.MethodPost, "/api/admin/billing/adjustments", map[string]any{"organizationId": "org", "amountYuan": 1.235, "direction": "debit", "note": " correction "}) + if got.Code != 200 || service.adjustment.AmountFen != 124 || service.adjustment.DeltaFen != -124 || service.adjustment.OperatorID != "root" { t.Fatalf("adjustment status=%d got=%+v body=%s", got.Code, service.adjustment, got.Body.String()) } + var adjustmentResponse map[string]json.RawMessage + if err := json.Unmarshal(got.Body.Bytes(), &adjustmentResponse); err != nil { + t.Fatalf("decode adjustment response: %v", err) + } + if _, ok := adjustmentResponse["wallet"]; !ok { + t.Fatalf("adjustment response missing lowercase wallet: %s", got.Body.String()) + } + if _, ok := adjustmentResponse["entry"]; !ok { + t.Fatalf("adjustment response missing lowercase entry: %s", got.Body.String()) + } + if _, ok := adjustmentResponse["Wallet"]; ok { + t.Fatalf("adjustment response contains uppercase Wallet: %s", got.Body.String()) + } + if _, ok := adjustmentResponse["Entry"]; ok { + t.Fatalf("adjustment response contains uppercase Entry: %s", got.Body.String()) + } if got := serveJSON(t, super, http.MethodPatch, "/api/admin/billing/prices/price-1", map[string]any{"standardUnitPriceFen": 1, "markupMultiplier": 2}); got.Code != 400 { t.Fatalf("whitelist status=%d", got.Code) } diff --git a/backend/internal/httpapi/method_compat.go b/backend/internal/httpapi/method_compat.go index 16b2d6c..05b5f3e 100644 --- a/backend/internal/httpapi/method_compat.go +++ b/backend/internal/httpapi/method_compat.go @@ -12,10 +12,10 @@ type routeMethodPattern struct { allow []string } -// WithRouteMethodCompatibility applies the method behavior that Next derives -// from app route exports. It sits outside authentication so OPTIONS never -// depends on runtime configuration and HEAD executes the corresponding GET -// semantics while suppressing the response body. +// WithRouteMethodCompatibility applies the legacy-compatible method matrix +// for the checked-in public HTTP contract. It sits outside authentication so +// OPTIONS never depends on runtime configuration and HEAD executes the +// corresponding GET semantics while suppressing the response body. func WithRouteMethodCompatibility(next http.Handler) http.Handler { patterns := routeMethodPatterns(GoRouteSurface()) return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/backend/internal/httpapi/route_surface.go b/backend/internal/httpapi/route_surface.go index 28230e3..f421ae4 100644 --- a/backend/internal/httpapi/route_surface.go +++ b/backend/internal/httpapi/route_surface.go @@ -6,7 +6,7 @@ import ( // RouteSurface describes one externally visible route explicitly owned by the // Go modular monolith. It is kept source-independent so contract tests can -// compare it with the checked-in Next.js surface before any cutover. +// compare it with the checked-in public HTTP contract. type RouteSurface struct { Method string `json:"method"` Path string `json:"path"` diff --git a/backend/internal/httpapi/route_surface_test.go b/backend/internal/httpapi/route_surface_test.go index 349a141..a6abd7d 100644 --- a/backend/internal/httpapi/route_surface_test.go +++ b/backend/internal/httpapi/route_surface_test.go @@ -10,7 +10,7 @@ import ( "testing" ) -func TestGoRouteSurfaceExactlyMatchesCheckedInNextManifest(t *testing.T) { +func TestGoRouteSurfaceExactlyMatchesCheckedInPublicHTTPContract(t *testing.T) { _, source, _, _ := runtime.Caller(0) raw, err := os.ReadFile(filepath.Join(filepath.Dir(source), "../../../contracts/http/route-surface.v1.json")) if err != nil { diff --git a/components/app-shell.tsx b/components/app-shell.tsx index ae636c7..8dd5b74 100644 --- a/components/app-shell.tsx +++ b/components/app-shell.tsx @@ -16,8 +16,8 @@ import { } from "lucide-react"; import clsx from "clsx"; import { revealChildren, runScopedMotion } from "@/lib/ui/motion"; -import type { AuthUser } from "@/lib/auth/session"; import { AccountUsageMenu } from "@/components/account-usage-menu"; +import { useBrowserAuth } from "@/components/browser-auth"; const nav = [ { href: "/create", label: "创作", icon: Sparkles }, @@ -28,19 +28,8 @@ const nav = [ { href: "/billing", label: "计费", icon: WalletCards } ]; -export function AppShell({ - children, - user, - authRequired, - isAdmin, - isSuperAdmin -}: { - children: React.ReactNode; - user?: AuthUser | null; - authRequired?: boolean; - isAdmin?: boolean; - isSuperAdmin?: boolean; -}) { +export function AppShell({ children }: { children: React.ReactNode }) { + const { user, authRequired, isAdmin, isSuperAdmin } = useBrowserAuth(); const pathname = usePathname(); const shellRef = useRef(null); const isAuthPage = pathname.startsWith("/auth"); diff --git a/components/auth-login-panel.tsx b/components/auth-login-panel.tsx index f24d2f7..851d5e3 100644 --- a/components/auth-login-panel.tsx +++ b/components/auth-login-panel.tsx @@ -5,37 +5,47 @@ import type { FormEvent } from "react"; import Image from "next/image"; import { Loader2, LogIn } from "lucide-react"; import { pulseFeedback, revealChildren, runScopedMotion } from "@/lib/ui/motion"; +import { useBrowserAuth } from "@/components/browser-auth"; +import { safeBrowserNext } from "@/lib/client/browser-auth"; export function AuthLoginPanel({ - next, - configured, - message, - missing, title = "账户登录", submitLabel = "登录" }: { - next: string; - configured: boolean; - message?: string | null; - missing?: string[]; title?: string; submitLabel?: string; }) { + const auth = useBrowserAuth(); const [phone, setPhone] = useState(""); const [password, setPassword] = useState(""); const [submitting, setSubmitting] = useState(false); const [error, setError] = useState(null); + const [next, setNext] = useState("/create"); + const [message, setMessage] = useState(null); const screenRef = useRef(null); const feedbackRef = useRef(null); - const hasMissingConfig = !configured && Boolean(missing?.length); + const configured = auth.status === "ready" && auth.authConfigured; + const hasMissingConfig = auth.status === "ready" && auth.authRequired && !auth.authConfigured; useEffect(() => { return runScopedMotion(screenRef, (scope) => revealChildren(scope)); }, []); + useEffect(() => { + const params = new URLSearchParams(window.location.search); + setNext(safeBrowserNext(params.get("next"))); + const errorCode = params.get("error"); + if (errorCode) setMessage(errorMessages[errorCode] || "登录失败,请重新登录。"); + else if (params.get("loggedOut") === "1") setMessage("已退出登录。"); + }, []); + + useEffect(() => { + if (auth.status === "ready" && auth.user) window.location.replace(next); + }, [auth.status, auth.user, next]); + useEffect(() => { pulseFeedback(feedbackRef.current); - }, [error, message, missing?.join(",")]); + }, [error, message, hasMissingConfig]); async function submit(event: FormEvent) { event.preventDefault(); @@ -58,7 +68,7 @@ export function AuthLoginPanel({ }); const result = await response.json().catch(() => ({})) as { error?: string; redirectTo?: string }; if (!response.ok) throw new Error(result.error || "登录失败"); - window.location.assign(result.redirectTo || next || "/create"); + window.location.assign(safeBrowserNext(result.redirectTo, next)); } catch (err) { setError(err instanceof Error ? err.message : String(err)); } finally { @@ -76,14 +86,15 @@ export function AuthLoginPanel({

{title}

- {message || hasMissingConfig || error ? ( + {message || hasMissingConfig || auth.status === "error" || error ? (
{message ?
{message}
: null} {hasMissingConfig ? (
- 缺少配置:{missing?.join("、")} + 账号认证配置不完整,请联系管理员。
) : null} + {auth.status === "error" ?
{auth.error || "无法读取认证状态。"}
: null} {error ?
{error}
: null}
) : null} @@ -128,3 +139,9 @@ export function AuthLoginPanel({ function formStringValue(value: FormDataEntryValue | null): string { return typeof value === "string" ? value.trim() : ""; } + +const errorMessages: Record = { + auth_not_configured: "账号认证配置不完整,请联系管理员。", + callback_failed: "登录失败,请重新登录。", + state_invalid: "登录状态已失效,请重新登录。" +}; diff --git a/components/browser-auth.tsx b/components/browser-auth.tsx new file mode 100644 index 0000000..8f6a7cf --- /dev/null +++ b/components/browser-auth.tsx @@ -0,0 +1,130 @@ +"use client"; + +import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react"; +import { usePathname, useRouter } from "next/navigation"; +import type { AuthMode, AuthUser } from "@/lib/auth/session"; +import { fetchBrowserAuthState, safeBrowserLocationNext, type BrowserCurrentSession } from "@/lib/client/browser-auth"; + +type BrowserAuthStatus = "loading" | "ready" | "error"; + +type BrowserAuthState = { + status: BrowserAuthStatus; + user: AuthUser | null; + authMode: AuthMode | null; + authRequired: boolean; + authConfigured: boolean; + isAdmin: boolean; + isSuperAdmin: boolean; + error: string | null; + refresh: () => Promise; +}; + +const BrowserAuthContext = createContext(null); + +export function BrowserAuthProvider({ children }: { children: React.ReactNode }) { + const [session, setSession] = useState(null); + const [status, setStatus] = useState("loading"); + const [error, setError] = useState(null); + + const loadSession = useCallback(async (signal?: AbortSignal) => { + try { + const current = await fetchBrowserAuthState(signal); + setSession(current); + setStatus("ready"); + setError(null); + } catch (cause) { + if (cause instanceof DOMException && cause.name === "AbortError") return; + setStatus("error"); + setError(cause instanceof Error ? cause.message : "无法读取认证状态"); + } + }, []); + + useEffect(() => { + const controller = new AbortController(); + void loadSession(controller.signal); + return () => controller.abort(); + }, [loadSession]); + + const value = useMemo(() => { + const user = session?.user || null; + const authRequired = session?.authRequired ?? true; + const isSuperAdmin = !authRequired || user?.role === "super_admin"; + const isAdmin = isSuperAdmin || user?.role === "organization_admin"; + return { + status, + user, + authMode: session?.authMode || null, + authRequired, + authConfigured: session?.authConfigured ?? false, + isAdmin, + isSuperAdmin, + error, + refresh: () => loadSession() + }; + }, [error, loadSession, session, status]); + + return {children}; +} + +export function useBrowserAuth(): BrowserAuthState { + const state = useContext(BrowserAuthContext); + if (!state) throw new Error("useBrowserAuth must be used inside BrowserAuthProvider"); + return state; +} + +export function BrowserAuthGuard({ + children, + role = "user" +}: { + children: React.ReactNode; + role?: "user" | "admin" | "super"; +}) { + const auth = useBrowserAuth(); + const pathname = usePathname(); + const router = useRouter(); + const needsLogin = auth.status === "ready" && auth.authRequired && !auth.user; + + useEffect(() => { + if (needsLogin) { + const next = safeBrowserLocationNext(window.location, pathname || "/create"); + router.replace(`/auth/login?next=${encodeURIComponent(next)}`); + } + }, [needsLogin, pathname, router]); + + if (auth.status === "loading" || needsLogin) { + return ; + } + if (auth.status === "error") { + return void auth.refresh()} />; + } + if ((role === "admin" && !auth.isAdmin) || (role === "super" && !auth.isSuperAdmin)) { + return ; + } + return <>{children}; +} + +export function ClientRedirect({ to, forwardNext = false }: { to: string; forwardNext?: boolean }) { + useEffect(() => { + const next = forwardNext ? new URLSearchParams(window.location.search).get("next") : null; + const destination = next ? `${to}?next=${encodeURIComponent(next)}` : to; + window.location.replace(destination); + }, [forwardNext, to]); + return ; +} + +function AuthStatePanel({ + message, + actionLabel, + onAction +}: { + message: string; + actionLabel?: string; + onAction?: () => void; +}) { + return ( +
+

{message}

+ {actionLabel && onAction ? : null} +
+ ); +} diff --git a/deploy/ack/configmap.yaml b/deploy/ack/configmap.yaml index b31a1f7..c8c01f9 100644 --- a/deploy/ack/configmap.yaml +++ b/deploy/ack/configmap.yaml @@ -1,15 +1,3 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: zhinian-runtime - namespace: zhinian -data: - NODE_ENV: production - PORT: "3000" - ZHINIAN_AUTH_REQUIRED: "1" - ZHINIAN_PUBLIC_BASE_URL: https://REPLACE_WITH_PUBLIC_HOST - ZHINIAN_GO_INTERNAL_BASE_URL: http://zhinian-go-api:8080 ---- # Go API runtime settings. Provider endpoints/models use code defaults unless # optional provider/OSS credentials are added to the Deployment. apiVersion: v1 diff --git a/deploy/ack/go-api.yaml b/deploy/ack/go-api.yaml index 081fbfb..cfe807c 100644 --- a/deploy/ack/go-api.yaml +++ b/deploy/ack/go-api.yaml @@ -45,12 +45,12 @@ spec: secretKeyRef: name: zhinian-go-db key: DATABASE_URL - # The session secret must be the same value Next.js uses so the - # frontend middleware and the Go backend verify the same cookies. + # Go alone creates and verifies the browser session cookie. The + # static Web workload must never receive this signing secret. - name: ZHINIAN_AUTH_SESSION_SECRET valueFrom: secretKeyRef: - name: zhinian-web-auth + name: zhinian-go-auth key: ZHINIAN_AUTH_SESSION_SECRET - name: ZHINIAN_BOOTSTRAP_ADMIN_PHONE valueFrom: diff --git a/deploy/ack/ingress.yaml b/deploy/ack/ingress.yaml index 35c93ad..2a44625 100644 --- a/deploy/ack/ingress.yaml +++ b/deploy/ack/ingress.yaml @@ -43,7 +43,7 @@ spec: name: zhinian-go-api port: number: 8080 - # Pages and static assets stay with Next.js. + # Exported pages and static assets stay with the stateless Web Nginx. - path: / pathType: Prefix backend: diff --git a/deploy/ack/migration-job.yaml b/deploy/ack/migration-job.yaml deleted file mode 100644 index 0c29b69..0000000 --- a/deploy/ack/migration-job.yaml +++ /dev/null @@ -1,60 +0,0 @@ -# DEPRECATED (2026-08-14): the initial production schema is executed manually -# from database/migrations/*.sql plus application-role grants. This Job is not -# part of the first-deployment path; keep the manifest only as an optional -# automation reference. -apiVersion: batch/v1 -kind: Job -metadata: - name: zhinian-db-migrate - namespace: zhinian -spec: - backoffLimit: 2 - ttlSecondsAfterFinished: 86400 - template: - metadata: - labels: - app.kubernetes.io/name: zhinian - app.kubernetes.io/component: database-migration - spec: - restartPolicy: Never - automountServiceAccountToken: false - securityContext: - seccompProfile: - type: RuntimeDefault - containers: - - name: migrate - image: REGISTRY/PROJECT/zhinian-aigc:REPLACE_TAG - imagePullPolicy: IfNotPresent - command: ["node", "scripts/migrate-postgres.mjs"] - env: - - name: NODE_ENV - value: production - - name: ZHINIAN_DATA_BACKEND - value: postgres - # Must match the username in zhinian-go-db/DATABASE_URL. - - name: DATABASE_APP_ROLE - value: REPLACE_WITH_RDS_APP_ROLE - - name: DATABASE_URL - valueFrom: - secretKeyRef: - name: zhinian-migration-db - key: DATABASE_URL - volumeMounts: - - name: rds-ca - mountPath: /etc/zhinian/rds - readOnly: true - resources: - requests: - cpu: 100m - memory: 128Mi - limits: - cpu: 500m - memory: 512Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: ["ALL"] - volumes: - - name: rds-ca - secret: - secretName: zhinian-rds-ca diff --git a/deploy/ack/secrets.example.yaml b/deploy/ack/secrets.example.yaml index 397e452..fe55725 100644 --- a/deploy/ack/secrets.example.yaml +++ b/deploy/ack/secrets.example.yaml @@ -25,12 +25,12 @@ stringData: apiVersion: v1 kind: Secret metadata: - name: zhinian-web-auth + name: zhinian-go-auth namespace: zhinian type: Opaque stringData: - # Shared by the Next.js middleware and the Go backend so both verify the - # same session cookies. Keep identical across workloads. + # Go is the sole owner of session creation and verification. Static Web never + # receives this signing secret. ZHINIAN_AUTH_SESSION_SECRET: REPLACE_WITH_A_DIFFERENT_LONG_RANDOM_VALUE --- apiVersion: v1 diff --git a/deploy/ack/web.yaml b/deploy/ack/web.yaml index 7e5f5fc..1d4cd44 100644 --- a/deploy/ack/web.yaml +++ b/deploy/ack/web.yaml @@ -1,16 +1,11 @@ -# Next.js frontend workload for the first production deployment: serves pages, -# static assets, and SSR only. All /api, /uploads, and /generated-results -# traffic is routed to zhinian-go-api by the Ingress, so this workload holds no -# RDS credentials and needs only the shared session secret for local cookie -# verification in the middleware. +# Stateless static frontend. Nginx serves the exported Next.js files only; all +# /api, /uploads, and /generated-results traffic belongs to zhinian-go-api. apiVersion: apps/v1 kind: Deployment metadata: name: zhinian-web namespace: zhinian spec: - # Keep one replica until uploaded/generated files are stored in OSS or another - # shared object store. PostgreSQL alone does not make local runtime files shared. replicas: 1 strategy: type: RollingUpdate @@ -29,6 +24,11 @@ spec: spec: automountServiceAccountToken: false securityContext: + runAsNonRoot: true + runAsUser: 101 + runAsGroup: 101 + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch seccompProfile: type: RuntimeDefault containers: @@ -38,47 +38,41 @@ spec: ports: - name: http containerPort: 3000 - envFrom: - - configMapRef: - name: zhinian-runtime - env: - # The session secret must be the same value the Go backend uses so - # the frontend middleware and the Go backend verify the same cookies. - - name: ZHINIAN_AUTH_SESSION_SECRET - valueFrom: - secretKeyRef: - name: zhinian-web-auth - key: ZHINIAN_AUTH_SESSION_SECRET startupProbe: httpGet: - path: /api/health + path: /healthz port: http periodSeconds: 5 failureThreshold: 24 readinessProbe: httpGet: - path: /api/health + path: /healthz port: http periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 livenessProbe: httpGet: - path: /api/health + path: /healthz port: http periodSeconds: 20 timeoutSeconds: 3 failureThreshold: 3 resources: requests: - cpu: 250m - memory: 512Mi + cpu: 25m + memory: 32Mi limits: - cpu: "1" - memory: 1Gi + cpu: 250m + memory: 128Mi securityContext: allowPrivilegeEscalation: false + readOnlyRootFilesystem: true capabilities: drop: ["ALL"] - # The current image runs as root. Add a fixed non-root image user and - # verify /app/.runtime permissions before enabling runAsNonRoot. + volumeMounts: + - name: nginx-tmp + mountPath: /tmp + volumes: + - name: nginx-tmp + emptyDir: {} diff --git a/deploy/ack/worker.yaml b/deploy/ack/worker.yaml deleted file mode 100644 index 040a65a..0000000 --- a/deploy/ack/worker.yaml +++ /dev/null @@ -1,52 +0,0 @@ -# DEPRECATED (2026-08-14): production deploys the Go API workload with the -# embedded WorkerLoop (ZHINIAN_GO_EMBEDDED_WORKER=true). The Node Worker is -# local-development only; do not apply this manifest in production. -apiVersion: apps/v1 -kind: Deployment -metadata: - name: zhinian-worker - namespace: zhinian -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: zhinian - app.kubernetes.io/component: worker - template: - metadata: - labels: - app.kubernetes.io/name: zhinian - app.kubernetes.io/component: worker - spec: - automountServiceAccountToken: false - securityContext: - seccompProfile: - type: RuntimeDefault - containers: - - name: worker - image: REGISTRY/PROJECT/zhinian-aigc:REPLACE_TAG - imagePullPolicy: IfNotPresent - command: ["node", "scripts/worker.mjs"] - env: - - name: NODE_ENV - value: production - - name: ZHINIAN_WORKER_BASE_URL - value: http://zhinian-web:3000 - - name: ZHINIAN_WORKER_REQUEST_TIMEOUT_MS - value: "120000" - - name: ZHINIAN_INTERNAL_WORKER_TOKEN - valueFrom: - secretKeyRef: - name: zhinian-worker-auth - key: ZHINIAN_INTERNAL_WORKER_TOKEN - resources: - requests: - cpu: 100m - memory: 128Mi - limits: - cpu: 500m - memory: 256Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: ["ALL"] diff --git a/deploy/nginx.conf b/deploy/nginx.conf new file mode 100644 index 0000000..13f0379 --- /dev/null +++ b/deploy/nginx.conf @@ -0,0 +1,51 @@ +worker_processes auto; +pid /tmp/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + access_log /dev/stdout; + error_log /dev/stderr warn; + sendfile on; + server_tokens off; + + client_body_temp_path /tmp/client_temp; + proxy_temp_path /tmp/proxy_temp; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + + server { + listen 3000; + root /usr/share/nginx/html; + + location = /healthz { + access_log off; + default_type text/plain; + return 200 "ok\n"; + } + + # These paths are owned by the Go workload. Ingress routes them there; + # reject them here as defense in depth if Web is reached directly. + location ~ ^/(api|uploads|generated-results)(?:/|$) { + return 404; + } + + location /_next/static/ { + expires 1y; + add_header Cache-Control "public, max-age=31536000, immutable"; + try_files $uri =404; + } + + location / { + add_header Cache-Control "no-cache, no-store, must-revalidate" always; + add_header Pragma "no-cache" always; + add_header Expires "0" always; + try_files $uri $uri.html $uri/ /index.html; + } + } +} diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md index 8099b91..a78f5d3 100644 --- a/docs/DEPLOYMENT.md +++ b/docs/DEPLOYMENT.md @@ -1,333 +1,156 @@ # 智念AIGC平台部署说明 -## 阿里云 ACK + RDS PostgreSQL(生产) +## 生产拓扑 -生产环境设置 `ZHINIAN_DATA_BACKEND=postgres`,并通过 Kubernetes Secret 注入 -`DATABASE_URL`。优先使用 RDS 内网连接地址;ACK 节点/Pod 与 RDS 必须位于同一 -或网络可达的 VPC,并在 RDS 白名单或安全组中仅放行实际工作负载网段。 +生产环境只有两类运行时: -数据库连接只配置一个 `DATABASE_URL`。默认按 `sslmode=verify-full` 建立 TLS 连接;如果 -容器内没有 RDS CA 根证书,请把 CA 路径直接写进连接串,例如: -`...?sslmode=verify-full&sslrootcert=/etc/zhinian/rds/ca.pem`,并按需挂载 CA 文件。 -不再设置 `DATABASE_SSL_MODE` 或 `DATABASE_CA_CERT_PATH`。 +- `zhinian-web`:Nginx 静态容器,只包含 Next.js `out/` 导出结果,不读取 Secret、 + ConfigMap、数据库或 Go 内网地址。 +- `zhinian-go-api`:唯一应用后端,负责 `/api`、`/uploads`、 + `/generated-results`、登录会话、权限、数据库、供应商调用及内嵌 WorkerLoop。 -```bash -kubectl apply -f deploy/ack/configmap.yaml -kubectl apply -f deploy/ack/secrets.example.yaml # 仅作模板;先替换全部占位值 -kubectl apply -f deploy/ack/web.yaml -f deploy/ack/go-api.yaml \ - -f deploy/ack/service.yaml -f deploy/ack/ingress.yaml -``` +浏览器始终请求同一个公网域名。Ingress 将后端路径转发给 Go,其余页面和静态资源转发给 +Web。登录 Cookie 为 HttpOnly Cookie,由浏览器自动随同域 API 请求携带;静态 Web +不解析 Cookie,也不持有会话签名密钥。 -生产拓扑为 ADR-003 双工作负载:Next.js 只服务页面/静态资源/SSR(不持有任何 -RDS/服务商凭据,仅共享会话密钥);Go 工作负载 `zhinian-go-api` 独占 -`/api`、`/uploads`、`/generated-results`,内嵌 WorkerLoop(生产**不部署** -Node Worker,`worker.yaml` 已弃用保留)。Ingress 按路径分流:页面 → Web, -后端路径 → Go,`/api/internal/worker` → 无端点 deny Service。 - -Next.js 的生产 SSR 通过 Web runtime ConfigMap 中的 -`ZHINIAN_GO_INTERNAL_BASE_URL=http://zhinian-go-api:8080` 访问集群内 Go -Service。该变量只供 Next 服务端 SSR 使用,不是公开访问地址,不应放入 -`NEXT_PUBLIC_*` 或暴露给浏览器;公网请求仍通过 Ingress 的公开域名进入。 - -Go 镜像构建(四选一,详见 [`backend/README.md`](./backend/README.md)): - -```bash -# 自包含构建(推荐国内 CI):单条命令,只拉 alpine 基础镜像,Go 工具链来自 -# alpine 包(阿里云 apk 镜像),模块走 goproxy.cn -docker build -f backend/Dockerfile.alpine -t REGISTRY/PROJECT/zhinian-go-api:TAG backend/ - -# 标准多阶段构建 -docker build -f backend/Dockerfile -t REGISTRY/PROJECT/zhinian-go-api:TAG backend/ - -# 镜像加速器无法拉取 golang 镜像时,用 --build-arg 换源 -docker build -f backend/Dockerfile \ - --build-arg GOLANG_IMAGE=<可用镜像源>/golang:1.21-alpine \ - --build-arg RUNTIME_IMAGE=<可用镜像源>/alpine:3.20 \ - -t REGISTRY/PROJECT/zhinian-go-api:TAG backend/ - -# 完全绕开 golang 镜像:先在任意有 Go 1.21 的机器编译静态二进制,再只基于 alpine 组装 -cd backend -CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \ - go build -trimpath -ldflags="-s -w" -o zhinian-api.linux ./cmd/zhinian-api -docker build -f backend/Dockerfile.runtime -t REGISTRY/PROJECT/zhinian-go-api:TAG backend/ -``` - -Go 首次启动时从 `zhinian-go-bootstrap` Secret 读取 -`ZHINIAN_BOOTSTRAP_ADMIN_*`,仅当不存在任何超级管理员时创建一次。 - -数据库 schema 由部署负责人在发布前手工执行,**不部署迁移 Job Pod**(清单 -`deploy/ack/migration-job.yaml` 已弃用保留):使用迁移角色账号依次执行 -`database/migrations/0001_initial_schema.sql`、`0002_generation_lifecycle_fencing.sql`, -再执行应用角色授权语句(表权限 + 两个并发函数 `claim_generation_jobs` 与 -`billing_post_wallet_entry` 的 EXECUTE 权限,参见 -`scripts/migrate-postgres.mjs` 中的 `provisionApplicationRole`)。Web/Go 的数据库 -账号应只具有应用运行权限。以后每次 schema 变更同样按版本化 SQL 文件手工执行,并在 -变更后再滚动工作负载。 - -迁移 SQL 包含重复数据保护:遇到重复的历史 `usage_events.job_id` 会失败并要求人工 -审计,不会自动删除计费/用量记录;清理后重新执行对应文件。 - -替换模板占位符后,可先运行 `npm run deploy:check` 做仓库内静态契约检查;真正发布前仍需 -使用目标 ACK 集群的 `kubectl apply --dry-run=server` 验证 CRD/准入策略和 Ingress 行为。 - -ACK 中的 Secret/ConfigMap 才是配置事实来源。不要在 `/settings` 页面修改生产密钥:该 -页面写入容器内 `.env.local`,Pod 重建会丢失,也不会自动更新 Kubernetes Secret。应修改 -Secret/ConfigMap 后触发 Deployment 滚动更新。 - -模板默认 Web 为 1 副本,因为仅启用 PostgreSQL 并不会共享上传/生成文件。确认这些文件 -已使用 OSS 或其他共享对象存储后,才可水平扩容;本地 `.runtime` 数据或文件不能在副本 -之间共享。Worker 只持有内部 token 并调用集群内 `zhinian-web` Service,不持有 -`DATABASE_URL`。Ingress 通过更长的 `/api/internal/worker` Prefix 把公网请求路由到 -没有 Endpoint 的 `zhinian-public-deny` Service,因此不会把内部接口转发给 Web;也可以 -在 API Gateway/WAF 再配置等价拒绝规则。不要默认添加依赖 Terway 或特定 ACK 托管组件 -的 webhook/白名单注解。 - -探针约定:`/api/health` 是不查询数据库的进程存活检查;`/api/ready` 会确认 PostgreSQL -关键表存在,并验证应用角色具备任务表读写和两个业务函数的执行权限,失败返回 503。 -启动探针避免迁移/冷启动期间过早重启。Worker 每次内部 tick 默认 120 秒超时,避免网络 -半开连接让轮询进程永久卡住;可用 `ZHINIAN_WORKER_REQUEST_TIMEOUT_MS` 调整。 - -连接预算按 `Web 副本数 × DATABASE_POOL_MAX` 计算,并为迁移、管理连接和故障切换 -预留余量。滚动更新默认可能短暂同时存在旧、新 Pod;模板将 `maxSurge` 设为 1,容量 -预算至少覆盖 `(replicas + 1) × pool max`,否则应降低 pool 或使用 `maxSurge: 0`。 - -当前 Docker runner 默认以 Node Alpine 镜像的 root 用户运行,模板没有虚构一个未经 -镜像验证的 UID。生产加固应在镜像中创建固定非 root 用户、修正 `/app/.runtime` 权限, -验证写入与启动后,再把 Pod 设置为 `runAsNonRoot: true`。 - -关键数据库变量: - -| 变量 | 说明 | +| 公网路径 | 工作负载 | | --- | --- | -| `ZHINIAN_DATA_BACKEND` | 生产固定为 `postgres`;配置错误不会降级到本地 JSON | -| `DATABASE_URL` | PostgreSQL URI,仅存 Secret;不要写入镜像、ConfigMap 或日志 | -| `DATABASE_APP_ROLE` | 应用角色名;手工执行授权语句时使用,与 Web/Go 的 RDS 用户名一致 | -| `DATABASE_URL` 的 `sslmode` / `sslrootcert` | 可在同一个连接串中指定 TLS 模式和 CA 路径;默认 `sslmode=verify-full` | -| `DATABASE_POOL_MAX` | 单个 Web Pod 最大连接数 | -| `DATABASE_CONNECTION_TIMEOUT_MS` | 建连超时;模板为 5000 ms | -| `DATABASE_IDLE_TIMEOUT_MS` | 空闲连接回收时间 | -| `DATABASE_STATEMENT_TIMEOUT_MS` | SQL 语句超时 | +| `/api/internal/worker` | selectorless deny Service,不对公网开放 | +| `/api/*` | `zhinian-go-api:8080` | +| `/uploads/*` | `zhinian-go-api:8080` | +| `/generated-results/*` | `zhinian-go-api:8080` | +| 其他路径 | `zhinian-web:3000` | -旧 `NEXT_PUBLIC_SUPABASE_URL`、`NEXT_PUBLIC_SUPABASE_ANON_KEY` 和 -`SUPABASE_SERVICE_ROLE_KEY` 已废弃,直连 PostgreSQL 路径不会读取它们。 +Web Nginx 对 Go 所有的三类路径也会直接返回 404,避免绕过 Ingress 后形成第二套 API +边界。 -本文面向运维部署。推荐使用 Docker Compose,同一套编排会启动 Web 服务和任务 Worker。 +## 构建镜像 -## 服务器要求 - -- Linux 服务器 -- Docker -- Docker Compose v2(`docker compose`)或旧版 `docker-compose` -- 可访问外网供应商接口:火山 Visual、EvoLink、Seedance、OSS - -## 一键部署 +Web 镜像在 builder 阶段执行静态导出,runner 只保留非 root Nginx 和 `out/`: ```bash -git clone <仓库地址> -cd NianAIGC -bash scripts/deploy.sh +docker build -t REGISTRY/PROJECT/zhinian-aigc:TAG . ``` -脚本会自动: - -- 从 `.env.example` 创建 `.env.local`(如果不存在) -- 创建 `.runtime/data`、`.runtime/uploads`、`.runtime/generated-results` -- 创建 `.runtime/logs` -- 构建镜像 -- 启动 `zhinian-aigc` Web 服务 -- 启动 `zhinian-worker` 任务 Worker -- 输出容器状态 - -默认访问: - -```text -http://服务器IP:3000 -``` - -## 必填生产配置 - -部署前编辑 `.env.local`: - -```env -APP_PORT=3000 -PORT=3000 -HOSTNAME=0.0.0.0 -NEXT_PUBLIC_APP_URL=https://你的域名 - -ZHINIAN_AUTH_REQUIRED=auto -ZHINIAN_AUTH_SESSION_SECRET=请替换为强随机会话密钥 -ZHINIAN_DATA_BACKEND=postgres -DATABASE_URL=postgresql://应用账号:密码@RDS内网地址:5432/数据库名 -# 可选:把 sslmode/sslrootcert 直接写入 DATABASE_URL - -ZHINIAN_API_KEYS=partner-a:请替换为强随机key -ZHINIAN_INTERNAL_WORKER_TOKEN=请替换为强随机token -ZHINIAN_WEBHOOK_SECRET=请替换为webhook签名密钥 -``` - -`ZHINIAN_API_KEYS` 冒号前是开放 API 账号 ID。不同账号 ID 的任务、素材和幂等键会写入不同 owner 分区,例如 `api:partner-a`。 - -真实生成能力按需配置: - -```env -IMAGE_GENERATE_ENGINE=evolink - -EVOLINK_API_KEY= - -VOLCENGINE_ACCESS_KEY_ID= -VOLCENGINE_SECRET_ACCESS_KEY= - -SEEDANCE_API_KEY= - -ALI_OSS_ENDPOINT= -ALI_OSS_BUCKET= -ALI_OSS_ACCESS_KEY_ID= -ALI_OSS_ACCESS_KEY_SECRET= -ALI_OSS_PUBLIC_BASE_URL= -``` - -如果不配置真实供应商密钥,mock 配置会保留本地验收能力,但生产对接应配置真实密钥。 - -平台账号部署说明: - -```text -npm run bootstrap:admin -- --phone 13800138000 --password '请替换为强密码' --name '平台超级管理员' -``` - -生产部署前先手工执行版本化 SQL 完成建库建表与授权(见上文"手工建库建表"步骤),然后 -通过环境变量初始化超级管理员:Go 后端首次启动时读取 -`ZHINIAN_BOOTSTRAP_ADMIN_PHONE` / `ZHINIAN_BOOTSTRAP_ADMIN_PASSWORD` / -`ZHINIAN_BOOTSTRAP_ADMIN_NAME`(密码至少 8 位,名称缺省为"平台超级管理员"),仅在 -不存在任何超级管理员时创建一次,无需单独脚本。旧的 `npm run bootstrap:admin` 脚本 -仅为本地/Next 开发保留。授权只向应用角色显式授予当前业务表 DML 和两个数据库函数 -EXECUTE;不会授予未来对象的默认权限、`schema_migrations` 或 DDL 权限。新增表/函数时 -必须随对应版本 SQL 显式更新授权。旧账号导入脚本 `npm run migrate:accounts` 仅为历史 -遗留工具保留,新部署无需使用。 - -## 旧版组织账号接口(已停用) - -如需启用 `/accounts` 后台账号管理,按组织能力接口文档配置: - -```env -ZHINIAN_ORG_API_BASE_URL=https:///hotelStaff -ZHINIAN_ORG_API_TOKEN= -ZHINIAN_STAFF_API_BASE_URL=https:///hotelStaff -ZHINIAN_STAFF_API_TOKEN= -ZHINIAN_ORG_TENANT_ID= -ZHINIAN_ORG_ID= -ZHINIAN_ORG_MEMBER_LIST_PATH= -``` - -平台后端会代理调用组织、部门、角色、成员和企业端用户接口;成员分页列表默认通过 `hotelStaff` 的 `/adminOrganization/organizationMember/organizationMemberList` 对外代理,只有直连基础组织服务内部 `/organizationMember/organizationMemberList` 时才需要 `from: Y`。如统一服务路径不同,可配置 `ZHINIAN_ORG_MEMBER_LIST_PATH` 覆盖。创建账号调用 `/adminOrganization/organizationMember/addOrganizationMemberAndCreatePlatformUser`,重置密码调用 `/adminPcUser/resetPlatformUserPassword`。这些接口默认转发当前登录管理员账号的 `access_token`,企业端用户接口会校验该 token 是否具备管理员角色 `1`;`ZHINIAN_ORG_API_TOKEN` / `ZHINIAN_STAFF_API_TOKEN` 只作为无登录 token 时的服务端兜底。 - -## 常用运维命令 +Go 镜像构建方式见 [`backend/README.md`](../backend/README.md)。国内 CI 可使用: ```bash -docker compose ps -docker compose logs -f zhinian-aigc -docker compose logs -f zhinian-worker -docker compose restart -docker compose down +docker build -f backend/Dockerfile.alpine \ + -t REGISTRY/PROJECT/zhinian-go-api:TAG backend/ ``` -Web 后台可在登录后访问: +发布前把 `deploy/ack/web.yaml` 和 `deploy/ack/go-api.yaml` 中的镜像占位符替换为 +不可变标签或 digest。 -```text -https://你的域名/logs -https://你的域名/settings -https://你的域名/accounts -https://你的域名/usage -https://你的域名/billing -``` +## RDS 与首次初始化 -日志默认写入 `.runtime/logs/server-events.jsonl`,用于查看 API 500 错误、Worker 任务异常、错误栈和请求路径。可通过环境变量 `ZHINIAN_LOG_DIR` 调整目录,通过 `ZHINIAN_LOG_MAX_BYTES` 调整单文件轮转大小。 +生产固定使用 PostgreSQL。数据库连接只通过 Go Deployment 的 Secret 注入,不得进入 +Web 镜像或 ConfigMap。优先使用 RDS 内网地址,并仅对白名单中的 ACK 工作负载网段放行。 -更新部署: +`DATABASE_URL` 应包含完整 TLS 参数。默认建议 `sslmode=verify-full`;需要自定义 CA 时, +把 `sslrootcert=/etc/zhinian/rds/ca.pem` 写入同一个连接串并挂载对应 Secret。 + +首次发布前,部署负责人按顺序手工执行: + +1. `database/migrations/0001_initial_schema.sql` +2. `database/migrations/0002_generation_lifecycle_fencing.sql` +3. 应用角色授权语句(参考 `scripts/migrate-postgres.mjs`) + +生产不部署迁移 Job。遇到历史重复数据时迁移会失败,需先人工审计,不能跳过或自动删除 +计费与用量记录。仓库不再提供可误执行的 Node Migration Job 或 Node Worker 清单;后台 +任务由 Go API 内嵌 WorkerLoop 处理。 + +Go 首次启动会读取 `zhinian-go-bootstrap` Secret 中的 +`ZHINIAN_BOOTSTRAP_ADMIN_PHONE` 和 `ZHINIAN_BOOTSTRAP_ADMIN_PASSWORD`,仅在不存在 +超级管理员时创建一次。当前 ACK 清单不注入 `ZHINIAN_BOOTSTRAP_ADMIN_NAME`,因此名称 +使用 Go 的默认值“平台超级管理员”。 + +## ACK 配置与发布 + +先根据 [`deploy/ack/secrets.example.yaml`](../deploy/ack/secrets.example.yaml) 创建不提交 +Git 的 `deploy/ack/secrets.production.yaml`,替换所有占位值。Web 不需要任何运行时 +Secret;会话密钥只属于 Go。 + +仓库内静态检查: ```bash -git pull -bash scripts/deploy.sh +npm run deploy:check ``` -健康检查: +提交到集群前还应使用目标集群验证准入策略: ```bash -curl -f http://127.0.0.1:${APP_PORT:-3000}/api/health +# 首次部署必须先真实创建 Namespace;否则后续 namespaced Secret/资源无法 dry-run。 +kubectl apply -f deploy/ack/namespace.yaml + +kubectl apply --dry-run=server -f deploy/ack/secrets.production.yaml +kubectl apply --dry-run=server -f deploy/ack/configmap.yaml +kubectl apply --dry-run=server -f deploy/ack/go-api.yaml +kubectl apply --dry-run=server -f deploy/ack/web.yaml +kubectl apply --dry-run=server -f deploy/ack/service.yaml +kubectl apply --dry-run=server -f deploy/ack/ingress.yaml ``` -OpenAPI: +确认无误后发布: ```bash -curl http://127.0.0.1:${APP_PORT:-3000}/api/v1/openapi.json +# Namespace 已在上一步单独创建;Secret 必须先于引用它的工作负载发布。 +kubectl apply -f deploy/ack/secrets.production.yaml +kubectl apply -f deploy/ack/configmap.yaml +kubectl apply -f deploy/ack/go-api.yaml +kubectl apply -f deploy/ack/web.yaml +kubectl apply -f deploy/ack/service.yaml +kubectl apply -f deploy/ack/ingress.yaml ``` -## 数据持久化 +Web 使用固定 UID/GID `101`、只读根文件系统和 `/tmp` 临时卷,监听容器端口 +`3000`。它是无状态静态服务,可以独立扩容。Go 模板默认一个副本;未接入 OSS 或其他 +共享对象存储前,不要扩容 Go,否则上传及生成文件不能在副本间共享。此时文件位于 Go +Pod 的 `emptyDir`,Pod 重建或滚动升级同样会永久丢失上传文件和生成结果;生产持久化这些 +文件必须先接入 OSS 或其他共享对象存储。 -Docker Compose 会挂载: +## 配置边界 -```text -./.runtime:/app/.runtime -``` +`zhinian-go-runtime` ConfigMap 只保存非敏感 Go 运行参数。下列敏感值必须放在 +Kubernetes Secret: -本地 JSON 数据层、上传文件和生成结果都会放在 `.runtime/` 下。`local` 仅适合单实例开发;如临时使用,必须备份该目录。 -服务端日志也会放在 `.runtime/logs/` 下,建议和运行时数据一起备份或接入服务器日志采集。 +- `DATABASE_URL` +- `ZHINIAN_AUTH_SESSION_SECRET`(Secret 名 `zhinian-go-auth`,仅注入 Go) +- `ZHINIAN_BOOTSTRAP_ADMIN_PHONE`、`ZHINIAN_BOOTSTRAP_ADMIN_PASSWORD` +- 服务商与 OSS 凭据 +- 开放 API Key、Webhook 签名密钥等 -生产 PostgreSQL 发布前必须按顺序手工执行版本化 SQL 文件(0001 再 0002)与角色授权;不部署 `zhinian-db-migrate` Job。执行完成后再滚动工作负载。首次打开 `/billing` 或提交真实任务时,系统会自动导入内置标准成本目录;平台参数档案会同步,已有倍率会保留,超级管理员只维护上浮倍率。 +生产配置的事实来源是 ACK Secret/ConfigMap。不要通过静态页面或修改 Pod 文件来更新 +生产密钥;修改 Secret/ConfigMap 后滚动 Go Deployment。 -建议备份: +## 探针与验收 + +- Web `/healthz`:Nginx 静态进程存活检查。 +- Go `/api/health`:Go 进程存活检查,不查询数据库。 +- Go `/api/ready`:检查 PostgreSQL schema、表权限和业务函数权限。 + +发布后执行: ```bash -tar -czf zhinian-runtime-$(date +%Y%m%d%H%M%S).tar.gz .runtime -``` +kubectl rollout status deployment/zhinian-go-api -n zhinian +kubectl rollout status deployment/zhinian-web -n zhinian -## 服务组成 - -- `zhinian-aigc`:Next.js Web/API 服务,默认容器端口 `3000` -- `zhinian-worker`:后台任务 Worker,负责提交供应商任务、轮询结果、导入资产和触发 Webhook - -注意:只启动 Web 服务时,任务会停留在 `queued` 或 `running`,必须同时运行 Worker。 - -## 反向代理建议 - -Nginx 示例: - -```nginx -server { - listen 80; - server_name your-domain.com; - - client_max_body_size 100m; - - location / { - proxy_pass http://127.0.0.1:3000; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } -} -``` - -配置反向代理后,将 `.env.local` 里的 `NEXT_PUBLIC_APP_URL` 设置成公网 HTTPS 地址。 - -## 验收清单 - -部署后执行: - -```bash +curl -f https://你的域名/ curl -f https://你的域名/api/health -curl -H "Authorization: Bearer " https://你的域名/api/v1/capabilities +curl -f https://你的域名/api/ready curl https://你的域名/api/v1/openapi.json ``` -确认: +还应验证: -- 未登录访问 Web 页面会跳转到 `/auth/login` -- 普通用户登录后看到创作、账号和计费;账号页可修改自己的密码,任务详情、输入要素和结果下载均在创作页右侧任务模块完成,点击页头账号 ID 可查看自己的快捷周期用量 -- 从管理员入口登录且命中管理员账号或专用角色白名单后,可访问 `/logs`、`/settings`、`/usage`,并在 `/accounts` 额外维护组织和成员;超级管理员还可配置 `/billing` 计费规则和组织余额 -- `/usage` 可按日期、组织、账号、功能和服务商筛选,Mock 与开放 API 任务不计入 -- `/billing` 可查看组织余额、成员消耗和账务流水;管理员通过“余额与上账”直接记入组织额度 -- `/api/health` 返回 `ok: true` -- `/logs` 可查看后台错误日志 -- `/api/v1/capabilities` 使用 API Key 可访问 -- `zhinian-worker` 日志持续输出 `claimed=...` -- OSS、EvoLink、火山、Seedance 密钥按业务需要配置完成 +- 未登录访问受保护页面后,浏览器跳转到 `/auth/login`。 +- 登录成功后,`GET /api/auth/me` 返回当前用户,刷新页面仍保持登录态。 +- 普通用户无法访问管理员 API;管理员页面与 API 权限一致。 +- 上传、生成结果访问分别通过 `/uploads`、`/generated-results` 命中 Go。 +- Web Pod 中不存在数据库、服务商、会话签名密钥或 Go 内网地址。 + +## 本地开发 + +`npm run dev` 仍用于前端开发;`npm run build` 生成可静态托管的 `out/`。生产不运行 +Node Web 进程。需要完整联调时,同时启动 Go API,并用反向代理按 +与生产相同的路径规则将同一站点的后端请求转发给 Go。 diff --git a/lib/client/browser-auth.ts b/lib/client/browser-auth.ts new file mode 100644 index 0000000..ecd2ea4 --- /dev/null +++ b/lib/client/browser-auth.ts @@ -0,0 +1,93 @@ +import type { AuthMode, AuthUser } from "@/lib/auth/session"; + +export type BrowserCurrentSession = { + authenticated: boolean; + authRequired: boolean; + authConfigured: boolean; + authMode: AuthMode | null; + user: AuthUser | null; +}; + +export async function fetchBrowserAuthState(signal?: AbortSignal): Promise { + const response = await fetch("/api/auth/me", { + method: "GET", + cache: "no-store", + credentials: "same-origin", + headers: { Accept: "application/json" }, + signal + }); + if (!response.ok) throw new Error(`认证状态请求失败(${response.status})`); + return parseCurrentSession(await response.json()); +} + +export function safeBrowserNext(value: string | null | undefined, fallback = "/create"): string { + if (!value || !value.startsWith("/") || value.startsWith("//") || value.includes("\\")) return fallback; + try { + const base = "http://zhinian.local"; + const parsed = new URL(value, base); + if (parsed.origin !== base) return fallback; + const path = `${parsed.pathname}${parsed.search}${parsed.hash}`; + if (parsed.pathname.startsWith("/api/auth") || parsed.pathname.startsWith("/auth/login") || parsed.pathname.startsWith("/auth/admin-login")) { + return fallback; + } + return path; + } catch { + return fallback; + } +} + +export function safeBrowserLocationNext( + location: Pick, + fallback = "/create" +): string { + return safeBrowserNext(`${location.pathname}${location.search}${location.hash}`, fallback); +} + +function parseCurrentSession(value: unknown): BrowserCurrentSession { + if (!isRecord(value) || typeof value.authenticated !== "boolean" || typeof value.authRequired !== "boolean" || typeof value.authConfigured !== "boolean") { + throw new Error("认证状态响应格式无效"); + } + if (!value.authenticated) { + if (value.authMode !== null || value.user !== null) throw new Error("认证状态响应格式无效"); + return { + authenticated: false, + authRequired: value.authRequired, + authConfigured: value.authConfigured, + authMode: null, + user: null + }; + } + if (!value.authConfigured || (value.authMode !== "user" && value.authMode !== "admin") || !isAuthUser(value.user)) { + throw new Error("认证用户响应格式无效"); + } + const expectedMode: AuthMode = value.user.role === "user" ? "user" : "admin"; + if (value.authMode !== expectedMode) throw new Error("认证用户响应格式无效"); + return { + authenticated: true, + authRequired: value.authRequired, + authConfigured: value.authConfigured, + authMode: value.authMode, + user: value.user + }; +} + +function isRecord(value: unknown): value is Record { + return typeof value === "object" && value !== null; +} + +function isAuthUser(value: unknown): value is AuthUser { + return isRecord(value) && + typeof value.id === "string" && + value.id.length > 0 && + typeof value.subject === "string" && + value.subject === value.id && + typeof value.displayName === "string" && + typeof value.clientId === "string" && + (value.role === "user" || value.role === "organization_admin" || value.role === "super_admin") && + value.status === "active" && + (value.role === "super_admin" || (typeof value.organizationId === "string" && value.organizationId.length > 0)) && + Array.isArray(value.authorities) && + value.authorities.every((item) => typeof item === "string") && + Array.isArray(value.scope) && + value.scope.every((item) => typeof item === "string"); +} diff --git a/middleware.ts b/middleware.ts deleted file mode 100644 index 5e4b194..0000000 --- a/middleware.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { NextResponse, type NextRequest } from "next/server"; -import { SESSION_COOKIE_NAME, getAuthRuntimeConfig, safeNextPath } from "@/lib/auth/config"; -import { hasAdminSessionAccess, hasSuperAdminAccess } from "@/lib/auth/permissions"; -import { parseSessionCookieValue, readChunkedCookieValue } from "@/lib/auth/session"; - -export async function middleware(request: NextRequest) { - const config = getAuthRuntimeConfig(); - if (!config.required) return NextResponse.next(); - - const pathname = request.nextUrl.pathname; - if (config.configured && config.sessionSecret) { - const session = await parseSessionCookieValue( - readChunkedCookieValue(SESSION_COOKIE_NAME, (name) => request.cookies.get(name)?.value), - config.sessionSecret - ); - if (session) { - const access = requiredAccess(pathname); - const allowed = access === "super" - ? hasSuperAdminAccess(session.user) - : access === "admin" - ? hasAdminSessionAccess(session) - : true; - if (!allowed) { - if (pathname.startsWith("/api/")) { - return NextResponse.json({ error: access === "super" ? "需要超级管理员权限。" : "需要管理员权限。" }, { status: 403 }); - } - return NextResponse.redirect(new URL(access === "super" ? "/create" : "/create", request.url)); - } - return NextResponse.next(); - } - } - - if (pathname.startsWith("/api/")) { - return NextResponse.json({ - error: config.configured ? "请先登录。" : "认证配置不完整。" - }, { status: config.configured ? 401 : 503 }); - } - - const loginUrl = new URL("/auth/login", request.url); - loginUrl.searchParams.set("next", safeNextPath(`${pathname}${request.nextUrl.search}`)); - if (!config.configured) loginUrl.searchParams.set("error", "auth_not_configured"); - return NextResponse.redirect(loginUrl); -} - -export const config = { - matcher: [ - "/", - "/create/:path*", - "/assets/:path*", - "/logs/:path*", - "/settings/:path*", - "/accounts/:path*", - "/usage/:path*", - "/billing/:path*", - "/image-edit/:path*", - "/uploads/:path*", - "/generated-results/:path*", - "/api/assets/:path*", - "/api/generations/:path*", - "/api/usage/:path*", - "/api/billing/:path*", - "/api/logs/:path*", - "/api/prompt/:path*", - "/api/settings/:path*", - "/api/admin/:path*" - ] -}; - -function requiredAccess(pathname: string): "super" | "admin" | null { - if (pathname.startsWith("/logs") || pathname.startsWith("/api/logs") || pathname.startsWith("/api/settings")) return "super"; - if (pathname.startsWith("/usage") || pathname.startsWith("/api/admin")) return "admin"; - return null; -} diff --git a/next.config.ts b/next.config.ts index 25aab3b..f13478d 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,16 +1,13 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { + output: "export", // Keep dev artifacts separate from production builds. Running `next build` // while a dev server is alive must not invalidate the dev server's chunks. distDir: process.env.NODE_ENV === "development" ? ".next-dev" : ".next", devIndicators: false, - experimental: { - serverActions: { - bodySizeLimit: "12mb" - } - }, images: { + unoptimized: true, remotePatterns: [ { protocol: "https", hostname: "**" }, { protocol: "http", hostname: "127.0.0.1" }, diff --git a/package.json b/package.json index 2a67e43..b1ee684 100644 --- a/package.json +++ b/package.json @@ -8,12 +8,6 @@ "scripts": { "dev": "next dev", "build": "next build", - "prestart": "next build", - "start": "next start --hostname 127.0.0.1 --port 3000", - "start:server": "next start --hostname 0.0.0.0 --port 3000", - "worker": "node scripts/worker.mjs", - "worker:once": "node scripts/worker.mjs --once", - "health": "node scripts/health-check.mjs", "info": "node scripts/print-app-info.mjs", "bootstrap:admin": "node scripts/bootstrap-admin.mjs", "db:migrate": "node scripts/migrate-postgres.mjs", diff --git a/scripts/check-ack-manifests.mjs b/scripts/check-ack-manifests.mjs index f9e2107..d500b98 100644 --- a/scripts/check-ack-manifests.mjs +++ b/scripts/check-ack-manifests.mjs @@ -1,8 +1,13 @@ import { readFileSync, readdirSync } from "node:fs"; const directory = new URL("../deploy/ack/", import.meta.url); +const repository = new URL("../", import.meta.url); const files = readdirSync(directory).filter((name) => name.endsWith(".yaml")).sort(); +assert(!files.includes("migration-job.yaml"), "ACK must not ship the removed Node migration Job"); +assert(!files.includes("worker.yaml"), "ACK must not ship the removed Node worker Deployment"); +assert(files.includes("namespace.yaml"), "ACK must include the Namespace manifest required by first deployment"); + for (const file of files) { const text = readFileSync(new URL(file, directory), "utf8"); assert(text.includes("apiVersion:"), `${file}: missing apiVersion`); @@ -10,41 +15,45 @@ for (const file of files) { assert(!text.includes("server-snippet"), `${file}: must not depend on disabled snippet annotations`); } -const migrationJob = read("migration-job.yaml"); -assert(migrationJob.includes("name: ZHINIAN_DATA_BACKEND\n value: postgres"), "migration Job must select postgres"); -assert(migrationJob.includes("name: DATABASE_APP_ROLE"), "migration Job must provision the Web role"); -assert(migrationJob.includes("secretName: zhinian-rds-ca"), "migration Job must mount the optional RDS CA used by DATABASE_URL"); -assert(!migrationJob.includes("DATABASE_SSL_MODE"), "migration Job must keep database TLS inside DATABASE_URL"); -assert(!migrationJob.includes("DATABASE_CA_CERT_PATH"), "migration Job must keep database TLS inside DATABASE_URL"); - const web = read("web.yaml"); -assert(/^\s*replicas: 1\s*$/m.test(web), "Web must default to one replica until object storage is shared"); -assert(web.includes("path: /api/health"), "Web must use process-level readiness (it is database-free in production)"); -assert(web.includes("name: zhinian-runtime"), "Web must consume the Web runtime ConfigMap"); +assert(/^\s*replicas: 1\s*$/m.test(web), "Web must default to one replica for the first deployment"); +assert(web.includes("path: /healthz"), "Web must probe the static Nginx health endpoint"); +assert(!/^\s*env(?:From)?:\s*$/m.test(web), "Web must not receive runtime environment configuration"); +assert(!web.includes("secretKeyRef:"), "Web must not receive application secrets"); +assert(web.includes("runAsNonRoot: true"), "Web must run as a non-root user"); +assert(web.includes("runAsUser: 101"), "Web must run as the unprivileged Nginx user"); +assert(web.includes("fsGroup: 101"), "Web temporary volume must be writable by unprivileged Nginx"); +assert(web.includes("readOnlyRootFilesystem: true"), "Web root filesystem must be read-only"); assert(!web.includes("ZHINIAN_DATA_BACKEND"), "Web must not select a database backend in production"); assert(!web.includes("DATABASE_URL"), "Web must not receive DATABASE_URL in production"); assert(!web.includes("zhinian-web-db"), "Web must not hold RDS credentials in production"); assert(!web.includes("rds-ca"), "Web must not mount the RDS CA in production"); +assert(!web.includes("ZHINIAN_AUTH_SESSION_SECRET"), "Web must not receive the Go session signing secret"); +assert(!web.includes("ZHINIAN_GO_INTERNAL_BASE_URL"), "Web must not receive an internal Go URL"); const goApi = read("go-api.yaml"); assert(/^\s*replicas: 1\s*$/m.test(goApi), "Go API must default to one replica until object storage is shared"); assert(goApi.includes("path: /api/ready"), "Go API must use database-aware readiness"); assert(goApi.includes("runAsNonRoot: true"), "Go API must run as a non-root user"); assert(goApi.includes("name: zhinian-go-runtime"), "Go API must consume the Go runtime ConfigMap"); +assert(goApi.includes("name: zhinian-go-auth"), "Go API must own the browser session signing Secret"); +assert(!goApi.includes("name: zhinian-web-auth"), "Go API must not reference the removed Web auth Secret"); assert(goApi.includes("name: zhinian-go-bootstrap"), "Go API must receive bootstrap administrator credentials"); assert(goApi.includes("secretName: zhinian-rds-ca"), "Go API must mount the optional RDS CA used by DATABASE_URL"); assert(!goApi.includes("DATABASE_SSL_MODE"), "Go API must keep database TLS inside DATABASE_URL"); assert(!goApi.includes("DATABASE_CA_CERT_PATH"), "Go API must keep database TLS inside DATABASE_URL"); +const secrets = read("secrets.example.yaml"); +assert(secrets.includes("name: zhinian-go-auth"), "Example secrets must name Go as the session Secret owner"); +assert(!secrets.includes("name: zhinian-web-auth"), "Example secrets must not retain the removed Web auth Secret"); + +const namespace = read("namespace.yaml"); +assert(namespace.includes("kind: Namespace"), "namespace.yaml must define a Namespace"); +assert(namespace.includes("name: zhinian"), "namespace.yaml must create the zhinian Namespace"); + const configMap = read("configmap.yaml"); -const webRuntime = configMap.split("\n---\n", 1)[0]; -const expectedInternalBaseUrl = "http://zhinian-go-api:8080"; -const internalBaseUrl = webRuntime.match(/^\s*ZHINIAN_GO_INTERNAL_BASE_URL:\s*(\S+)\s*$/m)?.[1]; -assert(internalBaseUrl, "Web runtime ConfigMap must define ZHINIAN_GO_INTERNAL_BASE_URL"); -assert(internalBaseUrl === expectedInternalBaseUrl, "Web runtime ConfigMap must use the cluster-internal Go API URL"); -assert(!webRuntime.includes("ZHINIAN_DATA_BACKEND"), "Web runtime ConfigMap must not select a database backend"); -assert(!webRuntime.includes("DATABASE_URL"), "Web runtime ConfigMap must not carry DATABASE_URL"); -assert(!webRuntime.includes("rds-ca"), "Web runtime ConfigMap must not carry the RDS CA"); +assert(!configMap.includes("name: zhinian-runtime"), "Static Web must not have a runtime ConfigMap"); +assert((configMap.match(/^kind: ConfigMap$/gm) ?? []).length === 1, "Only the Go runtime ConfigMap should remain"); assert(configMap.includes("ZHINIAN_GO_EMBEDDED_WORKER: \"true\""), "Go runtime ConfigMap must embed the WorkerLoop"); assert(configMap.includes("GO_BACKEND_HOST: 0.0.0.0"), "Go runtime ConfigMap must listen on the Pod interface"); assert(!configMap.includes("DATABASE_SSL_MODE"), "ConfigMaps must not carry database TLS settings"); @@ -66,17 +75,79 @@ const goService = goApi.match( ); assert(goService, "Go API Service must declare an HTTP name, port, and targetPort"); const [, serviceName, servicePort, targetPort] = goService; -const parsedInternalBaseUrl = new URL(internalBaseUrl); -assert(parsedInternalBaseUrl.hostname === serviceName, "Web internal Go URL must use the Go API Service name"); -assert(parsedInternalBaseUrl.port === servicePort, "Web internal Go URL must use the Go API Service port"); +assert(serviceName === "zhinian-go-api", "Go API Service name must match the Ingress backend"); assert(targetPort === servicePort, "Go API Service targetPort must match its port"); +const nextConfig = readRepository("next.config.ts"); +assert(nextConfig.includes('output: "export"'), "Next must emit a static export"); +assert(nextConfig.includes("unoptimized: true"), "Static export must not depend on the Next image optimizer"); +assert(!nextConfig.includes("serverActions"), "Static frontend must not enable Server Actions"); + +const dockerfile = readRepository("Dockerfile"); +assert(dockerfile.includes("nginxinc/nginx-unprivileged:"), "Web runner must use unprivileged Nginx"); +assert(dockerfile.includes("/app/out"), "Web runner must copy the static export"); +assert(dockerfile.includes("ENTRYPOINT []"), "Web runner must skip image entrypoint mutations on a read-only root filesystem"); +assert(!dockerfile.includes("next start"), "Production Web must not start a Next server"); +assert(!dockerfile.includes("/app/.next"), "Production Web must not copy Next server artifacts"); + +const dockerIgnore = readRepository(".dockerignore"); +assert(dockerIgnore.includes("!deploy/nginx.conf"), "Docker build context must include the Nginx runtime config"); + +const nginx = readRepository("deploy/nginx.conf"); +assert(nginx.includes("listen 3000;"), "Static Nginx must preserve the Web service port"); +assert(nginx.includes("location = /healthz"), "Static Nginx must expose /healthz"); +assert(nginx.includes("api|uploads|generated-results"), "Static Nginx must reject Go-owned paths"); +assert(nginx.includes("immutable"), "Hashed Next assets must be cached immutably"); +assert(nginx.includes("no-cache, no-store, must-revalidate"), "HTML navigation must not be cached"); + +const packageJson = JSON.parse(readRepository("package.json")); +assert(!packageJson.scripts.start, "package scripts must not advertise a Next production server"); +assert(!packageJson.scripts["start:server"], "package scripts must not advertise a public Next production server"); +assert(!packageJson.scripts.worker, "package scripts must not advertise the removed Node worker"); +assert(!packageJson.scripts["worker:once"], "package scripts must not advertise the removed one-shot Node worker"); +assert(!packageJson.scripts.health, "package scripts must not probe the removed Next API server"); + +const deploymentDocs = readRepository("docs/DEPLOYMENT.md"); +assert( + deploymentDocs.includes( + "kubectl apply -f deploy/ack/namespace.yaml\n\n" + + "kubectl apply --dry-run=server -f deploy/ack/secrets.production.yaml\n" + + "kubectl apply --dry-run=server -f deploy/ack/configmap.yaml", + ), + "Deployment docs must create the Namespace before dry-running namespaced Secrets and resources", +); +assert( + deploymentDocs.includes( + "kubectl apply -f deploy/ack/secrets.production.yaml\n" + + "kubectl apply -f deploy/ack/configmap.yaml", + ), + "Deployment docs must publish Secrets before other namespaced resources", +); +assert( + deploymentDocs.includes("当前 ACK 清单不注入 `ZHINIAN_BOOTSTRAP_ADMIN_NAME`"), + "Deployment docs must not claim the optional bootstrap administrator name is injected", +); +assert( + deploymentDocs.includes("Pod 重建或滚动升级同样会永久丢失上传文件和生成结果"), + "Deployment docs must disclose emptyDir data loss across Go Pod replacement", +); + +const gitIgnore = readRepository(".gitignore"); +assert( + gitIgnore.split("\n").includes("/deploy/ack/secrets.production.yaml"), + "The populated production Secret manifest must be ignored with an exact repository-root rule", +); + console.log(`ACK manifest assertions passed (${files.length} files)`); function read(file) { return readFileSync(new URL(file, directory), "utf8").replace(/\r\n/g, "\n"); } +function readRepository(file) { + return readFileSync(new URL(file, repository), "utf8").replace(/\r\n/g, "\n"); +} + function assert(condition, message) { if (!condition) throw new Error(message); } diff --git a/scripts/print-app-info.mjs b/scripts/print-app-info.mjs index 1c52648..0eb596f 100644 --- a/scripts/print-app-info.mjs +++ b/scripts/print-app-info.mjs @@ -11,8 +11,8 @@ console.log(JSON.stringify({ appId: 'zhinian-web-studio', packageName: pkg.name, version: pkg.version, - runtime: 'Next.js Web', - webOnly: true, + runtime: 'Static Next.js export on Nginx + Go API', + webOnly: false, primaryRoutes: [ '/', '/create', diff --git a/tests/admin-accounts-organizations-contract.test.ts b/tests/admin-accounts-organizations-contract.test.ts index f478710..4bd9876 100644 --- a/tests/admin-accounts-organizations-contract.test.ts +++ b/tests/admin-accounts-organizations-contract.test.ts @@ -5,9 +5,6 @@ import { isValidPhone, normalizePhone } from "@/lib/server/account-store"; type Fixture = { version: 1; phoneCases: Array<{ input: string; normalized: string; valid: boolean }>; - authorizationCases: Array<{ actorRole: string; targetRole: string; allowed: boolean }>; - sessionVersionCases: Array<{ name: string; increment: boolean }>; - archiveTables: string[]; }; const fixtureURL = new URL("../contracts/admin/accounts-organizations-v1.json", import.meta.url); @@ -21,22 +18,4 @@ describe("administration accounts and organizations v1 contract", () => { } }); - it("freezes route authorization and mutation policy consumed by Go", async () => { - const fixture = JSON.parse(await readFile(fixtureURL, "utf8")) as Fixture; - const accountsRoute = await readFile(new URL("../app/api/admin/accounts/route.ts", import.meta.url), "utf8"); - const passwordRoute = await readFile(new URL("../app/api/admin/accounts/password/route.ts", import.meta.url), "utf8"); - const organizationRoute = await readFile(new URL("../app/api/admin/organizations/route.ts", import.meta.url), "utf8"); - const store = await readFile(new URL("../lib/server/account-store.ts", import.meta.url), "utf8"); - - expect(accountsRoute).toContain('target.role !== "user"'); - expect(accountsRoute).toContain("actor.organizationId !== target.organizationId"); - expect(passwordRoute).toContain('target.role !== "user"'); - expect(organizationRoute).toContain("requireSuperAdmin(session.user)"); - expect(store).toContain("sessionVersion: nextPassword || patch.role || patch.organizationId !== undefined || patch.status ? current.sessionVersion + 1 : current.sessionVersion"); - expect(fixture.authorizationCases.filter((item) => item.allowed)).toHaveLength(2); - expect(fixture.sessionVersionCases.filter((item) => item.increment).map((item) => item.name)).toEqual([ - "role mutation", "organization mutation", "status mutation", "password mutation" - ]); - for (const table of fixture.archiveTables) expect(store).toContain(`"${table}"`); - }); }); diff --git a/tests/auth-current-session-contract.test.ts b/tests/auth-current-session-contract.test.ts deleted file mode 100644 index 62d152c..0000000 --- a/tests/auth-current-session-contract.test.ts +++ /dev/null @@ -1,242 +0,0 @@ -import { readFile } from "node:fs/promises"; - -import { afterEach, describe, expect, it, vi } from "vitest"; -import { createRequire } from "node:module"; - -import { getAuthRuntimeConfig } from "@/lib/auth/config"; -import type { AuthSession } from "@/lib/auth/session"; - -const { getOptionalAuthSession } = vi.hoisted(() => ({ - getOptionalAuthSession: vi.fn<() => Promise>() -})); - -vi.mock("@/lib/server/auth/current-user", () => ({ getOptionalAuthSession })); - -import * as currentSessionRoute from "@/app/api/auth/me/route"; - -type ExpectedConfig = { - required: boolean; - configured: boolean; - sessionSecret: string | null; -}; - -type CurrentSessionFixture = { - version: 1; - path: string; - methods: { - GET: MethodContract; - HEAD: MethodContract & { executesGet: true }; - OPTIONS: MethodContract; - unsupported: MethodContract & { methods: string[] }; - }; - authConfigurationCases: Array<{ - name: string; - environment: Record; - expected: ExpectedConfig; - }>; - responses: { - anonymous: CurrentSessionResponse; - authenticatedUser: CurrentSessionResponse; - unboundSuperAdministrator: CurrentSessionResponse; - }; - forbiddenSessionKeys: string[]; - infrastructureError: { - directGet: "rejects"; - transportStatus: number; - mustNotReturnAnonymous: boolean; - }; -}; - -type MethodContract = { - status: number; - body: "json" | "empty"; - contentType: string | null; - allow: string | null; -}; - -type CurrentSessionResponse = { - authenticated: boolean; - authRequired: boolean; - authConfigured: boolean; - authMode: "user" | "admin" | null; - user: Record | null; -}; - -const fixtureUrl = new URL("../contracts/auth/current-session-v1.json", import.meta.url); -const require = createRequire(import.meta.url); -const authEnvironmentKeys = [ - "NODE_ENV", - "ZHINIAN_AUTH_REQUIRED", - "ZHINIAN_AUTH_DISABLED", - "ZHINIAN_AUTH_SESSION_SECRET", - "AUTH_SESSION_SECRET", - "NEXTAUTH_SECRET" -] as const; -const originalEnvironment = new Map(authEnvironmentKeys.map((key) => [key, process.env[key]])); - -afterEach(() => { - getOptionalAuthSession.mockReset(); - restoreAuthEnvironment(); -}); - -async function loadFixture(): Promise { - return JSON.parse(await readFile(fixtureUrl, "utf8")) as CurrentSessionFixture; -} - -function restoreAuthEnvironment() { - for (const key of authEnvironmentKeys) { - const original = originalEnvironment.get(key); - if (original === undefined) Reflect.deleteProperty(process.env, key); - else Reflect.set(process.env, key, original); - } -} - -function configureAuthEnvironment(environment: Record) { - for (const key of authEnvironmentKeys) Reflect.deleteProperty(process.env, key); - for (const [key, value] of Object.entries(environment)) Reflect.set(process.env, key, value); -} - -function sessionFor(response: CurrentSessionResponse): AuthSession { - if (!response.user || !response.authMode) throw new Error("authenticated fixture response required"); - return { - version: 1, - authMode: response.authMode, - issuedAt: 100, - expiresAt: 200, - sessionVersion: 7, - accessToken: "must-not-leak", - tokenType: "bearer", - user: response.user as AuthSession["user"] - }; -} - -async function expectJsonResponse(expected: CurrentSessionResponse) { - const fixture = await loadFixture(); - const response = await currentSessionRoute.GET(); - - expect(response.status).toBe(fixture.methods.GET.status); - expect(response.headers.get("content-type")).toBe(fixture.methods.GET.contentType); - expect(response.headers.get("allow")).toBe(fixture.methods.GET.allow); - expect(await response.json()).toEqual(expected); -} - -describe("current session HTTP v1 cross-language contract", () => { - it("freezes the path and Next.js automatic method semantics", async () => { - const fixture = await loadFixture(); - - expect(fixture.version).toBe(1); - expect(fixture.path).toBe("/api/auth/me"); - expect(Object.keys(currentSessionRoute).sort()).toEqual(["GET", "runtime"]); - expect(currentSessionRoute.runtime).toBe("nodejs"); - expect(fixture.methods).toEqual({ - GET: { status: 200, body: "json", contentType: "application/json", allow: null }, - HEAD: { - status: 200, - body: "empty", - contentType: "application/json", - allow: null, - executesGet: true - }, - OPTIONS: { status: 204, body: "empty", contentType: null, allow: "GET, HEAD, OPTIONS" }, - unsupported: { - methods: ["POST", "PUT", "PATCH", "DELETE"], - status: 405, - body: "empty", - contentType: null, - allow: null - } - }); - - const { autoImplementMethods } = require( - "next/dist/server/route-modules/app-route/helpers/auto-implement-methods.js" - ) as { - autoImplementMethods: (handlers: Record) => Record Promise>; - }; - const handlers = autoImplementMethods({ GET: currentSessionRoute.GET }); - getOptionalAuthSession.mockResolvedValue(null); - configureAuthEnvironment({ NODE_ENV: "development" }); - - for (const method of ["HEAD", "OPTIONS", ...fixture.methods.unsupported.methods]) { - const response = await handlers[method](); - const expected = method === "HEAD" - ? fixture.methods.HEAD - : method === "OPTIONS" - ? fixture.methods.OPTIONS - : fixture.methods.unsupported; - expect(response.status, method).toBe(expected.status); - expect(response.headers.get("content-type"), method).toBe(expected.contentType); - expect(response.headers.get("allow"), method).toBe(expected.allow); - if (method !== "HEAD") expect(await response.text(), method).toBe(""); - } - }); - - it("consumes every auth configuration case through the real runtime resolver", async () => { - const fixture = await loadFixture(); - - expect(fixture.authConfigurationCases.length).toBeGreaterThanOrEqual(4); - for (const testCase of fixture.authConfigurationCases) { - configureAuthEnvironment(testCase.environment); - const config = getAuthRuntimeConfig(); - expect( - { - required: config.required, - configured: config.configured, - sessionSecret: config.sessionSecret ?? null - }, - testCase.name - ).toEqual(testCase.expected); - } - }); - - it("returns the exact five-key anonymous response", async () => { - const fixture = await loadFixture(); - configureAuthEnvironment({ NODE_ENV: "development" }); - getOptionalAuthSession.mockResolvedValue(null); - - expect(Object.keys(fixture.responses.anonymous).sort()).toEqual( - ["authenticated", "authRequired", "authConfigured", "authMode", "user"].sort() - ); - await expectJsonResponse(fixture.responses.anonymous); - }); - - it.each(["authenticatedUser", "unboundSuperAdministrator"] as const)( - "returns the exact public projection for %s and omits optional fields", - async (caseName) => { - const fixture = await loadFixture(); - const expected = fixture.responses[caseName]; - configureAuthEnvironment({ - NODE_ENV: "production", - ZHINIAN_AUTH_SESSION_SECRET: "route-test-secret" - }); - getOptionalAuthSession.mockResolvedValue(sessionFor(expected)); - - await expectJsonResponse(expected); - const serialized = JSON.stringify(expected); - for (const key of fixture.forbiddenSessionKeys) { - expect(serialized, `${caseName} leaked ${key}`).not.toContain(`"${key}"`); - } - if (caseName === "unboundSuperAdministrator") { - expect(expected.user).not.toHaveProperty("tenantId"); - expect(expected.user).not.toHaveProperty("organizationId"); - expect(expected.user).not.toHaveProperty("organizationName"); - } - } - ); - - it("propagates infrastructure errors for transport mapping instead of returning anonymous", async () => { - const fixture = await loadFixture(); - const failure = new Error("authorization snapshot unavailable"); - configureAuthEnvironment({ - NODE_ENV: "production", - ZHINIAN_AUTH_SESSION_SECRET: "route-test-secret" - }); - getOptionalAuthSession.mockRejectedValue(failure); - - expect(fixture.infrastructureError).toEqual({ - directGet: "rejects", - transportStatus: 500, - mustNotReturnAnonymous: true - }); - await expect(currentSessionRoute.GET()).rejects.toBe(failure); - }); -}); diff --git a/tests/auth-current-user-go-bridge.test.ts b/tests/auth-current-user-go-bridge.test.ts deleted file mode 100644 index e0ceca7..0000000 --- a/tests/auth-current-user-go-bridge.test.ts +++ /dev/null @@ -1,226 +0,0 @@ -import { afterEach, describe, expect, it, vi } from "vitest"; - -import { SESSION_COOKIE_NAME } from "@/lib/auth/config"; -import { chunkCookieValue, chunkedCookieName, createSignedJsonValue, type AuthSession } from "@/lib/auth/session"; - -const { cookieValues } = vi.hoisted(() => ({ - cookieValues: new Map(), -})); - -vi.mock("next/headers", () => ({ - cookies: vi.fn(async () => ({ - get: (name: string) => { - const value = cookieValues.get(name); - return value === undefined ? undefined : { name, value }; - }, - })), -})); - -import { getShellAuthState } from "@/lib/server/auth/current-user"; - -const authEnvironmentKeys = [ - "NODE_ENV", - "ZHINIAN_AUTH_REQUIRED", - "ZHINIAN_AUTH_SESSION_SECRET", - "ZHINIAN_GO_INTERNAL_BASE_URL", -] as const; -const originalEnvironment = new Map(authEnvironmentKeys.map((key) => [key, process.env[key]])); - -function configureGoBridge() { - Reflect.set(process.env, "NODE_ENV", "production"); - Reflect.set(process.env, "ZHINIAN_AUTH_REQUIRED", "true"); - Reflect.set(process.env, "ZHINIAN_AUTH_SESSION_SECRET", "bridge-test-secret"); - Reflect.set(process.env, "ZHINIAN_GO_INTERNAL_BASE_URL", "http://go-api.internal/"); -} - -async function seedPlatformSessionCookie() { - const session: AuthSession = { - version: 1, - authMode: "user", - issuedAt: Math.floor(Date.now() / 1000) - 10, - expiresAt: Math.floor(Date.now() / 1000) + 3600, - sessionVersion: 7, - user: { - id: "account-1", - subject: "account-1", - displayName: "旧名称", - clientId: "platform", - organizationId: "org-old", - organizationName: "旧组织", - role: "user", - authorities: ["ROLE_USER"], - scope: [], - }, - }; - const signed = await createSignedJsonValue(session, "bridge-test-secret"); - const chunks = chunkCookieValue(signed, 80); - chunks.forEach((value, index) => cookieValues.set(chunkedCookieName(SESSION_COOKIE_NAME, index), value)); - return chunks; -} - -afterEach(() => { - vi.unstubAllGlobals(); - cookieValues.clear(); - for (const key of authEnvironmentKeys) { - const original = originalEnvironment.get(key); - if (original === undefined) Reflect.deleteProperty(process.env, key); - else Reflect.set(process.env, key, original); - } -}); - -describe("authenticated shell state through the Go identity boundary", () => { - it("refreshes the signed platform session and forwards only its cookie chunks", async () => { - configureGoBridge(); - const chunks = await seedPlatformSessionCookie(); - cookieValues.set("theme", "dark"); - cookieValues.set("analytics_id", "do-not-forward"); - - const fetchMock = vi.fn().mockResolvedValue(new Response(JSON.stringify({ - authenticated: true, - authRequired: true, - authConfigured: true, - authMode: "admin", - user: { - id: "account-1", - subject: "account-1", - username: "13800138001", - phone: "13800138001", - displayName: "刷新名称", - clientId: "platform", - organizationId: "org-1", - organizationName: "刷新组织", - role: "organization_admin", - status: "active", - authorities: ["ROLE_ORGANIZATION_ADMIN", "ORGANIZATION_ADMIN"], - scope: [], - }, - }), { status: 200, headers: { "content-type": "application/json" } })); - vi.stubGlobal("fetch", fetchMock); - - await expect(getShellAuthState()).resolves.toEqual({ - user: expect.objectContaining({ - id: "account-1", - displayName: "刷新名称", - organizationId: "org-1", - role: "organization_admin", - }), - authRequired: true, - authConfigured: true, - isAdmin: true, - isSuperAdmin: false, - }); - expect(fetchMock).toHaveBeenCalledOnce(); - expect(fetchMock).toHaveBeenCalledWith("http://go-api.internal/api/auth/me", { - cache: "no-store", - headers: { - cookie: chunks - .map((value, index) => `${chunkedCookieName(SESSION_COOKIE_NAME, index)}=${value}`) - .join("; "), - }, - }); - }); - - it("treats a Go-rejected session as anonymous", async () => { - configureGoBridge(); - await seedPlatformSessionCookie(); - vi.stubGlobal("fetch", vi.fn().mockResolvedValue(new Response(JSON.stringify({ - authenticated: false, - authRequired: true, - authConfigured: true, - authMode: null, - user: null, - }), { status: 200, headers: { "content-type": "application/json" } }))); - - await expect(getShellAuthState()).resolves.toEqual({ - user: null, - authRequired: true, - authConfigured: true, - isAdmin: false, - isSuperAdmin: false, - }); - }); - - it.each([ - ["an upstream error", new Response(null, { status: 503 }), "status 503"], - [ - "an invalid authenticated response", - new Response(JSON.stringify({ - authenticated: true, - authRequired: true, - authConfigured: true, - authMode: "admin", - user: null, - }), { status: 200, headers: { "content-type": "application/json" } }), - "invalid authenticated response", - ], - ])("fails closed for %s", async (_caseName, response, expectedMessage) => { - configureGoBridge(); - await seedPlatformSessionCookie(); - vi.stubGlobal("fetch", vi.fn().mockResolvedValue(response)); - - await expect(getShellAuthState()).rejects.toThrow(expectedMessage); - }); - - const validOrganizationAdmin = { - id: "account-1", - subject: "account-1", - username: "13800138001", - phone: "13800138001", - displayName: "刷新名称", - clientId: "platform", - organizationId: "org-1", - organizationName: "刷新组织", - role: "organization_admin", - status: "active", - authorities: ["ROLE_ORGANIZATION_ADMIN", "ORGANIZATION_ADMIN"], - scope: [], - }; - const { role: _role, status: _status, ...userWithoutRoleOrStatus } = validOrganizationAdmin; - const { organizationId: _organizationId, organizationName: _organizationName, ...userWithoutOrganization } = - validOrganizationAdmin; - - it.each([ - ["missing platform role and status", { - authMode: "admin", - authConfigured: true, - user: { ...userWithoutRoleOrStatus, authorities: ["SUPER_ADMIN"] }, - }], - ["a disabled account", { - authMode: "admin", - authConfigured: true, - user: { ...validOrganizationAdmin, status: "disabled" }, - }], - ["a mismatched subject", { - authMode: "admin", - authConfigured: true, - user: { ...validOrganizationAdmin, subject: "other-account" }, - }], - ["a role/authMode mismatch", { - authMode: "user", - authConfigured: true, - user: validOrganizationAdmin, - }], - ["an unconfigured authenticated response", { - authMode: "admin", - authConfigured: false, - user: validOrganizationAdmin, - }], - ["an organization-bound role without an organization", { - authMode: "admin", - authConfigured: true, - user: userWithoutOrganization, - }], - ])("rejects %s", async (_caseName, invalid) => { - configureGoBridge(); - await seedPlatformSessionCookie(); - vi.stubGlobal("fetch", vi.fn().mockResolvedValue(new Response(JSON.stringify({ - authenticated: true, - authRequired: true, - authMode: invalid.authMode, - authConfigured: invalid.authConfigured, - user: invalid.user, - }), { status: 200, headers: { "content-type": "application/json" } }))); - - await expect(getShellAuthState()).rejects.toThrow("invalid authenticated response"); - }); -}); diff --git a/tests/auth-login-panel.test.ts b/tests/auth-login-panel.test.ts index 31e3d51..a068007 100644 --- a/tests/auth-login-panel.test.ts +++ b/tests/auth-login-panel.test.ts @@ -25,6 +25,8 @@ describe("AuthLoginPanel", () => { expect(panelSource).not.toContain('disabled={!configured || submitting || !phone.trim() || !password}'); expect(panelSource).not.toContain("authMode"); expect(panelSource).not.toContain("alternateHref"); + expect(panelSource).toContain("window.location.assign(safeBrowserNext(result.redirectTo, next))"); + expect(panelSource).not.toContain("window.location.assign(result.redirectTo"); expect(loginPageSource).not.toContain("/auth/admin-login"); expect(adminPageSource).toContain("/auth/login"); }); diff --git a/tests/auth-logout-contract.test.ts b/tests/auth-logout-contract.test.ts deleted file mode 100644 index cb223de..0000000 --- a/tests/auth-logout-contract.test.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { readFile } from "node:fs/promises"; - -import { afterEach, describe, expect, it, vi } from "vitest"; - -import * as logoutRoute from "@/app/api/auth/logout/route"; - -type LogoutFixture = { - version: 1; - path: string; - methods: string[]; - status: number; - location: string; - requiresAuthentication: boolean; - cookieFixture: string; - duplicateBaseCookieWrite: boolean; -}; - -type SessionCookieFixture = { - cookie: { - chunkNames: string[]; - attributes: { httpOnly: boolean; sameSite: string; path: string }; - clear: { value: string; maxAgeSeconds: number }; - }; -}; - -const fixtureUrl = new URL("../contracts/auth/logout-v1.json", import.meta.url); - -async function loadFixture(): Promise { - return JSON.parse(await readFile(fixtureUrl, "utf8")) as LogoutFixture; -} - -async function loadCookieFixture(relativePath: string): Promise { - return JSON.parse(await readFile(new URL(`../contracts/auth/${relativePath}`, import.meta.url), "utf8")) as SessionCookieFixture; -} - -function setCookieLines(response: Response): string[] { - const headers = response.headers as Headers & { getSetCookie?: () => string[] }; - return headers.getSetCookie?.() ?? [response.headers.get("set-cookie") ?? ""]; -} - -afterEach(() => vi.unstubAllEnvs()); - -describe("logout HTTP v1 cross-language contract", () => { - it("allows anonymous GET and POST and returns the same 307 redirect", async () => { - const fixture = await loadFixture(); - expect({ version: fixture.version, path: fixture.path, methods: fixture.methods }).toEqual({ - version: 1, - path: "/api/auth/logout", - methods: ["GET", "POST"] - }); - expect(Object.keys(logoutRoute).sort()).toEqual(["GET", "POST", "runtime"]); - expect(fixture.requiresAuthentication).toBe(false); - - for (const method of fixture.methods) { - const response = await logoutRoute[method as "GET" | "POST"]( - new Request("https://app.example.test/api/auth/logout", { method }) - ); - expect(response.status, method).toBe(fixture.status); - expect(response.headers.get("location"), method).toBe(fixture.location); - } - }); - - it("clears all 20 legacy chunk names and preserves the externally visible duplicate base write", async () => { - const fixture = await loadFixture(); - const cookieFixture = await loadCookieFixture(fixture.cookieFixture); - vi.stubEnv("ZHINIAN_AUTH_COOKIE_SECURE", "true"); - const response = await logoutRoute.POST(new Request("http://127.0.0.1/api/auth/logout", { method: "POST" })); - const lines = setCookieLines(response); - const names = lines.map((line) => line.slice(0, line.indexOf("="))); - - expect(lines).toHaveLength(cookieFixture.cookie.chunkNames.length + (fixture.duplicateBaseCookieWrite ? 1 : 0)); - expect(names).toEqual([ - ...cookieFixture.cookie.chunkNames, - ...(fixture.duplicateBaseCookieWrite ? [cookieFixture.cookie.chunkNames[0]] : []) - ]); - for (const line of lines) { - expect(line).toContain("HttpOnly"); - expect(line).toContain("Path=/"); - expect(line).toContain("SameSite=lax"); - expect(line).toContain("Secure"); - expect(line).toContain(`Max-Age=${cookieFixture.cookie.clear.maxAgeSeconds}`); - } - }); -}); diff --git a/tests/auth-password-login-contract.test.ts b/tests/auth-password-login-contract.test.ts deleted file mode 100644 index 200068d..0000000 --- a/tests/auth-password-login-contract.test.ts +++ /dev/null @@ -1,260 +0,0 @@ -import { mkdtemp, readFile, rm } from "node:fs/promises"; -import { tmpdir } from "node:os"; -import { join } from "node:path"; - -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; - -import { safeNextPath } from "@/lib/auth/config"; -import { parseSessionCookieValue } from "@/lib/auth/session"; -import { - createPlatformOrganization, - createPlatformUser, - updatePlatformOrganization, - updatePlatformUser -} from "@/lib/server/account-store"; -import { resetLocalAuthRateLimitForTests } from "@/lib/server/auth/local"; -import type { PlatformOrganization, PlatformUserRecord } from "@/lib/types"; -import * as passwordRoute from "@/app/api/auth/password/route"; - -type PasswordLoginFixture = { - version: 1; - path: string; - method: "POST"; - localSessionTtlSeconds: number; - inputCases: Array<{ - name: string; - body: Record; - expectedRedirect: string; - }>; - safeNextCases: Array<{ input: string | null; expected: string }>; - success: { - topLevelKeys: string[]; - publicUserKeys: string[]; - forbiddenSerializedKeys: string[]; - }; - errors: Record<"invalidInput" | "invalidCredentials" | "disabledAccount" | "disabledOrganization" | "lockedAccount" | "rateLimited" | "unconfigured", { - status: number; - body: { error: string }; - }>; - rateLimit: { attemptsPerIp: number; windowSeconds: number }; - cookieFixture: string; -}; - -type SessionCookieFixture = { - cookie: { - chunkNames: string[]; - attributes: { httpOnly: boolean; sameSite: string; path: string }; - clear: { maxAgeSeconds: number }; - }; -}; - -const fixtureUrl = new URL("../contracts/auth/password-login-v1.json", import.meta.url); -const authEnvironmentKeys = [ - "NODE_ENV", - "ZHINIAN_DATA_DIR", - "ZHINIAN_DATA_BACKEND", - "ZHINIAN_AUTH_REQUIRED", - "ZHINIAN_AUTH_DISABLED", - "ZHINIAN_AUTH_SESSION_SECRET", - "AUTH_SESSION_SECRET", - "NEXTAUTH_SECRET", - "ZHINIAN_AUTH_COOKIE_SECURE", - "NEXT_PUBLIC_APP_URL", - "ZHINIAN_PUBLIC_BASE_URL" -] as const; -const originalEnvironment = new Map(authEnvironmentKeys.map((key) => [key, process.env[key]])); -const sessionSecret = "password-contract-session-secret-with-enough-entropy"; -let runtimeDir = ""; -let organization: PlatformOrganization; -let user: PlatformUserRecord; - -async function loadFixture(): Promise { - return JSON.parse(await readFile(fixtureUrl, "utf8")) as PasswordLoginFixture; -} - -async function loadCookieFixture(relativePath: string): Promise { - return JSON.parse(await readFile(new URL(`../contracts/auth/${relativePath}`, import.meta.url), "utf8")) as SessionCookieFixture; -} - -function login(body: unknown, ip = "192.0.2.10", url = "http://127.0.0.1/api/auth/password") { - return passwordRoute.POST(new Request(url, { - method: "POST", - headers: { "content-type": "application/json", "x-forwarded-for": ip }, - body: typeof body === "string" ? body : JSON.stringify(body) - })); -} - -function setCookieLines(response: Response): string[] { - const headers = response.headers as Headers & { getSetCookie?: () => string[] }; - return headers.getSetCookie?.() ?? [response.headers.get("set-cookie") ?? ""]; -} - -function unsignedCookiePayload(cookieValue: string): Record { - const [payload] = cookieValue.split("."); - return JSON.parse(Buffer.from(payload.replace(/-/g, "+").replace(/_/g, "/"), "base64url").toString("utf8")) as Record; -} - -beforeEach(async () => { - runtimeDir = await mkdtemp(join(tmpdir(), "zhinian-password-contract-")); - vi.stubEnv("NODE_ENV", "test"); - vi.stubEnv("ZHINIAN_DATA_DIR", runtimeDir); - vi.stubEnv("ZHINIAN_DATA_BACKEND", "local"); - vi.stubEnv("ZHINIAN_AUTH_REQUIRED", "1"); - vi.stubEnv("ZHINIAN_AUTH_DISABLED", ""); - vi.stubEnv("ZHINIAN_AUTH_SESSION_SECRET", sessionSecret); - vi.stubEnv("ZHINIAN_AUTH_COOKIE_SECURE", "false"); - resetLocalAuthRateLimitForTests(); - organization = await createPlatformOrganization("契约测试组织"); - user = await createPlatformUser({ - phone: "13800138000", - displayName: "契约测试用户", - password: "TestPass123", - role: "user", - organizationId: organization.id - }); -}); - -afterEach(async () => { - resetLocalAuthRateLimitForTests(); - vi.unstubAllEnvs(); - for (const key of authEnvironmentKeys) { - const original = originalEnvironment.get(key); - if (original === undefined) Reflect.deleteProperty(process.env, key); - else Reflect.set(process.env, key, original); - } - await rm(runtimeDir, { recursive: true, force: true }); -}); - -describe("password login HTTP v1 cross-language contract", () => { - it("freezes route identity, input aliases, trimming, ignored authMode, and safe redirects", async () => { - const fixture = await loadFixture(); - expect({ version: fixture.version, path: fixture.path, method: fixture.method }).toEqual({ - version: 1, - path: "/api/auth/password", - method: "POST" - }); - expect(Object.keys(passwordRoute).sort()).toEqual(["POST", "dynamic", "runtime"]); - expect(passwordRoute.runtime).toBe("nodejs"); - expect(passwordRoute.dynamic).toBe("force-dynamic"); - - for (const testCase of fixture.safeNextCases) { - expect(safeNextPath(testCase.input), testCase.input ?? "null").toBe(testCase.expected); - } - - for (const [index, testCase] of fixture.inputCases.entries()) { - const response = await login(testCase.body, `192.0.2.${20 + index}`); - expect(response.status, testCase.name).toBe(200); - const body = await response.json(); - expect(body.redirectTo, testCase.name).toBe(testCase.expectedRedirect); - expect(body.authMode, testCase.name).toBe("user"); - } - }); - - it("returns the exact public body and a parseable one-day session without sensitive fields", async () => { - const fixture = await loadFixture(); - const response = await login({ phone: user.phone, password: "TestPass123", next: "/assets?tab=mine#recent" }); - const body = await response.json(); - - expect(response.status).toBe(200); - expect(body).toEqual({ - ok: true, - redirectTo: "/assets?tab=mine#recent", - user: { - id: user.id, - subject: user.id, - username: user.phone, - phone: user.phone, - displayName: user.displayName, - clientId: "platform", - organizationId: organization.id, - organizationName: organization.name, - role: "user", - status: "active", - authorities: ["ROLE_USER"], - scope: [] - }, - authMode: "user" - }); - expect(Object.keys(body).sort()).toEqual([...fixture.success.topLevelKeys].sort()); - expect(Object.keys(body.user).sort()).toEqual([...fixture.success.publicUserKeys].sort()); - for (const key of fixture.success.forbiddenSerializedKeys) { - expect(JSON.stringify(body)).not.toContain(`"${key}"`); - } - - const cookieValue = response.cookies.get("zhinian_session")?.value; - const session = await parseSessionCookieValue(cookieValue, sessionSecret, 0); - expect(session).not.toBeNull(); - expect(session?.expiresAt! - session?.issuedAt!).toBe(fixture.localSessionTtlSeconds); - expect(session).toMatchObject({ - version: 1, - authMode: "user", - sessionVersion: user.sessionVersion, - user: body.user - }); - const rawSession = unsignedCookiePayload(cookieValue!); - expect(rawSession).not.toHaveProperty("accessToken"); - expect(rawSession).not.toHaveProperty("tokenType"); - }); - - it("writes the shared Cookie name set and legacy attributes, including stale-chunk clears", async () => { - const fixture = await loadFixture(); - const cookieFixture = await loadCookieFixture(fixture.cookieFixture); - const response = await login({ phone: user.phone, password: "TestPass123" }); - const lines = setCookieLines(response); - - expect(lines).toHaveLength(cookieFixture.cookie.chunkNames.length); - expect(lines.map((line) => line.slice(0, line.indexOf("=")))).toEqual(cookieFixture.cookie.chunkNames); - expect(lines[0]).toContain("HttpOnly"); - expect(lines[0]).toContain("Path=/"); - expect(lines[0]).toContain("SameSite=lax"); - expect(lines[0]).not.toContain("Secure"); - expect(lines[0]).toContain("Expires="); - for (const line of lines.slice(1)) { - expect(line).toContain("Max-Age=0"); - expect(line).not.toContain("Expires="); - } - }); - - it("freezes 400, 401, 403, 423, 429, and 503 public error semantics", async () => { - const { errors, rateLimit } = await loadFixture(); - - const invalidInput = await login("not-json", "192.0.2.30"); - expect({ status: invalidInput.status, body: await invalidInput.json() }).toEqual(errors.invalidInput); - - const invalidCredentials = await login({ username: " 19900000000 ", password: "wrong" }, "192.0.2.31"); - expect({ status: invalidCredentials.status, body: await invalidCredentials.json() }).toEqual(errors.invalidCredentials); - - await updatePlatformUser(user.id, { status: "disabled" }); - const disabled = await login({ phone: user.phone, password: "TestPass123" }, "192.0.2.32"); - expect({ status: disabled.status, body: await disabled.json() }).toEqual(errors.disabledAccount); - await updatePlatformUser(user.id, { status: "active" }); - - let locked: Response | undefined; - for (let attempt = 0; attempt < 5; attempt += 1) { - locked = await login({ phone: user.phone, password: "wrong" }, `192.0.2.${40 + attempt}`); - } - expect({ status: locked?.status, body: await locked?.json() }).toEqual(errors.lockedAccount); - - for (let attempt = 0; attempt < rateLimit.attemptsPerIp; attempt += 1) { - const response = await login({ phone: "19900000000", password: "wrong" }, "192.0.2.50"); - expect(response.status, `allowed IP attempt ${attempt + 1}`).toBe(401); - } - const rateLimited = await login({ phone: "19900000000", password: "wrong" }, "192.0.2.50"); - expect({ status: rateLimited.status, body: await rateLimited.json() }).toEqual(errors.rateLimited); - - vi.stubEnv("ZHINIAN_AUTH_SESSION_SECRET", ""); - vi.stubEnv("AUTH_SESSION_SECRET", ""); - vi.stubEnv("NEXTAUTH_SECRET", ""); - const unconfigured = await login({ phone: user.phone, password: "TestPass123" }, "192.0.2.60"); - expect({ status: unconfigured.status, body: await unconfigured.json() }).toEqual(errors.unconfigured); - - expect(rateLimit.windowSeconds).toBe(15 * 60); - }); - - it("rejects a user whose organization is disabled", async () => { - const fixture = await loadFixture(); - await updatePlatformOrganization(organization.id, { status: "disabled" }); - const response = await login({ phone: user.phone, password: "TestPass123" }, "192.0.2.70"); - expect({ status: response.status, body: await response.json() }).toEqual(fixture.errors.disabledOrganization); - }); -}); diff --git a/tests/auth-password-route.test.ts b/tests/auth-password-route.test.ts deleted file mode 100644 index 04e5c1c..0000000 --- a/tests/auth-password-route.test.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { mkdtemp, rm } from "node:fs/promises"; -import { tmpdir } from "node:os"; -import { join } from "node:path"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { parseSessionCookieValue } from "@/lib/auth/session"; -import { - createPlatformOrganization, - createPlatformUser, - updatePlatformUser -} from "@/lib/server/account-store"; -import { resetLocalAuthRateLimitForTests } from "@/lib/server/auth/local"; -import type { PlatformUserRecord } from "@/lib/types"; -import { POST } from "@/app/api/auth/password/route"; - -const SESSION_SECRET = "test-platform-session-secret-with-enough-entropy"; -let runtimeDir = ""; -let ordinaryUser: PlatformUserRecord; - -describe("platform password auth route", () => { - beforeEach(async () => { - runtimeDir = await mkdtemp(join(tmpdir(), "zhinian-auth-")); - vi.stubEnv("ZHINIAN_DATA_DIR", runtimeDir); - vi.stubEnv("ZHINIAN_AUTH_REQUIRED", "1"); - vi.stubEnv("ZHINIAN_AUTH_SESSION_SECRET", SESSION_SECRET); - vi.stubEnv("ZHINIAN_AUTH_DISABLED", ""); - vi.stubEnv("ZHINIAN_DATA_BACKEND", "local"); - resetLocalAuthRateLimitForTests(); - - const organization = await createPlatformOrganization("测试组织"); - ordinaryUser = await createPlatformUser({ - phone: "13800138000", - displayName: "测试用户", - password: "TestPass123", - role: "user", - organizationId: organization.id - }); - }); - - afterEach(async () => { - resetLocalAuthRateLimitForTests(); - vi.unstubAllEnvs(); - await rm(runtimeDir, { force: true, recursive: true }); - }); - - it("logs in every role with the platform phone/password session", async () => { - const response = await POST(new Request("http://127.0.0.1/api/auth/password", { - method: "POST", - headers: { "x-forwarded-for": "192.0.2.10" }, - body: JSON.stringify({ - phone: "138 0013-8000", - password: "TestPass123", - next: "/assets" - }) - })); - - expect(response.status).toBe(200); - await expect(response.json()).resolves.toMatchObject({ - ok: true, - redirectTo: "/assets", - authMode: "user", - user: { id: ordinaryUser.id, phone: "13800138000", role: "user", clientId: "platform" } - }); - expect(await parseSessionCookieValue( - response.cookies.get("zhinian_session")?.value, - SESSION_SECRET - )).toMatchObject({ - authMode: "user", - sessionVersion: 1, - user: { id: ordinaryUser.id, role: "user", clientId: "platform" } - }); - }); - - it("logs in a super administrator through the same endpoint", async () => { - const admin = await createPlatformUser({ - phone: "13900139000", - displayName: "平台超级管理员", - password: "AdminPass123", - role: "super_admin" - }); - - const response = await POST(new Request("http://127.0.0.1/api/auth/password", { - method: "POST", - body: JSON.stringify({ phone: admin.phone, password: "AdminPass123", authMode: "admin" }) - })); - - expect(response.status).toBe(200); - await expect(response.json()).resolves.toMatchObject({ - authMode: "admin", - user: { id: admin.id, role: "super_admin" } - }); - }); - - it("locks an account after five failed passwords", async () => { - let lastResponse: Response | undefined; - for (let attempt = 1; attempt <= 5; attempt += 1) { - lastResponse = await POST(new Request("http://127.0.0.1/api/auth/password", { - method: "POST", - headers: { "x-forwarded-for": "192.0.2.11" }, - body: JSON.stringify({ phone: ordinaryUser.phone, password: "wrong-pass" }) - })); - expect(lastResponse.status).toBe(attempt === 5 ? 423 : 401); - } - await expect(lastResponse?.json()).resolves.toMatchObject({ error: "登录失败次数过多,请 15 分钟后再试。" }); - - const lockedResponse = await POST(new Request("http://127.0.0.1/api/auth/password", { - method: "POST", - body: JSON.stringify({ phone: ordinaryUser.phone, password: "TestPass123" }) - })); - expect(lockedResponse.status).toBe(423); - }); - - it("rejects disabled accounts and duplicate phone identities", async () => { - await expect(createPlatformUser({ - phone: ordinaryUser.phone, - displayName: "重复账号", - password: "AnotherPass123", - role: "user", - organizationId: ordinaryUser.organizationId - })).rejects.toThrow("该手机号已创建账号。"); - - await updatePlatformUser(ordinaryUser.id, { status: "disabled" }); - const response = await POST(new Request("http://127.0.0.1/api/auth/password", { - method: "POST", - body: JSON.stringify({ phone: ordinaryUser.phone, password: "TestPass123" }) - })); - expect(response.status).toBe(403); - await expect(response.json()).resolves.toEqual({ error: "账号已停用,请联系管理员。" }); - }); -}); diff --git a/tests/http-route-surface-contract.test.ts b/tests/http-route-surface-contract.test.ts deleted file mode 100644 index be6e243..0000000 --- a/tests/http-route-surface-contract.test.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { readFile, readdir } from "node:fs/promises"; -import { dirname, join, relative, sep } from "node:path"; -import { fileURLToPath } from "node:url"; - -import { describe, expect, it } from "vitest"; - -type RouteContract = { - version: 1; - routes: Array<{ - method: "DELETE" | "GET" | "PATCH" | "POST" | "PUT"; - path: string; - }>; -}; - -const repositoryRoot = dirname(dirname(fileURLToPath(import.meta.url))); -const appRoot = join(repositoryRoot, "app"); -const contractPath = join(repositoryRoot, "contracts", "http", "route-surface.v1.json"); -const exportedMethod = /^\s*export\s+(?:async\s+)?function\s+(GET|POST|PUT|PATCH|DELETE)\b/gm; - -async function findRouteFiles(directory: string): Promise { - const entries = await readdir(directory, { withFileTypes: true }); - const nested = await Promise.all( - entries.map(async (entry) => { - const path = join(directory, entry.name); - if (entry.isDirectory()) return findRouteFiles(path); - return entry.isFile() && entry.name === "route.ts" ? [path] : []; - }), - ); - return nested.flat().sort(); -} - -function routePath(routeFile: string): string { - const routeDirectory = relative(appRoot, dirname(routeFile)); - const segments = routeDirectory.split(sep).map((segment) => { - if (segment.startsWith("[...") && segment.endsWith("]")) { - return `{${segment.slice(4, -1)}...}`; - } - if (segment.startsWith("[") && segment.endsWith("]")) { - return `{${segment.slice(1, -1)}}`; - } - return segment; - }); - return `/${segments.join("/")}`; -} - -async function deriveRouteSurface(routeFiles: string[]): Promise { - const routes = await Promise.all( - routeFiles.map(async (routeFile) => { - const source = await readFile(routeFile, "utf8"); - return Array.from(source.matchAll(exportedMethod), (match) => ({ - method: match[1] as RouteContract["routes"][number]["method"], - path: routePath(routeFile), - })); - }), - ); - return routes.flat().sort((left, right) => { - const leftKey = `${left.path}\u0000${left.method}`; - const rightKey = `${right.path}\u0000${right.method}`; - return leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0; - }); -} - -describe("HTTP route surface contract", () => { - it("exactly records every exported Next route method without loading handlers", async () => { - const routeFiles = await findRouteFiles(appRoot); - const actual = await deriveRouteSurface(routeFiles); - const contract = JSON.parse(await readFile(contractPath, "utf8")) as RouteContract; - - expect(routeFiles).toHaveLength(47); - expect(actual).toHaveLength(66); - expect(contract.version).toBe(1); - expect(contract.routes).toEqual(actual); - }); -}); diff --git a/tests/static-frontend-architecture.test.ts b/tests/static-frontend-architecture.test.ts new file mode 100644 index 0000000..0608d1b --- /dev/null +++ b/tests/static-frontend-architecture.test.ts @@ -0,0 +1,106 @@ +import { access, readFile, readdir } from "node:fs/promises"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +import { afterEach, describe, expect, it, vi } from "vitest"; + +import { safeBrowserLocationNext, safeBrowserNext } from "@/lib/client/browser-auth"; +import nextConfig from "../next.config"; + +const repositoryRoot = dirname(dirname(fileURLToPath(import.meta.url))); +const appRoot = join(repositoryRoot, "app"); + +afterEach(() => vi.unstubAllGlobals()); + +async function findProductionEntryFiles(directory: string): Promise { + const entries = await readdir(directory, { withFileTypes: true }); + const nested = await Promise.all(entries.map(async (entry) => { + const path = join(directory, entry.name); + if (entry.isDirectory()) return findProductionEntryFiles(path); + return entry.isFile() && /^(?:layout|page|route)\.tsx?$/.test(entry.name) ? [path] : []; + })); + return nested.flat(); +} + +async function findFilesOrEmpty(directory: string): Promise { + const entries = await readdir(directory, { withFileTypes: true }).catch((error: NodeJS.ErrnoException) => { + if (error.code === "ENOENT") return []; + throw error; + }); + const nested = await Promise.all(entries.map(async (entry) => { + const path = join(directory, entry.name); + return entry.isDirectory() ? findFilesOrEmpty(path) : [path]; + })); + return nested.flat(); +} + +describe("static frontend architecture", () => { + it("exports an image-optimizer-independent static site", () => { + expect(nextConfig.output).toBe("export"); + expect(nextConfig.images?.unoptimized).toBe(true); + }); + + it("has no Next server runtime entry points", async () => { + expect(await findFilesOrEmpty(join(appRoot, "api"))).toEqual([]); + expect(await findFilesOrEmpty(join(appRoot, "uploads"))).toEqual([]); + expect(await findFilesOrEmpty(join(appRoot, "generated-results"))).toEqual([]); + await expect(access(join(repositoryRoot, "middleware.ts"))).rejects.toMatchObject({ code: "ENOENT" }); + + const entryFiles = await findProductionEntryFiles(appRoot); + expect(entryFiles.filter((path) => path.endsWith("route.ts"))).toEqual([]); + for (const entryFile of entryFiles) { + const source = await readFile(entryFile, "utf8"); + expect(source, entryFile).not.toMatch(/(?:from\s+|import\s*\()?["']@\/lib\/server(?:\/|["'])/); + expect(source, entryFile).not.toMatch(/(?:from\s+|import\s*\()?["']next\/(?:headers|server)["']/); + } + }); + + it("loads current identity from the same-origin Go API", async () => { + const responseBody = { + authenticated: false, + authRequired: true, + authConfigured: true, + authMode: null, + user: null + }; + const fetchMock = vi.fn().mockResolvedValue( + new Response(JSON.stringify(responseBody), { + status: 200, + headers: { "content-type": "application/json" } + }) + ); + vi.stubGlobal("fetch", fetchMock); + + const { fetchBrowserAuthState } = await import("@/lib/client/browser-auth"); + await expect(fetchBrowserAuthState()).resolves.toEqual(responseBody); + expect(fetchMock).toHaveBeenCalledOnce(); + expect(fetchMock).toHaveBeenCalledWith("/api/auth/me", { + method: "GET", + cache: "no-store", + credentials: "same-origin", + headers: { Accept: "application/json" }, + signal: undefined + }); + + }); + + it("keeps safe same-origin redirects away from auth endpoints", () => { + expect(safeBrowserNext("/billing?tab=wallet#history")).toBe("/billing?tab=wallet#history"); + expect(safeBrowserLocationNext({ + pathname: "/create", + search: "?mode=video", + hash: "#x" + })).toBe("/create?mode=video#x"); + expect(safeBrowserNext("//evil.example/path", "/create?mode=video#x")).toBe("/create?mode=video#x"); + + for (const unsafe of [ + "//evil.example/path", + "/\\evil.example/path", + "/api/auth/logout", + "/auth/login", + "/auth/admin-login" + ]) { + expect(safeBrowserNext(unsafe), unsafe).toBe("/create"); + } + }); +}); diff --git a/tsconfig.tsbuildinfo b/tsconfig.tsbuildinfo index 3fc3014..23fb5bd 100644 --- a/tsconfig.tsbuildinfo +++ b/tsconfig.tsbuildinfo @@ -1 +1 @@ -{"fileNames":["./node_modules/typescript/lib/lib.es5.d.ts","./node_modules/typescript/lib/lib.es2015.d.ts","./node_modules/typescript/lib/lib.es2016.d.ts","./node_modules/typescript/lib/lib.es2017.d.ts","./node_modules/typescript/lib/lib.es2018.d.ts","./node_modules/typescript/lib/lib.es2019.d.ts","./node_modules/typescript/lib/lib.es2020.d.ts","./node_modules/typescript/lib/lib.es2021.d.ts","./node_modules/typescript/lib/lib.es2022.d.ts","./node_modules/typescript/lib/lib.dom.d.ts","./node_modules/typescript/lib/lib.dom.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.core.d.ts","./node_modules/typescript/lib/lib.es2015.collection.d.ts","./node_modules/typescript/lib/lib.es2015.generator.d.ts","./node_modules/typescript/lib/lib.es2015.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.promise.d.ts","./node_modules/typescript/lib/lib.es2015.proxy.d.ts","./node_modules/typescript/lib/lib.es2015.reflect.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2016.array.include.d.ts","./node_modules/typescript/lib/lib.es2016.intl.d.ts","./node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","./node_modules/typescript/lib/lib.es2017.date.d.ts","./node_modules/typescript/lib/lib.es2017.object.d.ts","./node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2017.string.d.ts","./node_modules/typescript/lib/lib.es2017.intl.d.ts","./node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","./node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","./node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","./node_modules/typescript/lib/lib.es2018.intl.d.ts","./node_modules/typescript/lib/lib.es2018.promise.d.ts","./node_modules/typescript/lib/lib.es2018.regexp.d.ts","./node_modules/typescript/lib/lib.es2019.array.d.ts","./node_modules/typescript/lib/lib.es2019.object.d.ts","./node_modules/typescript/lib/lib.es2019.string.d.ts","./node_modules/typescript/lib/lib.es2019.symbol.d.ts","./node_modules/typescript/lib/lib.es2019.intl.d.ts","./node_modules/typescript/lib/lib.es2020.bigint.d.ts","./node_modules/typescript/lib/lib.es2020.date.d.ts","./node_modules/typescript/lib/lib.es2020.promise.d.ts","./node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2020.string.d.ts","./node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2020.intl.d.ts","./node_modules/typescript/lib/lib.es2020.number.d.ts","./node_modules/typescript/lib/lib.es2021.promise.d.ts","./node_modules/typescript/lib/lib.es2021.string.d.ts","./node_modules/typescript/lib/lib.es2021.weakref.d.ts","./node_modules/typescript/lib/lib.es2021.intl.d.ts","./node_modules/typescript/lib/lib.es2022.array.d.ts","./node_modules/typescript/lib/lib.es2022.error.d.ts","./node_modules/typescript/lib/lib.es2022.intl.d.ts","./node_modules/typescript/lib/lib.es2022.object.d.ts","./node_modules/typescript/lib/lib.es2022.string.d.ts","./node_modules/typescript/lib/lib.es2022.regexp.d.ts","./node_modules/typescript/lib/lib.decorators.d.ts","./node_modules/typescript/lib/lib.decorators.legacy.d.ts","./.next/types/routes.d.ts","./node_modules/@types/react/global.d.ts","./node_modules/csstype/index.d.ts","./node_modules/@types/react/index.d.ts","./node_modules/next/dist/styled-jsx/types/css.d.ts","./node_modules/next/dist/styled-jsx/types/macro.d.ts","./node_modules/next/dist/styled-jsx/types/style.d.ts","./node_modules/next/dist/styled-jsx/types/global.d.ts","./node_modules/next/dist/styled-jsx/types/index.d.ts","./node_modules/next/dist/shared/lib/amp.d.ts","./node_modules/next/amp.d.ts","./node_modules/next/dist/server/get-page-files.d.ts","./node_modules/@types/node/compatibility/disposable.d.ts","./node_modules/@types/node/compatibility/indexable.d.ts","./node_modules/@types/node/compatibility/iterators.d.ts","./node_modules/@types/node/compatibility/index.d.ts","./node_modules/@types/node/globals.typedarray.d.ts","./node_modules/@types/node/buffer.buffer.d.ts","./node_modules/@types/node/globals.d.ts","./node_modules/@types/node/web-globals/abortcontroller.d.ts","./node_modules/@types/node/web-globals/domexception.d.ts","./node_modules/@types/node/web-globals/events.d.ts","./node_modules/undici-types/header.d.ts","./node_modules/undici-types/readable.d.ts","./node_modules/undici-types/file.d.ts","./node_modules/undici-types/fetch.d.ts","./node_modules/undici-types/formdata.d.ts","./node_modules/undici-types/connector.d.ts","./node_modules/undici-types/client.d.ts","./node_modules/undici-types/errors.d.ts","./node_modules/undici-types/dispatcher.d.ts","./node_modules/undici-types/global-dispatcher.d.ts","./node_modules/undici-types/global-origin.d.ts","./node_modules/undici-types/pool-stats.d.ts","./node_modules/undici-types/pool.d.ts","./node_modules/undici-types/handlers.d.ts","./node_modules/undici-types/balanced-pool.d.ts","./node_modules/undici-types/agent.d.ts","./node_modules/undici-types/mock-interceptor.d.ts","./node_modules/undici-types/mock-agent.d.ts","./node_modules/undici-types/mock-client.d.ts","./node_modules/undici-types/mock-pool.d.ts","./node_modules/undici-types/mock-errors.d.ts","./node_modules/undici-types/proxy-agent.d.ts","./node_modules/undici-types/env-http-proxy-agent.d.ts","./node_modules/undici-types/retry-handler.d.ts","./node_modules/undici-types/retry-agent.d.ts","./node_modules/undici-types/api.d.ts","./node_modules/undici-types/interceptors.d.ts","./node_modules/undici-types/util.d.ts","./node_modules/undici-types/cookies.d.ts","./node_modules/undici-types/patch.d.ts","./node_modules/undici-types/websocket.d.ts","./node_modules/undici-types/eventsource.d.ts","./node_modules/undici-types/filereader.d.ts","./node_modules/undici-types/diagnostics-channel.d.ts","./node_modules/undici-types/content-type.d.ts","./node_modules/undici-types/cache.d.ts","./node_modules/undici-types/index.d.ts","./node_modules/@types/node/web-globals/fetch.d.ts","./node_modules/@types/node/web-globals/navigator.d.ts","./node_modules/@types/node/web-globals/storage.d.ts","./node_modules/@types/node/assert.d.ts","./node_modules/@types/node/assert/strict.d.ts","./node_modules/@types/node/async_hooks.d.ts","./node_modules/@types/node/buffer.d.ts","./node_modules/@types/node/child_process.d.ts","./node_modules/@types/node/cluster.d.ts","./node_modules/@types/node/console.d.ts","./node_modules/@types/node/constants.d.ts","./node_modules/@types/node/crypto.d.ts","./node_modules/@types/node/dgram.d.ts","./node_modules/@types/node/diagnostics_channel.d.ts","./node_modules/@types/node/dns.d.ts","./node_modules/@types/node/dns/promises.d.ts","./node_modules/@types/node/domain.d.ts","./node_modules/@types/node/events.d.ts","./node_modules/@types/node/fs.d.ts","./node_modules/@types/node/fs/promises.d.ts","./node_modules/@types/node/http.d.ts","./node_modules/@types/node/http2.d.ts","./node_modules/@types/node/https.d.ts","./node_modules/@types/node/inspector.d.ts","./node_modules/@types/node/inspector.generated.d.ts","./node_modules/@types/node/module.d.ts","./node_modules/@types/node/net.d.ts","./node_modules/@types/node/os.d.ts","./node_modules/@types/node/path.d.ts","./node_modules/@types/node/perf_hooks.d.ts","./node_modules/@types/node/process.d.ts","./node_modules/@types/node/punycode.d.ts","./node_modules/@types/node/querystring.d.ts","./node_modules/@types/node/readline.d.ts","./node_modules/@types/node/readline/promises.d.ts","./node_modules/@types/node/repl.d.ts","./node_modules/@types/node/sea.d.ts","./node_modules/@types/node/sqlite.d.ts","./node_modules/@types/node/stream.d.ts","./node_modules/@types/node/stream/promises.d.ts","./node_modules/@types/node/stream/consumers.d.ts","./node_modules/@types/node/stream/web.d.ts","./node_modules/@types/node/string_decoder.d.ts","./node_modules/@types/node/test.d.ts","./node_modules/@types/node/timers.d.ts","./node_modules/@types/node/timers/promises.d.ts","./node_modules/@types/node/tls.d.ts","./node_modules/@types/node/trace_events.d.ts","./node_modules/@types/node/tty.d.ts","./node_modules/@types/node/url.d.ts","./node_modules/@types/node/util.d.ts","./node_modules/@types/node/v8.d.ts","./node_modules/@types/node/vm.d.ts","./node_modules/@types/node/wasi.d.ts","./node_modules/@types/node/worker_threads.d.ts","./node_modules/@types/node/zlib.d.ts","./node_modules/@types/node/index.d.ts","./node_modules/@types/react/canary.d.ts","./node_modules/@types/react/experimental.d.ts","./node_modules/@types/react-dom/index.d.ts","./node_modules/@types/react-dom/canary.d.ts","./node_modules/@types/react-dom/experimental.d.ts","./node_modules/next/dist/lib/fallback.d.ts","./node_modules/next/dist/compiled/webpack/webpack.d.ts","./node_modules/next/dist/server/config.d.ts","./node_modules/next/dist/lib/load-custom-routes.d.ts","./node_modules/next/dist/shared/lib/image-config.d.ts","./node_modules/next/dist/build/webpack/plugins/subresource-integrity-plugin.d.ts","./node_modules/next/dist/server/body-streams.d.ts","./node_modules/next/dist/server/lib/cache-control.d.ts","./node_modules/next/dist/lib/setup-exception-listeners.d.ts","./node_modules/next/dist/lib/worker.d.ts","./node_modules/next/dist/lib/constants.d.ts","./node_modules/next/dist/client/components/app-router-headers.d.ts","./node_modules/next/dist/build/rendering-mode.d.ts","./node_modules/next/dist/server/lib/router-utils/build-prefetch-segment-data-route.d.ts","./node_modules/next/dist/server/require-hook.d.ts","./node_modules/next/dist/server/lib/experimental/ppr.d.ts","./node_modules/next/dist/build/webpack/plugins/app-build-manifest-plugin.d.ts","./node_modules/next/dist/lib/page-types.d.ts","./node_modules/next/dist/build/segment-config/app/app-segment-config.d.ts","./node_modules/next/dist/build/segment-config/pages/pages-segment-config.d.ts","./node_modules/next/dist/build/analysis/get-page-static-info.d.ts","./node_modules/next/dist/build/webpack/loaders/get-module-build-info.d.ts","./node_modules/next/dist/build/webpack/plugins/middleware-plugin.d.ts","./node_modules/next/dist/server/node-polyfill-crypto.d.ts","./node_modules/next/dist/server/node-environment-baseline.d.ts","./node_modules/next/dist/server/node-environment-extensions/error-inspect.d.ts","./node_modules/next/dist/server/node-environment-extensions/random.d.ts","./node_modules/next/dist/server/node-environment-extensions/date.d.ts","./node_modules/next/dist/server/node-environment-extensions/web-crypto.d.ts","./node_modules/next/dist/server/node-environment-extensions/node-crypto.d.ts","./node_modules/next/dist/server/node-environment.d.ts","./node_modules/next/dist/build/page-extensions-type.d.ts","./node_modules/next/dist/build/webpack/plugins/flight-manifest-plugin.d.ts","./node_modules/next/dist/server/instrumentation/types.d.ts","./node_modules/next/dist/lib/coalesced-function.d.ts","./node_modules/next/dist/shared/lib/router/utils/middleware-route-matcher.d.ts","./node_modules/next/dist/server/lib/router-utils/types.d.ts","./node_modules/next/dist/shared/lib/modern-browserslist-target.d.ts","./node_modules/next/dist/shared/lib/constants.d.ts","./node_modules/next/dist/trace/types.d.ts","./node_modules/next/dist/trace/trace.d.ts","./node_modules/next/dist/trace/shared.d.ts","./node_modules/next/dist/trace/index.d.ts","./node_modules/next/dist/build/load-jsconfig.d.ts","./node_modules/@next/env/dist/index.d.ts","./node_modules/next/dist/build/webpack/plugins/telemetry-plugin/use-cache-tracker-utils.d.ts","./node_modules/next/dist/build/webpack/plugins/telemetry-plugin/telemetry-plugin.d.ts","./node_modules/next/dist/telemetry/storage.d.ts","./node_modules/next/dist/build/build-context.d.ts","./node_modules/next/dist/shared/lib/bloom-filter.d.ts","./node_modules/next/dist/build/webpack-config.d.ts","./node_modules/next/dist/server/route-kind.d.ts","./node_modules/next/dist/server/route-definitions/route-definition.d.ts","./node_modules/next/dist/build/swc/generated-native.d.ts","./node_modules/next/dist/build/swc/types.d.ts","./node_modules/next/dist/server/dev/parse-version-info.d.ts","./node_modules/next/dist/next-devtools/shared/types.d.ts","./node_modules/next/dist/server/dev/dev-indicator-server-state.d.ts","./node_modules/next/dist/server/lib/parse-stack.d.ts","./node_modules/next/dist/next-devtools/server/shared.d.ts","./node_modules/next/dist/next-devtools/shared/stack-frame.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/utils/get-error-by-type.d.ts","./node_modules/@types/react/jsx-runtime.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/container/runtime-error/render-error.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/shared.d.ts","./node_modules/next/dist/server/dev/hot-reloader-types.d.ts","./node_modules/next/dist/server/lib/cache-handlers/types.d.ts","./node_modules/next/dist/server/response-cache/types.d.ts","./node_modules/next/dist/server/resume-data-cache/cache-store.d.ts","./node_modules/next/dist/server/resume-data-cache/resume-data-cache.d.ts","./node_modules/next/dist/server/render-result.d.ts","./node_modules/next/dist/server/lib/i18n-provider.d.ts","./node_modules/next/dist/server/web/next-url.d.ts","./node_modules/next/dist/compiled/@edge-runtime/cookies/index.d.ts","./node_modules/next/dist/server/web/spec-extension/cookies.d.ts","./node_modules/next/dist/server/web/spec-extension/request.d.ts","./node_modules/next/dist/server/after/builtin-request-context.d.ts","./node_modules/next/dist/server/web/spec-extension/fetch-event.d.ts","./node_modules/next/dist/server/web/spec-extension/response.d.ts","./node_modules/next/dist/build/segment-config/middleware/middleware-config.d.ts","./node_modules/next/dist/server/web/types.d.ts","./node_modules/next/dist/build/webpack/plugins/pages-manifest-plugin.d.ts","./node_modules/next/dist/shared/lib/router/utils/parse-url.d.ts","./node_modules/next/dist/server/base-http/node.d.ts","./node_modules/next/dist/build/webpack/plugins/next-font-manifest-plugin.d.ts","./node_modules/next/dist/server/route-definitions/locale-route-definition.d.ts","./node_modules/next/dist/server/route-definitions/pages-route-definition.d.ts","./node_modules/next/dist/shared/lib/mitt.d.ts","./node_modules/next/dist/client/with-router.d.ts","./node_modules/next/dist/client/router.d.ts","./node_modules/next/dist/client/route-loader.d.ts","./node_modules/next/dist/client/page-loader.d.ts","./node_modules/next/dist/shared/lib/router/router.d.ts","./node_modules/next/dist/shared/lib/router-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/loadable-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/loadable.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/image-config-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/hooks-client-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/head-manager-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-definitions/app-page-route-definition.d.ts","./node_modules/next/dist/build/webpack/loaders/metadata/types.d.ts","./node_modules/next/dist/build/webpack/loaders/next-app-loader/index.d.ts","./node_modules/next/dist/server/lib/app-dir-module.d.ts","./node_modules/next/dist/server/web/spec-extension/adapters/request-cookies.d.ts","./node_modules/next/dist/server/async-storage/draft-mode-provider.d.ts","./node_modules/next/dist/server/web/spec-extension/adapters/headers.d.ts","./node_modules/next/dist/server/app-render/cache-signal.d.ts","./node_modules/next/dist/server/app-render/dynamic-rendering.d.ts","./node_modules/next/dist/server/request/fallback-params.d.ts","./node_modules/next/dist/server/app-render/work-unit-async-storage-instance.d.ts","./node_modules/next/dist/server/response-cache/index.d.ts","./node_modules/next/dist/server/lib/lazy-result.d.ts","./node_modules/next/dist/server/lib/implicit-tags.d.ts","./node_modules/next/dist/server/app-render/work-unit-async-storage.external.d.ts","./node_modules/next/dist/shared/lib/deep-readonly.d.ts","./node_modules/next/dist/shared/lib/router/utils/parse-relative-url.d.ts","./node_modules/next/dist/server/app-render/app-render.d.ts","./node_modules/next/dist/shared/lib/server-inserted-html.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/amp-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/contexts/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/app-page/module.compiled.d.ts","./node_modules/next/dist/client/components/error-boundary.d.ts","./node_modules/next/dist/client/components/layout-router.d.ts","./node_modules/next/dist/client/components/render-from-template-context.d.ts","./node_modules/next/dist/server/app-render/action-async-storage-instance.d.ts","./node_modules/next/dist/server/app-render/action-async-storage.external.d.ts","./node_modules/next/dist/client/components/client-page.d.ts","./node_modules/next/dist/client/components/client-segment.d.ts","./node_modules/next/dist/server/request/search-params.d.ts","./node_modules/next/dist/client/components/hooks-server-context.d.ts","./node_modules/next/dist/client/components/http-access-fallback/error-boundary.d.ts","./node_modules/next/dist/lib/metadata/types/alternative-urls-types.d.ts","./node_modules/next/dist/lib/metadata/types/extra-types.d.ts","./node_modules/next/dist/lib/metadata/types/metadata-types.d.ts","./node_modules/next/dist/lib/metadata/types/manifest-types.d.ts","./node_modules/next/dist/lib/metadata/types/opengraph-types.d.ts","./node_modules/next/dist/lib/metadata/types/twitter-types.d.ts","./node_modules/next/dist/lib/metadata/types/metadata-interface.d.ts","./node_modules/next/dist/lib/metadata/types/resolvers.d.ts","./node_modules/next/dist/lib/metadata/types/icons.d.ts","./node_modules/next/dist/lib/metadata/resolve-metadata.d.ts","./node_modules/next/dist/lib/metadata/metadata.d.ts","./node_modules/next/dist/lib/framework/boundary-components.d.ts","./node_modules/next/dist/server/app-render/rsc/preloads.d.ts","./node_modules/next/dist/server/app-render/rsc/postpone.d.ts","./node_modules/next/dist/server/app-render/rsc/taint.d.ts","./node_modules/next/dist/shared/lib/segment-cache/segment-value-encoding.d.ts","./node_modules/next/dist/server/app-render/collect-segment-data.d.ts","./node_modules/next/dist/next-devtools/userspace/app/segment-explorer-node.d.ts","./node_modules/next/dist/server/app-render/entry-base.d.ts","./node_modules/next/dist/build/templates/app-page.d.ts","./node_modules/@types/react/jsx-dev-runtime.d.ts","./node_modules/@types/react/compiler-runtime.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/rsc/entrypoints.d.ts","./node_modules/@types/react-dom/client.d.ts","./node_modules/@types/react-dom/static.d.ts","./node_modules/@types/react-dom/server.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/ssr/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/app-page/module.d.ts","./node_modules/next/dist/server/web/adapter.d.ts","./node_modules/next/dist/server/use-cache/cache-life.d.ts","./node_modules/next/dist/server/app-render/types.d.ts","./node_modules/next/dist/client/components/router-reducer/router-reducer-types.d.ts","./node_modules/next/dist/client/flight-data-helpers.d.ts","./node_modules/next/dist/client/components/router-reducer/fetch-server-response.d.ts","./node_modules/next/dist/shared/lib/app-router-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-modules/pages/vendored/contexts/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/pages/module.compiled.d.ts","./node_modules/next/dist/build/templates/pages.d.ts","./node_modules/next/dist/server/route-modules/pages/module.d.ts","./node_modules/next/dist/next-devtools/userspace/pages/pages-dev-overlay-setup.d.ts","./node_modules/next/dist/server/render.d.ts","./node_modules/next/dist/server/route-definitions/pages-api-route-definition.d.ts","./node_modules/next/dist/server/route-matches/pages-api-route-match.d.ts","./node_modules/next/dist/server/route-matchers/route-matcher.d.ts","./node_modules/next/dist/server/route-matcher-providers/route-matcher-provider.d.ts","./node_modules/next/dist/server/route-matcher-managers/route-matcher-manager.d.ts","./node_modules/next/dist/server/normalizers/normalizer.d.ts","./node_modules/next/dist/server/normalizers/locale-route-normalizer.d.ts","./node_modules/next/dist/server/normalizers/request/pathname-normalizer.d.ts","./node_modules/next/dist/server/normalizers/request/suffix.d.ts","./node_modules/next/dist/server/normalizers/request/rsc.d.ts","./node_modules/next/dist/server/normalizers/request/prefetch-rsc.d.ts","./node_modules/next/dist/server/normalizers/request/next-data.d.ts","./node_modules/next/dist/server/normalizers/request/segment-prefix-rsc.d.ts","./node_modules/next/dist/build/static-paths/types.d.ts","./node_modules/next/dist/server/base-server.d.ts","./node_modules/next/dist/server/lib/async-callback-set.d.ts","./node_modules/next/dist/shared/lib/router/utils/route-regex.d.ts","./node_modules/next/dist/shared/lib/router/utils/route-matcher.d.ts","./node_modules/sharp/lib/index.d.ts","./node_modules/next/dist/server/image-optimizer.d.ts","./node_modules/next/dist/server/next-server.d.ts","./node_modules/next/dist/server/lib/types.d.ts","./node_modules/next/dist/server/lib/lru-cache.d.ts","./node_modules/next/dist/server/lib/dev-bundler-service.d.ts","./node_modules/next/dist/server/dev/static-paths-worker.d.ts","./node_modules/next/dist/server/dev/next-dev-server.d.ts","./node_modules/next/dist/server/next.d.ts","./node_modules/next/dist/server/lib/render-server.d.ts","./node_modules/next/dist/server/lib/router-server.d.ts","./node_modules/next/dist/shared/lib/router/utils/path-match.d.ts","./node_modules/next/dist/server/lib/router-utils/filesystem.d.ts","./node_modules/next/dist/server/lib/router-utils/setup-dev-bundler.d.ts","./node_modules/next/dist/server/lib/router-utils/router-server-context.d.ts","./node_modules/next/dist/server/route-modules/route-module.d.ts","./node_modules/next/dist/server/load-components.d.ts","./node_modules/next/dist/server/route-definitions/app-route-route-definition.d.ts","./node_modules/next/dist/server/async-storage/work-store.d.ts","./node_modules/next/dist/server/web/http.d.ts","./node_modules/next/dist/server/route-modules/app-route/shared-modules.d.ts","./node_modules/next/dist/client/components/redirect-status-code.d.ts","./node_modules/next/dist/client/components/redirect-error.d.ts","./node_modules/next/dist/build/templates/app-route.d.ts","./node_modules/next/dist/server/route-modules/app-route/module.d.ts","./node_modules/next/dist/server/route-modules/app-route/module.compiled.d.ts","./node_modules/next/dist/build/segment-config/app/app-segments.d.ts","./node_modules/next/dist/build/utils.d.ts","./node_modules/next/dist/build/turborepo-access-trace/types.d.ts","./node_modules/next/dist/build/turborepo-access-trace/result.d.ts","./node_modules/next/dist/build/turborepo-access-trace/helpers.d.ts","./node_modules/next/dist/build/turborepo-access-trace/index.d.ts","./node_modules/next/dist/export/routes/types.d.ts","./node_modules/next/dist/export/types.d.ts","./node_modules/next/dist/export/worker.d.ts","./node_modules/next/dist/build/worker.d.ts","./node_modules/next/dist/build/index.d.ts","./node_modules/next/dist/server/lib/incremental-cache/index.d.ts","./node_modules/next/dist/server/after/after.d.ts","./node_modules/next/dist/server/after/after-context.d.ts","./node_modules/next/dist/server/app-render/work-async-storage-instance.d.ts","./node_modules/next/dist/server/app-render/work-async-storage.external.d.ts","./node_modules/next/dist/server/request/params.d.ts","./node_modules/next/dist/server/route-matches/route-match.d.ts","./node_modules/next/dist/server/request-meta.d.ts","./node_modules/next/dist/cli/next-test.d.ts","./node_modules/next/dist/server/config-shared.d.ts","./node_modules/next/dist/server/base-http/index.d.ts","./node_modules/next/dist/server/api-utils/index.d.ts","./node_modules/next/dist/types.d.ts","./node_modules/next/dist/shared/lib/html-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/utils.d.ts","./node_modules/next/dist/pages/_app.d.ts","./node_modules/next/app.d.ts","./node_modules/next/dist/server/web/spec-extension/unstable-cache.d.ts","./node_modules/next/dist/server/web/spec-extension/revalidate.d.ts","./node_modules/next/dist/server/web/spec-extension/unstable-no-store.d.ts","./node_modules/next/dist/server/use-cache/cache-tag.d.ts","./node_modules/next/cache.d.ts","./node_modules/next/dist/shared/lib/runtime-config.external.d.ts","./node_modules/next/config.d.ts","./node_modules/next/dist/pages/_document.d.ts","./node_modules/next/document.d.ts","./node_modules/next/dist/shared/lib/dynamic.d.ts","./node_modules/next/dynamic.d.ts","./node_modules/next/dist/pages/_error.d.ts","./node_modules/next/error.d.ts","./node_modules/next/dist/shared/lib/head.d.ts","./node_modules/next/head.d.ts","./node_modules/next/dist/server/request/cookies.d.ts","./node_modules/next/dist/server/request/headers.d.ts","./node_modules/next/dist/server/request/draft-mode.d.ts","./node_modules/next/headers.d.ts","./node_modules/next/dist/shared/lib/get-img-props.d.ts","./node_modules/next/dist/client/image-component.d.ts","./node_modules/next/dist/shared/lib/image-external.d.ts","./node_modules/next/image.d.ts","./node_modules/next/dist/client/link.d.ts","./node_modules/next/link.d.ts","./node_modules/next/dist/client/components/redirect.d.ts","./node_modules/next/dist/client/components/not-found.d.ts","./node_modules/next/dist/client/components/forbidden.d.ts","./node_modules/next/dist/client/components/unauthorized.d.ts","./node_modules/next/dist/client/components/unstable-rethrow.server.d.ts","./node_modules/next/dist/client/components/unstable-rethrow.d.ts","./node_modules/next/dist/client/components/navigation.react-server.d.ts","./node_modules/next/dist/client/components/unrecognized-action-error.d.ts","./node_modules/next/dist/client/components/navigation.d.ts","./node_modules/next/navigation.d.ts","./node_modules/next/router.d.ts","./node_modules/next/dist/client/script.d.ts","./node_modules/next/script.d.ts","./node_modules/next/dist/server/web/spec-extension/user-agent.d.ts","./node_modules/next/dist/compiled/@edge-runtime/primitives/url.d.ts","./node_modules/next/dist/server/web/spec-extension/image-response.d.ts","./node_modules/next/dist/compiled/@vercel/og/satori/index.d.ts","./node_modules/next/dist/compiled/@vercel/og/emoji/index.d.ts","./node_modules/next/dist/compiled/@vercel/og/types.d.ts","./node_modules/next/dist/server/after/index.d.ts","./node_modules/next/dist/server/request/root-params.d.ts","./node_modules/next/dist/server/request/connection.d.ts","./node_modules/next/server.d.ts","./node_modules/next/types/global.d.ts","./node_modules/next/types/compiled.d.ts","./node_modules/next/types.d.ts","./node_modules/next/index.d.ts","./node_modules/next/image-types/global.d.ts","./next-env.d.ts","./lib/auth/config.ts","./lib/auth/session.ts","./middleware.ts","./next.config.ts","./node_modules/@vitest/spy/optional-types.d.ts","./node_modules/@vitest/spy/dist/index.d.ts","./node_modules/tinyrainbow/dist/index.d.ts","./node_modules/@standard-schema/spec/dist/index.d.ts","./node_modules/@vitest/pretty-format/dist/index.d.ts","./node_modules/@vitest/utils/dist/types.d-bcelap-c.d.ts","./node_modules/@vitest/utils/dist/diff.d.ts","./node_modules/@vitest/utils/dist/display.d.ts","./node_modules/@types/deep-eql/index.d.ts","./node_modules/assertion-error/index.d.ts","./node_modules/@types/chai/index.d.ts","./node_modules/@vitest/expect/dist/index.d.ts","./node_modules/vite/types/hmrpayload.d.ts","./node_modules/vite/dist/node/chunks/modulerunnertransport.d.ts","./node_modules/vite/types/customevent.d.ts","./node_modules/rolldown/dist/shared/logging-bsnejils.d.mts","./node_modules/@oxc-project/types/types.d.ts","./node_modules/rolldown/dist/shared/binding-dktddyoy.d.mts","./node_modules/@rolldown/pluginutils/dist/filter/index.d.mts","./node_modules/@rolldown/pluginutils/dist/index.d.mts","./node_modules/rolldown/dist/shared/define-config-bo24xyuk.d.mts","./node_modules/rolldown/dist/index.d.mts","./node_modules/rolldown/dist/parse-ast-index.d.mts","./node_modules/vite/types/internal/rolluptypecompat.d.ts","./node_modules/rolldown/dist/shared/constructors-dc4y1bfn.d.mts","./node_modules/rolldown/dist/plugins-index.d.mts","./node_modules/rolldown/dist/shared/transform-bpesea-x.d.mts","./node_modules/rolldown/dist/utils-index.d.mts","./node_modules/vite/types/hot.d.ts","./node_modules/vite/dist/node/module-runner.d.ts","./node_modules/vite/types/internal/esbuildoptions.d.ts","./node_modules/vite/types/metadata.d.ts","./node_modules/vite/types/internal/terseroptions.d.ts","./node_modules/source-map-js/source-map.d.ts","./node_modules/postcss/lib/previous-map.d.ts","./node_modules/postcss/lib/input.d.ts","./node_modules/postcss/lib/css-syntax-error.d.ts","./node_modules/postcss/lib/declaration.d.ts","./node_modules/postcss/lib/root.d.ts","./node_modules/postcss/lib/warning.d.ts","./node_modules/postcss/lib/lazy-result.d.ts","./node_modules/postcss/lib/no-work-result.d.ts","./node_modules/postcss/lib/processor.d.ts","./node_modules/postcss/lib/result.d.ts","./node_modules/postcss/lib/document.d.ts","./node_modules/postcss/lib/rule.d.ts","./node_modules/postcss/lib/node.d.ts","./node_modules/postcss/lib/comment.d.ts","./node_modules/postcss/lib/container.d.ts","./node_modules/postcss/lib/at-rule.d.ts","./node_modules/postcss/lib/list.d.ts","./node_modules/postcss/lib/postcss.d.ts","./node_modules/postcss/lib/postcss.d.mts","./node_modules/lightningcss/node/ast.d.ts","./node_modules/lightningcss/node/targets.d.ts","./node_modules/lightningcss/node/index.d.ts","./node_modules/vite/types/internal/lightningcssoptions.d.ts","./node_modules/vite/types/internal/csspreprocessoroptions.d.ts","./node_modules/rolldown/dist/filter-index.d.mts","./node_modules/vite/types/importglob.d.ts","./node_modules/vite/dist/node/index.d.ts","./node_modules/@vitest/utils/dist/types.d.ts","./node_modules/@vitest/utils/dist/helpers.d.ts","./node_modules/@vitest/utils/dist/timers.d.ts","./node_modules/@vitest/utils/dist/index.d.ts","./node_modules/@vitest/runner/dist/tasks.d-deyaimiu.d.ts","./node_modules/@vitest/runner/dist/index.d.ts","./node_modules/vitest/dist/chunks/traces.d.d2t_r8rx.d.ts","./node_modules/@vitest/snapshot/dist/environment.d-dojxxzv9.d.ts","./node_modules/@vitest/snapshot/dist/rawsnapshot.d-d_x3-62x.d.ts","./node_modules/@vitest/snapshot/dist/index.d.ts","./node_modules/vitest/dist/chunks/config.d.a1h_y6jt.d.ts","./node_modules/vitest/dist/chunks/environment.d.crsxczp1.d.ts","./node_modules/vitest/dist/chunks/rpc.d.b_8spu0w.d.ts","./node_modules/vitest/dist/chunks/worker.d.zphpo4yb.d.ts","./node_modules/vitest/dist/chunks/browser.d.bcoexmfg.d.ts","./node_modules/vitest/optional-types.d.ts","./node_modules/@vitest/runner/dist/utils.d.ts","./node_modules/tinybench/dist/index.d.ts","./node_modules/vitest/dist/chunks/benchmark.d.daahlpsq.d.ts","./node_modules/@vitest/mocker/dist/types.d-bji5eawu.d.ts","./node_modules/@vitest/mocker/dist/index.d-b41z0auw.d.ts","./node_modules/@vitest/mocker/dist/index.d.ts","./node_modules/@vitest/utils/dist/source-map.d.ts","./node_modules/vitest/dist/chunks/coverage.d.bztk59wp.d.ts","./node_modules/@vitest/utils/dist/serialize.d.ts","./node_modules/@vitest/utils/dist/error.d.ts","./node_modules/vitest/dist/browser.d.ts","./node_modules/vitest/browser/context.d.ts","./node_modules/@vitest/snapshot/dist/manager.d.ts","./node_modules/vitest/dist/chunks/reporters.d.ctluhkka.d.ts","./node_modules/vitest/dist/chunks/plugin.d.c0upjs_f.d.ts","./node_modules/vitest/dist/config.d.ts","./node_modules/vitest/config.d.ts","./vitest.config.ts","./node_modules/@supabase/functions-js/dist/module/types.d.ts","./node_modules/@supabase/functions-js/dist/module/functionsclient.d.ts","./node_modules/@supabase/functions-js/dist/module/index.d.ts","./node_modules/@supabase/postgrest-js/dist/index.d.mts","./node_modules/@supabase/realtime-js/dist/module/lib/websocket-factory.d.ts","./node_modules/@supabase/realtime-js/dist/module/lib/serializer.d.ts","./node_modules/@supabase/phoenix/priv/static/types/constants.d.ts","./node_modules/@supabase/phoenix/priv/static/types/longpoll.d.ts","./node_modules/@supabase/phoenix/priv/static/types/types.d.ts","./node_modules/@supabase/phoenix/priv/static/types/timer.d.ts","./node_modules/@supabase/phoenix/priv/static/types/socket.d.ts","./node_modules/@supabase/phoenix/priv/static/types/push.d.ts","./node_modules/@supabase/phoenix/priv/static/types/channel.d.ts","./node_modules/@supabase/phoenix/priv/static/types/presence.d.ts","./node_modules/@supabase/phoenix/priv/static/types/serializer.d.ts","./node_modules/@supabase/phoenix/priv/static/types/index.d.ts","./node_modules/@supabase/realtime-js/dist/module/phoenix/types.d.ts","./node_modules/@supabase/realtime-js/dist/module/lib/constants.d.ts","./node_modules/@supabase/realtime-js/dist/module/realtimepresence.d.ts","./node_modules/@supabase/realtime-js/dist/module/realtimechannel.d.ts","./node_modules/@supabase/realtime-js/dist/module/realtimeclient.d.ts","./node_modules/@supabase/realtime-js/dist/module/index.d.ts","./node_modules/iceberg-js/dist/index.d.ts","./node_modules/@supabase/storage-js/dist/index.d.mts","./node_modules/@supabase/auth-js/dist/module/lib/error-codes.d.ts","./node_modules/@supabase/auth-js/dist/module/lib/errors.d.ts","./node_modules/@supabase/auth-js/dist/module/lib/web3/ethereum.d.ts","./node_modules/@supabase/auth-js/dist/module/lib/web3/solana.d.ts","./node_modules/@supabase/auth-js/dist/module/lib/webauthn.dom.d.ts","./node_modules/@supabase/auth-js/dist/module/lib/helpers.d.ts","./node_modules/@supabase/auth-js/dist/module/gotrueclient.d.ts","./node_modules/@supabase/auth-js/dist/module/lib/webauthn.errors.d.ts","./node_modules/@supabase/auth-js/dist/module/lib/webauthn.d.ts","./node_modules/@supabase/auth-js/dist/module/lib/types.d.ts","./node_modules/@supabase/auth-js/dist/module/lib/fetch.d.ts","./node_modules/@supabase/auth-js/dist/module/gotrueadminapi.d.ts","./node_modules/@supabase/auth-js/dist/module/authadminapi.d.ts","./node_modules/@supabase/auth-js/dist/module/authclient.d.ts","./node_modules/@supabase/auth-js/dist/module/lib/locks.d.ts","./node_modules/@supabase/auth-js/dist/module/index.d.ts","./node_modules/@supabase/supabase-js/dist/index.d.mts","./lib/types.ts","./lib/server/ids.ts","./lib/server/runtime.ts","./lib/server/data-store.ts","./lib/server/api.ts","./lib/server/auth/current-user.ts","./app/api/assets/route.ts","./lib/server/storage.ts","./app/api/assets/[id]/route.ts","./app/api/assets/[id]/download/route.ts","./lib/jimeng/capabilities.ts","./lib/evolink/image-client.ts","./lib/server/mock-image.ts","./lib/volcengine/signature.ts","./lib/volcengine/visual-client.ts","./lib/server/generation-service.ts","./app/api/assets/[id]/inpaint/route.ts","./app/api/assets/[id]/upscale/route.ts","./app/api/assets/upload/route.ts","./lib/server/auth/jwt.ts","./lib/server/auth/oauth.ts","./app/api/auth/callback/route.ts","./app/api/auth/captcha/route.ts","./app/api/auth/login/route.ts","./app/api/auth/logout/route.ts","./app/api/auth/me/route.ts","./app/api/auth/password/route.ts","./lib/content/seedance-starter/catalog.json","./lib/content/video-templates.ts","./lib/prompt/assembler.ts","./app/api/generations/image/route.ts","./app/api/generations/image/[id]/route.ts","./app/api/generations/image/[id]/retry/route.ts","./lib/video-settings.ts","./lib/seedance/client.ts","./lib/server/video-generation-service.ts","./app/api/generations/video/route.ts","./app/api/generations/video/[id]/route.ts","./app/api/health/route.ts","./lib/server/public-api-auth.ts","./lib/server/webhook.ts","./lib/server/task-manager.ts","./app/api/internal/worker/tick/route.ts","./app/api/prompt/assemble/route.ts","./lib/server/app-settings.ts","./app/api/settings/route.ts","./lib/server/public-api-assets.ts","./lib/server/public-api-jobs.ts","./lib/server/public-api-response.ts","./app/api/v1/assets/route.ts","./app/api/v1/assets/[id]/route.ts","./app/api/v1/assets/[id]/download/route.ts","./app/api/v1/capabilities/route.ts","./app/api/v1/jobs/route.ts","./app/api/v1/jobs/[id]/route.ts","./app/api/v1/jobs/[id]/cancel/route.ts","./app/api/v1/openapi.json/route.ts","./app/generated-results/[...path]/route.ts","./app/uploads/[...path]/route.ts","./lib/client/random-uuid-polyfill.ts","./node_modules/gsap/types/animation.d.ts","./node_modules/gsap/types/custom-bounce.d.ts","./node_modules/gsap/types/custom-ease.d.ts","./node_modules/gsap/types/custom-wiggle.d.ts","./node_modules/gsap/types/css-plugin.d.ts","./node_modules/gsap/types/css-rule-plugin.d.ts","./node_modules/gsap/types/draggable.d.ts","./node_modules/gsap/types/draw-svg-plugin.d.ts","./node_modules/gsap/types/ease.d.ts","./node_modules/gsap/types/easel-plugin.d.ts","./node_modules/gsap/types/flip.d.ts","./node_modules/gsap/types/gs-dev-tools.d.ts","./node_modules/gsap/types/gsap-plugins.d.ts","./node_modules/gsap/types/gsap-utils.d.ts","./node_modules/gsap/types/utils/velocitytracker.d.ts","./node_modules/gsap/types/inertia-plugin.d.ts","./node_modules/gsap/types/morph-svg-plugin.d.ts","./node_modules/gsap/types/motion-path-plugin.d.ts","./node_modules/gsap/types/motion-path-helper.d.ts","./node_modules/gsap/types/observer.d.ts","./node_modules/gsap/types/physics-2d-plugin.d.ts","./node_modules/gsap/types/physics-props-plugin.d.ts","./node_modules/gsap/types/pixi-plugin.d.ts","./node_modules/gsap/types/scramble-text-plugin.d.ts","./node_modules/gsap/types/scroll-to-plugin.d.ts","./node_modules/gsap/types/scroll-trigger.d.ts","./node_modules/gsap/types/scroll-smoother.d.ts","./node_modules/gsap/types/split-text.d.ts","./node_modules/gsap/types/text-plugin.d.ts","./node_modules/gsap/types/timeline.d.ts","./node_modules/gsap/types/tween.d.ts","./node_modules/gsap/types/gsap-core.d.ts","./node_modules/gsap/types/index.d.ts","./lib/ui/motion.ts","./node_modules/vitest/dist/chunks/global.d.dvssrdq5.d.ts","./node_modules/vitest/optional-runtime-types.d.ts","./node_modules/vitest/dist/chunks/suite.d.udjtyagw.d.ts","./node_modules/vitest/dist/chunks/evaluatedmodules.d.bxj5omdx.d.ts","./node_modules/vitest/dist/runners.d.ts","./node_modules/expect-type/dist/utils.d.ts","./node_modules/expect-type/dist/overloads.d.ts","./node_modules/expect-type/dist/branding.d.ts","./node_modules/expect-type/dist/messages.d.ts","./node_modules/expect-type/dist/index.d.ts","./node_modules/vitest/dist/index.d.ts","./tests/auth-session.test.ts","./tests/data-store-concurrency.test.ts","./tests/deploy-env.test.ts","./tests/evolink-image-client.test.ts","./tests/jimeng-capabilities.test.ts","./tests/prompt-assembler.test.ts","./tests/random-uuid-polyfill.test.ts","./tests/task-management.test.ts","./tests/video-settings.test.ts","./tests/volcengine-signature.test.ts","./tests/worker-script.test.ts","./types/ali-oss.d.ts","./node_modules/lucide-react/dist/lucide-react.d.ts","./node_modules/clsx/clsx.d.mts","./components/app-shell.tsx","./app/layout.tsx","./app/page.tsx","./components/pagination.tsx","./components/asset-manager.tsx","./app/assets/page.tsx","./components/auth-login-panel.tsx","./app/auth/login/page.tsx","./components/image-editor.tsx","./components/create-studio.tsx","./app/create/page.tsx","./app/image-edit/page.tsx","./components/settings-panel.tsx","./app/settings/page.tsx","./.next/types/cache-life.d.ts","./.next/types/validator.ts","./.next/types/app/page.ts","./.next/types/app/api/assets/route.ts","./.next/types/app/api/assets/[id]/route.ts","./.next/types/app/api/assets/[id]/download/route.ts","./.next/types/app/api/assets/[id]/inpaint/route.ts","./.next/types/app/api/assets/[id]/upscale/route.ts","./.next/types/app/api/assets/upload/route.ts","./.next/types/app/api/auth/callback/route.ts","./.next/types/app/api/auth/captcha/route.ts","./.next/types/app/api/auth/login/route.ts","./.next/types/app/api/auth/logout/route.ts","./.next/types/app/api/auth/me/route.ts","./.next/types/app/api/auth/password/route.ts","./.next/types/app/api/generations/image/route.ts","./.next/types/app/api/generations/image/[id]/route.ts","./.next/types/app/api/generations/image/[id]/retry/route.ts","./.next/types/app/api/generations/video/route.ts","./.next/types/app/api/generations/video/[id]/route.ts","./.next/types/app/api/health/route.ts","./.next/types/app/api/internal/worker/tick/route.ts","./.next/types/app/api/prompt/assemble/route.ts","./.next/types/app/api/settings/route.ts","./.next/types/app/api/v1/assets/route.ts","./.next/types/app/api/v1/assets/[id]/route.ts","./.next/types/app/api/v1/assets/[id]/download/route.ts","./.next/types/app/api/v1/capabilities/route.ts","./.next/types/app/api/v1/jobs/route.ts","./.next/types/app/api/v1/jobs/[id]/route.ts","./.next/types/app/api/v1/jobs/[id]/cancel/route.ts","./.next/types/app/api/v1/openapi.json/route.ts","./.next/types/app/assets/page.ts","./.next/types/app/auth/login/page.ts","./.next/types/app/create/page.ts","./.next/types/app/generated-results/[...path]/route.ts","./.next/types/app/image-edit/page.ts","./.next/types/app/settings/page.ts","./.next/types/app/uploads/[...path]/route.ts","./node_modules/@types/aria-query/index.d.ts","./node_modules/@types/estree/index.d.ts"],"fileIdsList":[[77,125,142,143,472,628,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,635,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,627,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,636,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,625,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,637,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,640,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,641,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,642,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,643,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,644,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,645,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,651,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,650,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,649,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,656,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,655,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,657,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,661,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,662,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,664,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,670,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,669,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,668,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,671,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,674,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,673,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,672,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,675,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,318,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,743],[77,125,142,143,318,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,745],[77,125,142,143,318,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,748],[77,125,142,143,472,676,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,318,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,749],[77,125,142,143,318,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,740],[77,125,142,143,318,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,751],[77,125,142,143,472,677,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,425,426,427,428,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[60,77,125,142,143,472,475,625,627,628,635,636,637,640,641,642,643,644,645,649,650,651,655,656,657,661,662,664,668,669,670,671,672,673,674,675,676,677,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,739,740,743,745,748,749,751],[77,125,142,143,622,623,624,626,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,621,622,623,624,626,634,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,621,622,623,624,634,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,619,622,623,624,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,621,623,624,626,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,639,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,479,623,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,479,623,624,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,479,480,623,638,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,621,623,624,634,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,619,621,622,623,624,634,648,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,621,622,623,624,654,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,479,623,629,630,633,653,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,623,658,660,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,623,624,648,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,623,624,663,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,623,626,658,665,667,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,623,658,665,667,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,619,621,622,623,626,658,665,667,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,623,629,630,653,658,667,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,622,623,658,667,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,619,621,622,623,658,666,667,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,621,623,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,742],[77,125,142,143,459,479,624,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,744],[77,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,747],[77,125,142,143,622,624,626,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,459,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,462,476,624,678,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,738],[77,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,750],[63,77,125,142,143,447,449,459,480,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,712,736,737],[63,77,125,142,143,619,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,712,736,741],[63,77,125,142,143,447,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,712,736],[63,77,125,142,143,619,648,652,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,712,736,737,741,746],[63,77,125,142,143,619,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,712,736,737,741],[77,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,736],[63,77,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,712,736],[77,125,142,143,646,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,619,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,647,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,648,652,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,138,142,143,147,479,619,621,629,630,633,653,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,443,479,480,621,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,130,142,143,479,480,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,479,480,621,638,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,138,142,143,147,618,619,620,621,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,619,621,622,626,629,630,631,633,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,130,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,619,621,622,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,130,142,143,619,621,622,634,648,654,658,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,623,658,666,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,138,142,143,147,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,138,142,143,147,619,620,621,622,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,735],[77,125,130,142,143,619,621,622,634,654,659,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,619,621,622,626,648,652,653,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,130,142,143,619,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,619,632,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,472,479,480,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[60,77,125,142,143,476,477,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,476,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,501,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,613,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,608,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,603,611,612,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,603,607,611,612,613,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,603,608,611,613,614,615,616,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,602,611,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,611,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,606,611,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,603,604,605,606,610,612,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,603,606,608,609,611,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,578,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,578,579,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,586,587,588,589,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,585,586,587,588,589,590,591,592,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,586,590,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,586,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,585,586,587,590,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,584,585,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,582,596,597,598,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,594,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,593,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,593,594,595,596,598,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,582,583,594,595,597,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,597,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,600,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,580,581,599,601,617,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,491,492,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,122,123,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,124,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,130,142,143,160,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,126,131,136,142,143,145,157,168,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,126,127,136,142,143,145,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[72,73,74,77,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,128,142,143,169,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,129,130,137,142,143,146,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,130,142,143,157,165,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,131,133,136,142,143,145,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,124,125,132,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,133,134,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,135,136,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,124,125,136,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,136,137,138,142,143,157,168,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,136,137,138,142,143,152,157,160,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,118,125,133,136,139,142,143,145,157,168,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,136,137,139,140,142,143,145,157,165,168,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,141,142,143,157,165,168,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[75,76,77,78,79,80,81,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,136,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,144,168,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,133,136,142,143,145,157,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,146,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,147,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,124,125,142,143,148,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,150,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,151,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,136,142,143,152,153,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,152,154,169,171,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,137,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,136,142,143,157,158,160,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,159,160,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,157,158,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,160,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,161,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,122,125,142,143,157,162,168,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,136,142,143,163,164,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,163,164,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,130,142,143,145,157,165,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,166,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,145,167,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,151,168,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,130,142,143,169,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,157,170,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,144,171,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,172,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,118,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,118,125,136,138,142,143,148,157,160,168,170,171,173,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,157,174,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,67,77,125,142,143,176,177,178,180,420,468,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,67,77,125,142,143,176,177,178,179,335,420,468,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,67,77,125,142,143,176,177,179,180,420,468,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,180,335,336,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,180,335,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,67,77,125,142,143,177,178,179,180,420,468,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,67,77,125,142,143,176,178,179,180,420,468,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[61,62,77,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,484,485,486,489,490,493,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,563,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,563,564,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,489,547,548,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,489,547,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,547,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,487,547,551,552,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,487,547,551,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,483,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,487,488,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,487,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,487,488,544,568,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,544,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,487,490,544,545,546,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,718,719],[77,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,718,719,720,721],[77,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,718,720],[77,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,718],[77,125,142,143,680,681,682,683,684,685,686,687,688,689,690,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711],[77,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,536,537,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[69,77,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,423,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,430,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,184,198,199,200,202,417,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,184,223,225,227,228,231,417,419,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,184,188,190,191,192,193,194,406,417,419,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,417,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,199,301,387,396,413,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,184,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,181,413,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,235,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,234,417,419,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,283,301,330,474,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,294,310,396,412,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,348,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,400,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,399,400,401,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,399,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[71,77,125,139,142,143,181,184,188,191,195,196,197,199,203,211,212,341,366,397,417,420,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,184,201,219,223,224,229,230,417,474,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,201,474,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,212,219,281,417,474,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,474,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,184,201,202,474,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,226,474,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,195,398,405,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,151,243,413,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,243,413,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,243,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,302,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,298,346,413,456,457,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,393,450,451,452,453,455,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,392,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,392,393,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,192,342,343,344,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,342,345,346,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,454,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,342,346,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,185,444,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,168,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,201,271,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,201,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,269,273,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,270,422,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,67,77,125,139,142,143,175,176,177,178,179,180,420,466,467,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,188,250,342,352,367,387,402,403,417,418,474,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,211,404,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,420,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,183,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,283,297,309,319,321,412,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,151,283,297,318,319,320,412,473,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,312,313,314,315,316,317,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,314,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,318,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,241,242,243,245,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,236,237,238,244,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,241,244,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,239,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,240,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,243,270,422,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,243,421,422,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,243,422,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,367,409,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,409,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,418,422,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,306,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,124,125,142,143,305,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,213,251,289,291,293,294,295,296,339,342,412,415,418,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,213,327,342,346,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,294,412,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,294,303,304,306,307,308,309,310,311,322,323,324,325,326,328,329,412,413,474,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,288,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,151,213,214,250,265,295,339,340,341,346,367,387,408,417,418,419,420,474,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,412,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,124,125,142,143,199,292,295,341,408,410,411,418,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,294,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,124,125,142,143,250,255,284,285,286,287,288,289,290,291,293,412,413,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,255,256,284,418,419,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,199,341,342,367,408,412,418,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,417,419,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,157,415,418,419,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,151,168,181,188,201,213,214,216,251,252,257,262,265,291,295,342,352,354,357,359,362,363,364,365,366,387,407,408,413,415,417,418,419,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,157,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,184,185,186,188,193,196,201,219,407,415,416,420,422,474,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,157,168,231,233,235,236,237,238,245,474,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,151,168,181,223,233,261,262,263,264,291,342,357,366,367,373,376,377,387,408,413,415,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,195,196,211,341,366,408,417,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,168,185,188,291,371,415,417,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,282,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,374,375,384,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,415,417,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,289,292,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,291,295,407,422,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,151,217,223,264,357,367,373,376,379,415,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,195,211,223,380,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,184,216,382,407,417,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,168,417,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,201,215,216,217,228,246,381,383,407,417,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[71,77,125,142,143,213,295,386,420,422,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,151,168,188,195,203,211,214,251,257,261,262,263,264,265,291,342,354,367,368,370,372,387,407,408,413,414,415,422,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,157,195,373,378,384,415,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,206,207,208,209,210,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,252,358,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,360,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,358,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,360,361,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,188,191,192,250,418,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,151,183,185,213,251,265,295,350,351,387,415,419,420,422,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,151,168,187,192,291,351,414,418,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,284,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,285,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,286,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,413,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,232,248,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,188,232,251,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,247,248,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,249,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,232,233,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,232,266,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,232,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,252,356,414,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,355,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,233,413,414,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,353,414,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,233,413,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,339,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,188,193,251,280,283,289,291,295,297,300,331,334,338,342,386,407,415,418,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,274,277,278,279,298,299,346,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,178,180,243,332,333,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,178,180,243,332,333,337,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,395,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,199,256,294,295,306,310,342,386,388,389,390,391,393,394,397,407,412,417,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,346,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,350,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,251,267,347,349,352,386,415,420,422,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,274,275,276,277,278,279,298,299,346,421,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[71,77,125,139,142,143,151,168,214,232,233,265,291,295,384,385,387,407,408,417,418,420,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,256,258,261,408,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,252,417,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,255,294,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,254,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,256,257,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,253,255,417,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,139,142,143,187,256,258,259,260,417,418,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,342,343,345,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,218,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,185,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,413,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,71,77,125,142,143,265,295,420,422,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,185,444,445,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,273,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,151,168,183,230,268,270,272,422,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,201,413,418,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,369,413,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,342,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,137,139,142,143,151,183,219,225,273,420,421,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,77,125,142,143,176,177,178,179,180,420,468,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,64,65,66,67,77,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,220,221,222,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,220,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[63,67,77,125,139,141,142,143,151,175,176,177,178,179,180,181,183,214,318,379,417,419,422,468,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,432,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,434,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,436,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,438,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,440,441,442,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,446,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[68,70,77,125,142,143,424,429,431,433,435,437,439,443,447,449,459,460,462,472,473,474,475,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,448,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,458,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,270,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,461,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,124,125,142,143,256,258,259,261,309,413,463,464,465,468,469,470,471,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,175,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,531,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,529,531,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,520,528,529,530,532,534,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,518,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,521,526,531,534,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,517,534,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,521,522,525,526,527,534,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,521,522,523,525,526,534,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,518,519,520,521,522,526,527,528,530,531,532,534,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,534,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,516,518,519,520,521,522,523,525,526,527,528,529,530,531,532,533,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,516,534,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,521,523,524,526,527,534,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,525,534,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,526,527,531,534,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,519,529,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,503,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,498,500,503,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,499,500,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,500,503,507,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,499,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,500,503,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,498,499,500,502,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,498,500,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,499,500,509,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,157,175,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,90,94,125,142,143,168,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,90,125,142,143,157,168,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,85,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,87,90,125,142,143,165,168,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,145,165,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,85,125,142,143,175,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,87,90,125,142,143,145,168,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,82,83,86,89,125,136,142,143,157,168,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,90,97,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,82,88,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,90,111,112,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,86,90,125,142,143,160,168,175,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,111,125,142,143,175,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,84,85,125,142,143,175,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,90,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,84,85,86,87,88,89,90,91,92,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,112,113,114,115,116,117,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,90,105,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,90,97,98,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,88,90,98,99,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,89,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,82,85,90,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,90,94,98,99,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,94,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,88,90,93,125,142,143,168,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,82,87,90,97,125,142,143,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,157,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,85,90,111,125,142,143,173,175,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,495,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,136,137,139,140,141,142,143,145,157,165,168,174,175,495,496,497,504,505,506,508,510,512,513,514,515,535,539,540,541,542,543,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,495,496,497,511,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,497,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,538,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,504,514,543,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,504,543,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,570,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,494,575,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,713],[77,125,142,143,484,487,489,490,545,546,547,549,550,553,554,566,567,569,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,713],[77,125,142,143,549,560,561,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,713],[77,125,142,143,549,550,557,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,713],[77,125,142,143,487,489,549,550,553,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,713],[77,125,142,143,512,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,142,143,487,494,549,550,553,562,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,713],[77,125,142,143,543,573,575,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711],[77,125,128,137,142,143,157,487,489,494,543,547,549,550,553,554,557,558,559,562,565,566,567,571,572,575,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,713],[77,125,142,143,512,549,550,553,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,713],[77,125,142,143,549,560,561,562,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,713],[77,125,142,143,512,549,554,555,556,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,713],[77,125,128,137,142,143,157,487,489,494,512,543,547,549,550,553,554,555,556,557,558,559,560,561,562,565,566,567,571,572,573,574,575,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,713],[77,125,142,143,484,487,489,494,512,547,549,550,553,554,555,556,557,558,560,561,562,565,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,713,714,715,716,717,722],[77,125,142,143,487,489,549,550,553,554,560,561,562,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,713,715],[77,125,130,142,143,479,480,638,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,723],[77,125,138,142,143,146,147,621,622,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,723],[77,125,126,138,142,143,146,147,169,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,723],[77,125,142,143,630,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,723],[77,125,142,143,629,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,723],[77,125,142,143,648,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,723],[77,125,142,143,171,678,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,723],[77,125,138,142,143,146,147,621,622,658,659,660,666,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,723],[77,125,142,143,652,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,723],[77,125,142,143,632,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,723],[77,125,126,142,143,168,169,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711,723],[77,125,142,143,576,680,681,682,683,684,685,686,687,688,689,690,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,710,711]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"866b4d0564e00560b9048072e6b784d7da8a092f0e2ca4452ea479bbc0a48bd2","affectsGlobalScope":true},{"version":"7e29f41b158de217f94cb9676bf9cbd0cd9b5a46e1985141ed36e075c52bf6ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac51dd7d31333793807a6abaa5ae168512b6131bd41d9c5b98477fc3b7800f9f","impliedFormat":1},{"version":"bd7dee3446a5b94651d58000ddfda40296f073e9372891f65003a524b4620697","impliedFormat":1},{"version":"acd8fd5090ac73902278889c38336ff3f48af6ba03aa665eb34a75e7ba1dccc4","impliedFormat":1},{"version":"d6258883868fb2680d2ca96bc8b1352cab69874581493e6d52680c5ffecdb6cc","impliedFormat":1},{"version":"1b61d259de5350f8b1e5db06290d31eaebebc6baafd5f79d314b5af9256d7153","impliedFormat":1},{"version":"f258e3960f324a956fc76a3d3d9e964fff2244ff5859dcc6ce5951e5413ca826","impliedFormat":1},{"version":"643f7232d07bf75e15bd8f658f664d6183a0efaca5eb84b48201c7671a266979","impliedFormat":1},{"version":"0f6666b58e9276ac3a38fdc80993d19208442d6027ab885580d93aec76b4ef00","impliedFormat":1},{"version":"05fd364b8ef02fb1e174fbac8b825bdb1e5a36a016997c8e421f5fab0a6da0a0","impliedFormat":1},{"version":"631eff75b0e35d1b1b31081d55209abc43e16b49426546ab5a9b40bdd40b1f60","impliedFormat":1},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"b52476feb4a0cbcb25e5931b930fc73cb6643fb1a5060bf8a3dda0eeae5b4b68","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"13f5c844119c43e51ce777c509267f14d6aaf31eafb2c2b002ca35584cd13b29","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"9855e02d837744303391e5623a531734443a5f8e6e8755e018c41d63ad797db2","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"c906fb15bd2aabc9ed1e3f44eb6a8661199d6c320b3aa196b826121552cb3695","impliedFormat":1},{"version":"22295e8103f1d6d8ea4b5d6211e43421fe4564e34d0dd8e09e520e452d89e659","impliedFormat":1},{"version":"58647d85d0f722a1ce9de50955df60a7489f0593bf1a7015521efe901c06d770","impliedFormat":1},{"version":"73b5fa37db36eeac90c4d752e39586f1b57187400c4f5280fd05f16437287a45","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6f137d651076822d4fe884287e68fd61785a0d3d1fdb250a5059b691fa897db","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"bceb58df66ab8fb00170df20cd813978c5ab84be1d285710c4eb005d8e9d8efb","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"814118df420c4e38fe5ae1b9a3bafb6e9c2aa40838e528cde908381867be6466","impliedFormat":1},{"version":"a3fc63c0d7b031693f665f5494412ba4b551fe644ededccc0ab5922401079c95","impliedFormat":1},{"version":"80523c00b8544a2000ae0143e4a90a00b47f99823eb7926c1e03c494216fc363","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"746911b62b329587939560deb5c036aca48aece03147b021fa680223255d5183","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"c8d3e5a18ba35629954e48c4cc8f11dc88224650067a172685c736b27a34a4dc","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"2b55d426ff2b9087485e52ac4bc7cfafe1dc420fc76dad926cd46526567c501a","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"47613031a5a31510831304405af561b0ffaedb734437c595256bb61a90f9311b","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"8a1a0d0a4a06a8d278947fcb66bf684f117bf147f89b06e50662d79a53be3e9f","affectsGlobalScope":true,"impliedFormat":1},{"version":"358765d5ea8afd285d4fd1532e78b88273f18cb3f87403a9b16fef61ac9fdcfe","impliedFormat":1},{"version":"9f55299850d4f0921e79b6bf344b47c420ce0f507b9dcf593e532b09ea7eeea1","impliedFormat":1},{"version":"2beff543f6e9a9701df88daeee3cdd70a34b4a1c11cb4c734472195a5cb2af54","impliedFormat":1},{"version":"2e07abf27aa06353d46f4448c0bbac73431f6065eef7113128a5cd804d0c384d","impliedFormat":1},{"version":"be1cc4d94ea60cbe567bc29ed479d42587bf1e6cba490f123d329976b0fe4ee5","impliedFormat":1},{"version":"42bc0e1a903408137c3df2b06dfd7e402cdab5bbfa5fcfb871b22ebfdb30bd0b","impliedFormat":1},{"version":"9894dafe342b976d251aac58e616ac6df8db91fb9d98934ff9dd103e9e82578f","impliedFormat":1},{"version":"413df52d4ea14472c2fa5bee62f7a40abd1eb49be0b9722ee01ee4e52e63beb2","impliedFormat":1},{"version":"db6d2d9daad8a6d83f281af12ce4355a20b9a3e71b82b9f57cddcca0a8964a96","impliedFormat":1},{"version":"829b9e6028b29e6a8b1c01ddb713efe59da04d857089298fa79acbdb3cfcfdef","impliedFormat":1},{"version":"24f8562308dd8ba6013120557fa7b44950b619610b2c6cb8784c79f11e3c4f90","impliedFormat":1},{"version":"5f90b8c733a1bda63e42160b15a2301051e83a6f9d5332a59d16eb12f463270d","impliedFormat":1},{"version":"a86f82d646a739041d6702101afa82dcb935c416dd93cbca7fd754fd0282ce1f","impliedFormat":1},{"version":"ad0d1d75d129b1c80f911be438d6b61bfa8703930a8ff2be2f0e1f8a91841c64","impliedFormat":1},{"version":"ce75b1aebb33d510ff28af960a9221410a3eaf7f18fc5f21f9404075fba77256","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"496bbf339f3838c41f164238543e9fe5f1f10659cb30b68903851618464b98ba","impliedFormat":1},{"version":"5178eb4415a172c287c711dc60a619e110c3fd0b7de01ed0627e51a5336aa09c","impliedFormat":1},{"version":"ca6e5264278b53345bc1ce95f42fb0a8b733a09e3d6479c6ccfca55cdc45038c","impliedFormat":1},{"version":"9e2739b32f741859263fdba0244c194ca8e96da49b430377930b8f721d77c000","impliedFormat":1},{"version":"fb1d8e814a3eeb5101ca13515e0548e112bd1ff3fb358ece535b93e94adf5a3a","impliedFormat":1},{"version":"ffa495b17a5ef1d0399586b590bd281056cee6ce3583e34f39926f8dcc6ecdb5","impliedFormat":1},{"version":"98b18458acb46072947aabeeeab1e410f047e0cacc972943059ca5500b0a5e95","impliedFormat":1},{"version":"361e2b13c6765d7f85bb7600b48fde782b90c7c41105b7dab1f6e7871071ba20","impliedFormat":1},{"version":"c86fe861cf1b4c46a0fb7d74dffe596cf679a2e5e8b1456881313170f092e3fa","impliedFormat":1},{"version":"b6db56e4903e9c32e533b78ac85522de734b3d3a8541bf24d256058d464bf04b","impliedFormat":1},{"version":"24daa0366f837d22c94a5c0bad5bf1fd0f6b29e1fae92dc47c3072c3fdb2fbd5","impliedFormat":1},{"version":"570bb5a00836ffad3e4127f6adf581bfc4535737d8ff763a4d6f4cc877e60d98","impliedFormat":1},{"version":"889c00f3d32091841268f0b994beba4dceaa5df7573be12c2c829d7c5fbc232c","impliedFormat":1},{"version":"65f43099ded6073336e697512d9b80f2d4fec3182b7b2316abf712e84104db00","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"acf5a2ac47b59ca07afa9abbd2b31d001bf7448b041927befae2ea5b1951d9f9","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"d71291eff1e19d8762a908ba947e891af44749f3a2cbc5bd2ec4b72f72ea795f","impliedFormat":1},{"version":"c0480e03db4b816dff2682b347c95f2177699525c54e7e6f6aa8ded890b76be7","impliedFormat":1},{"version":"27ab780875bcbb65e09da7496f2ca36288b0c541abaa75c311450a077d54ec15","impliedFormat":1},{"version":"b620391fe8060cf9bedc176a4d01366e6574d7a71e0ac0ab344a4e76576fcbb8","impliedFormat":1},{"version":"380647d8f3b7f852cca6d154a376dbf8ac620a2f12b936594504a8a852e71d2f","impliedFormat":1},{"version":"208c9af9429dd3c76f5927b971263174aaa4bc7621ddec63f163640cbd3c473c","impliedFormat":1},{"version":"6459054aabb306821a043e02b89d54da508e3a6966601a41e71c166e4ea1474f","impliedFormat":1},{"version":"a23185bc5ef590c287c28a91baf280367b50ae4ea40327366ad01f6f4a8edbc5","impliedFormat":1},{"version":"bb37588926aba35c9283fe8d46ebf4e79ffe976343105f5c6d45f282793352b2","impliedFormat":1},{"version":"002eae065e6960458bda3cf695e578b0d1e2785523476f8a9170b103c709cd4f","impliedFormat":1},{"version":"c83bb0c9c5645a46c68356c2f73fdc9de339ce77f7f45a954f560c7e0b8d5ebb","impliedFormat":1},{"version":"05c97cddbaf99978f83d96de2d8af86aded9332592f08ce4a284d72d0952c391","impliedFormat":1},{"version":"72179f9dd22a86deaad4cc3490eb0fe69ee084d503b686985965654013f1391b","impliedFormat":1},{"version":"2e6114a7dd6feeef85b2c80120fdbfb59a5529c0dcc5bfa8447b6996c97a69f5","impliedFormat":1},{"version":"7b6ff760c8a240b40dab6e4419b989f06a5b782f4710d2967e67c695ef3e93c4","impliedFormat":1},{"version":"c8f004e6036aa1c764ad4ec543cf89a5c1893a9535c80ef3f2b653e370de45e6","impliedFormat":1},{"version":"dd80b1e600d00f5c6a6ba23f455b84a7db121219e68f89f10552c54ba46e4dc9","impliedFormat":1},{"version":"b064c36f35de7387d71c599bfcf28875849a1dbc733e82bd26cae3d1cd060521","impliedFormat":1},{"version":"6a148329edecbda07c21098639ef4254ef7869fb25a69f58e5d6a8b7b69d4236","impliedFormat":1},{"version":"8de9fe97fa9e00ec00666fa77ab6e91b35d25af8ca75dabcb01e14ad3299b150","impliedFormat":1},{"version":"f63ab283a1c8f5c79fabe7ca4ef85f9633339c4f0e822fce6a767f9d59282af2","impliedFormat":1},{"version":"dba114fb6a32b355a9cfc26ca2276834d72fe0e94cd2c3494005547025015369","impliedFormat":1},{"version":"a54c996c8870ef1728a2c1fa9b8eaec0bf4a8001cd2583c02dd5869289465b10","impliedFormat":1},{"version":"3e7efde639c6a6c3edb9847b3f61e308bf7a69685b92f665048c45132f51c218","impliedFormat":1},{"version":"df45ca1176e6ac211eae7ddf51336dc075c5314bc5c253651bae639defd5eec5","impliedFormat":1},{"version":"3754982006a3b32c502cff0867ca83584f7a43b1035989ca73603f400de13c96","impliedFormat":1},{"version":"a30ae9bb8a8fa7b90f24b8a0496702063ae4fe75deb27da731ed4a03b2eb6631","impliedFormat":1},{"version":"f974e4a06953682a2c15d5bd5114c0284d5abf8bc0fe4da25cb9159427b70072","impliedFormat":1},{"version":"50256e9c31318487f3752b7ac12ff365c8949953e04568009c8705db802776fb","impliedFormat":1},{"version":"7d73b24e7bf31dfb8a931ca6c4245f6bb0814dfae17e4b60c9e194a631fe5f7b","impliedFormat":1},{"version":"413586add0cfe7369b64979d4ec2ed56c3f771c0667fbde1bf1f10063ede0b08","impliedFormat":1},{"version":"06472528e998d152375ad3bd8ebcb69ff4694fd8d2effaf60a9d9f25a37a097a","impliedFormat":1},{"version":"50b5bc34ce6b12eccb76214b51aadfa56572aa6cc79c2b9455cdbb3d6c76af1d","impliedFormat":1},{"version":"b7e16ef7f646a50991119b205794ebfd3a4d8f8e0f314981ebbe991639023d0e","impliedFormat":1},{"version":"42c169fb8c2d42f4f668c624a9a11e719d5d07dacbebb63cbcf7ef365b0a75b3","impliedFormat":1},{"version":"a401617604fa1f6ce437b81689563dfdc377069e4c58465dbd8d16069aede0a5","impliedFormat":1},{"version":"e9dd71cf12123419c60dab867d44fbee5c358169f99529121eaef277f5c83531","impliedFormat":1},{"version":"5b6a189ba3a0befa1f5d9cb028eb9eec2af2089c32f04ff50e2411f63d70f25d","impliedFormat":1},{"version":"d6e73f8010935b7b4c7487b6fb13ea197cc610f0965b759bec03a561ccf8423a","impliedFormat":1},{"version":"174f3864e398f3f33f9a446a4f403d55a892aa55328cf6686135dfaf9e171657","impliedFormat":1},{"version":"824c76aec8d8c7e65769688cbee102238c0ef421ed6686f41b2a7d8e7e78a931","impliedFormat":1},{"version":"75b868be3463d5a8cfc0d9396f0a3d973b8c297401d00bfb008a42ab16643f13","impliedFormat":1},{"version":"15a234e5031b19c48a69ccc1607522d6e4b50f57d308ecb7fe863d44cd9f9eb3","impliedFormat":1},{"version":"d682336018141807fb602709e2d95a192828fcb8d5ba06dda3833a8ea98f69e3","impliedFormat":1},{"version":"6124e973eab8c52cabf3c07575204efc1784aca6b0a30c79eb85fe240a857efa","impliedFormat":1},{"version":"0d891735a21edc75df51f3eb995e18149e119d1ce22fd40db2b260c5960b914e","impliedFormat":1},{"version":"3b414b99a73171e1c4b7b7714e26b87d6c5cb03d200352da5342ab4088a54c85","impliedFormat":1},{"version":"4fbd3116e00ed3a6410499924b6403cc9367fdca303e34838129b328058ede40","impliedFormat":1},{"version":"b01bd582a6e41457bc56e6f0f9de4cb17f33f5f3843a7cf8210ac9c18472fb0f","impliedFormat":1},{"version":"0a437ae178f999b46b6153d79095b60c42c996bc0458c04955f1c996dc68b971","impliedFormat":1},{"version":"74b2a5e5197bd0f2e0077a1ea7c07455bbea67b87b0869d9786d55104006784f","impliedFormat":1},{"version":"4a7baeb6325920044f66c0f8e5e6f1f52e06e6d87588d837bdf44feb6f35c664","impliedFormat":1},{"version":"6dcf60530c25194a9ee0962230e874ff29d34c59605d8e069a49928759a17e0a","impliedFormat":1},{"version":"7274fbffbd7c9589d8d0ffba68157237afd5cecff1e99881ea3399127e60572f","impliedFormat":1},{"version":"1a42d2ec31a1fe62fdc51591768695ed4a2dc64c01be113e7ff22890bebb5e3f","impliedFormat":1},{"version":"1a82deef4c1d39f6882f28d275cad4c01f907b9b39be9cbc472fcf2cf051e05b","impliedFormat":1},{"version":"c5426dbfc1cf90532f66965a7aa8c1136a78d4d0f96d8180ecbfc11d7722f1a5","impliedFormat":1},{"version":"65a15fc47900787c0bd18b603afb98d33ede930bed1798fc984d5ebb78b26cf9","impliedFormat":1},{"version":"9d202701f6e0744adb6314d03d2eb8fc994798fc83d91b691b75b07626a69801","impliedFormat":1},{"version":"de9d2df7663e64e3a91bf495f315a7577e23ba088f2949d5ce9ec96f44fba37d","impliedFormat":1},{"version":"c7af78a2ea7cb1cd009cfb5bdb48cd0b03dad3b54f6da7aab615c2e9e9d570c5","impliedFormat":1},{"version":"1ee45496b5f8bdee6f7abc233355898e5bf9bd51255db65f5ff7ede617ca0027","impliedFormat":1},{"version":"0c7c947ff881c4274c0800deaa0086971e0bfe51f89a33bd3048eaa3792d4876","affectsGlobalScope":true,"impliedFormat":1},{"version":"db01d18853469bcb5601b9fc9826931cc84cc1a1944b33cad76fd6f1e3d8c544","affectsGlobalScope":true,"impliedFormat":1},{"version":"a8f8e6ab2fa07b45251f403548b78eaf2022f3c2254df3dc186cb2671fe4996d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fa6c12a7c0f6b84d512f200690bfc74819e99efae69e4c95c4cd30f6884c526e","impliedFormat":1},{"version":"f1c32f9ce9c497da4dc215c3bc84b722ea02497d35f9134db3bb40a8d918b92b","impliedFormat":1},{"version":"b73c319af2cc3ef8f6421308a250f328836531ea3761823b4cabbd133047aefa","affectsGlobalScope":true,"impliedFormat":1},{"version":"e433b0337b8106909e7953015e8fa3f2d30797cea27141d1c5b135365bb975a6","impliedFormat":1},{"version":"15b36126e0089bfef173ab61329e8286ce74af5e809d8a72edcafd0cc049057f","impliedFormat":1},{"version":"ddff7fc6edbdc5163a09e22bf8df7bef75f75369ebd7ecea95ba55c4386e2441","impliedFormat":1},{"version":"106c6025f1d99fd468fd8bf6e5bda724e11e5905a4076c5d29790b6c3745e50c","impliedFormat":1},{"version":"a57b1802794433adec9ff3fed12aa79d671faed86c49b09e02e1ac41b4f1d33a","impliedFormat":1},{"version":"ad10d4f0517599cdeca7755b930f148804e3e0e5b5a3847adce0f1f71bbccd74","impliedFormat":1},{"version":"1042064ece5bb47d6aba91648fbe0635c17c600ebdf567588b4ca715602f0a9d","impliedFormat":1},{"version":"c49469a5349b3cc1965710b5b0f98ed6c028686aa8450bcb3796728873eb923e","impliedFormat":1},{"version":"4a889f2c763edb4d55cb624257272ac10d04a1cad2ed2948b10ed4a7fda2a428","impliedFormat":1},{"version":"7bb79aa2fead87d9d56294ef71e056487e848d7b550c9a367523ee5416c44cfa","impliedFormat":1},{"version":"72d63643a657c02d3e51cd99a08b47c9b020a565c55f246907050d3c8a5e77fb","impliedFormat":1},{"version":"1d415445ea58f8033ba199703e55ff7483c52ac6742075b803bd3e7bbe9f5d61","impliedFormat":1},{"version":"d6406c629bb3efc31aedb2de809bef471e475c86c7e67f3ef9b676b5d7e0d6b2","impliedFormat":1},{"version":"27ff4196654e6373c9af16b6165120e2dd2169f9ad6abb5c935af5abd8c7938c","impliedFormat":1},{"version":"71d8ba39a9e024d9e4bb922464d18542ed8d2c25ee78efa7890c27213cc6e5d3","impliedFormat":1},{"version":"8c030e515014c10a2b98f9f48408e3ba18023dfd3f56e3312c6c2f3ae1f55a16","impliedFormat":1},{"version":"dafc31e9e8751f437122eb8582b93d477e002839864410ff782504a12f2a550c","impliedFormat":1},{"version":"754498c5208ce3c5134f6eabd49b25cf5e1a042373515718953581636491f3c3","impliedFormat":1},{"version":"9c82171d836c47486074e4ca8e059735bf97b205e70b196535b5efd40cbe1bc5","impliedFormat":1},{"version":"f56bdc6884648806d34bc66d31cdb787c4718d04105ce2cd88535db214631f82","impliedFormat":1},{"version":"633d58a237f4bb25ec7d565e4ffa32cecdcee8660ac12189c4351c52557cee9e","impliedFormat":1},{"version":"2e4f37ffe8862b14d8e24ae8763daaa8340c0df0b859d9a9733def0eee7562d9","impliedFormat":1},{"version":"13283350547389802aa35d9f2188effaeac805499169a06ef5cd77ce2a0bd63f","impliedFormat":1},{"version":"ce791f6ea807560f08065d1af6014581eeb54a05abd73294777a281b6dfd73c2","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"49f95e989b4632c6c2a578cc0078ee19a5831832d79cc59abecf5160ea71abad","impliedFormat":1},{"version":"9666533332f26e8995e4d6fe472bdeec9f15d405693723e6497bf94120c566c8","impliedFormat":1},{"version":"ce0df82a9ae6f914ba08409d4d883983cc08e6d59eb2df02d8e4d68309e7848b","impliedFormat":1},{"version":"796273b2edc72e78a04e86d7c58ae94d370ab93a0ddf40b1aa85a37a1c29ecd7","impliedFormat":1},{"version":"5df15a69187d737d6d8d066e189ae4f97e41f4d53712a46b2710ff9f8563ec9f","impliedFormat":1},{"version":"e17cd049a1448de4944800399daa4a64c5db8657cc9be7ef46be66e2a2cd0e7c","impliedFormat":1},{"version":"43fa6ea8714e18adc312b30450b13562949ba2f205a1972a459180fa54471018","impliedFormat":1},{"version":"6e89c2c177347d90916bad67714d0fb473f7e37fb3ce912f4ed521fe2892cd0d","impliedFormat":1},{"version":"43ba4f2fa8c698f5c304d21a3ef596741e8e85a810b7c1f9b692653791d8d97a","impliedFormat":1},{"version":"4d4927cbee21750904af7acf940c5e3c491b4d5ebc676530211e389dd375607a","impliedFormat":1},{"version":"72105519d0390262cf0abe84cf41c926ade0ff475d35eb21307b2f94de985778","impliedFormat":1},{"version":"8a97e578a9bc40eb4f1b0ca78f476f2e9154ecbbfd5567ee72943bab37fc156a","impliedFormat":1},{"version":"c857e0aae3f5f444abd791ec81206020fbcc1223e187316677e026d1c1d6fe08","impliedFormat":1},{"version":"ccf6dd45b708fb74ba9ed0f2478d4eb9195c9dfef0ff83a6092fa3cf2ff53b4f","impliedFormat":1},{"version":"2d7db1d73456e8c5075387d4240c29a2a900847f9c1bff106a2e490da8fbd457","impliedFormat":1},{"version":"2b15c805f48e4e970f8ec0b1915f22d13ca6212375e8987663e2ef5f0205e832","impliedFormat":1},{"version":"f22d05663d873ee7a600faf78abb67f3f719d32266803440cf11d5db7ac0cab2","impliedFormat":1},{"version":"d93c544ad20197b3976b0716c6d5cd5994e71165985d31dcab6e1f77feb4b8f2","impliedFormat":1},{"version":"35069c2c417bd7443ae7c7cafd1de02f665bf015479fec998985ffbbf500628c","impliedFormat":1},{"version":"a8b1c79a833ee148251e88a2553d02ce1641d71d2921cce28e79678f3d8b96aa","impliedFormat":1},{"version":"126d4f950d2bba0bd45b3a86c76554d4126c16339e257e6d2fabf8b6bf1ce00c","impliedFormat":1},{"version":"7e0b7f91c5ab6e33f511efc640d36e6f933510b11be24f98836a20a2dc914c2d","impliedFormat":1},{"version":"045b752f44bf9bbdcaffd882424ab0e15cb8d11fa94e1448942e338c8ef19fba","impliedFormat":1},{"version":"2894c56cad581928bb37607810af011764a2f511f575d28c9f4af0f2ef02d1ab","impliedFormat":1},{"version":"0a72186f94215d020cb386f7dca81d7495ab6c17066eb07d0f44a5bf33c1b21a","impliedFormat":1},{"version":"2d3cc2211f352f46ea6b7cf2c751c141ffcdf514d6e7ae7ee20b7b6742da313f","impliedFormat":1},{"version":"c75445151ff8b77d9923191efed7203985b1a9e09eccf4b054e7be864e27923d","impliedFormat":1},{"version":"0aedb02516baf3e66b2c1db9fef50666d6ed257edac0f866ea32f1aa05aa474f","impliedFormat":1},{"version":"fa8a8fbf91ee2a4779496225f0312aac6635b0f21aa09cdafa4283fe32d519c5","affectsGlobalScope":true,"impliedFormat":1},{"version":"0e8aef93d79b000deb6ec336b5645c87de167168e184e84521886f9ecc69a4b5","impliedFormat":1},{"version":"56ccb49443bfb72e5952f7012f0de1a8679f9f75fc93a5c1ac0bafb28725fc5f","impliedFormat":1},{"version":"20fa37b636fdcc1746ea0738f733d0aed17890d1cd7cb1b2f37010222c23f13e","impliedFormat":1},{"version":"d90b9f1520366d713a73bd30c5a9eb0040d0fb6076aff370796bc776fd705943","impliedFormat":1},{"version":"bc03c3c352f689e38c0ddd50c39b1e65d59273991bfc8858a9e3c0ebb79c023b","impliedFormat":1},{"version":"19df3488557c2fc9b4d8f0bac0fd20fb59aa19dec67c81f93813951a81a867f8","affectsGlobalScope":true,"impliedFormat":1},{"version":"b25350193e103ae90423c5418ddb0ad1168dc9c393c9295ef34980b990030617","affectsGlobalScope":true,"impliedFormat":1},{"version":"bef86adb77316505c6b471da1d9b8c9e428867c2566270e8894d4d773a1c4dc2","impliedFormat":1},{"version":"de7052bfee2981443498239a90c04ea5cc07065d5b9bb61b12cb6c84313ad4ef","impliedFormat":1},{"version":"a3e7d932dc9c09daa99141a8e4800fc6c58c625af0d4bbb017773dc36da75426","impliedFormat":1},{"version":"43e96a3d5d1411ab40ba2f61d6a3192e58177bcf3b133a80ad2a16591611726d","impliedFormat":1},{"version":"4a2edd238d9104eac35b60d727f1123de5062f452b70ed8e0366cb36387dfdfd","impliedFormat":1},{"version":"ca921bf56756cb6fe957f6af693a35251b134fb932dc13f3dfff0bb7106f80b4","impliedFormat":1},{"version":"fee92c97f1aa59eb7098a0cc34ff4df7e6b11bae71526aca84359a2575f313d8","impliedFormat":1},{"version":"0bd0297484aacea217d0b76e55452862da3c5d9e33b24430e0719d1161657225","impliedFormat":1},{"version":"2ab6d334bcbf2aff3acfc4fd8c73ecd82b981d3c3aa47b3f3b89281772286904","impliedFormat":1},{"version":"d07cbc787a997d83f7bde3877fec5fb5b12ce8c1b7047eb792996ed9726b4dde","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"4805f6161c2c8cefb8d3b8bd96a080c0fe8dbc9315f6ad2e53238f9a79e528a6","impliedFormat":1},{"version":"b83cb14474fa60c5f3ec660146b97d122f0735627f80d82dd03e8caa39b4388c","impliedFormat":1},{"version":"f374cb24e93e7798c4d9e83ff872fa52d2cdb36306392b840a6ddf46cb925cb6","impliedFormat":1},{"version":"49179c6a23701c642bd99abe30d996919748014848b738d8e85181fc159685ff","impliedFormat":1},{"version":"b73cbf0a72c8800cf8f96a9acfe94f3ad32ca71342a8908b8ae484d61113f647","impliedFormat":1},{"version":"bae6dd176832f6423966647382c0d7ba9e63f8c167522f09a982f086cd4e8b23","impliedFormat":1},{"version":"20865ac316b8893c1a0cc383ccfc1801443fbcc2a7255be166cf90d03fac88c9","impliedFormat":1},{"version":"c9958eb32126a3843deedda8c22fb97024aa5d6dd588b90af2d7f2bfac540f23","impliedFormat":1},{"version":"461d0ad8ae5f2ff981778af912ba71b37a8426a33301daa00f21c6ccb27f8156","impliedFormat":1},{"version":"e927c2c13c4eaf0a7f17e6022eee8519eb29ef42c4c13a31e81a611ab8c95577","impliedFormat":1},{"version":"fcafff163ca5e66d3b87126e756e1b6dfa8c526aa9cd2a2b0a9da837d81bbd72","impliedFormat":1},{"version":"70246ad95ad8a22bdfe806cb5d383a26c0c6e58e7207ab9c431f1cb175aca657","impliedFormat":1},{"version":"f00f3aa5d64ff46e600648b55a79dcd1333458f7a10da2ed594d9f0a44b76d0b","impliedFormat":1},{"version":"772d8d5eb158b6c92412c03228bd9902ccb1457d7a705b8129814a5d1a6308fc","impliedFormat":1},{"version":"45490817629431853543adcb91c0673c25af52a456479588b6486daba34f68bb","impliedFormat":1},{"version":"802e797bcab5663b2c9f63f51bdf67eff7c41bc64c0fd65e6da3e7941359e2f7","impliedFormat":1},{"version":"8b4327413e5af38cd8cb97c59f48c3c866015d5d642f28518e3a891c469f240e","impliedFormat":1},{"version":"8514c62ce38e58457d967e9e73f128eedc1378115f712b9eef7127f7c88f82ae","impliedFormat":1},{"version":"f1289e05358c546a5b664fbb35a27738954ec2cc6eb4137350353099d154fc62","impliedFormat":1},{"version":"4b20fcf10a5413680e39f5666464859fc56b1003e7dfe2405ced82371ebd49b6","impliedFormat":1},{"version":"1d17ba45cfbe77a9c7e0df92f7d95f3eefd49ee23d1104d0548b215be56945ad","impliedFormat":1},{"version":"f7d628893c9fa52ba3ab01bcb5e79191636c4331ee5667ecc6373cbccff8ae12","impliedFormat":1},{"version":"1d879125d1ec570bf04bc1f362fdbe0cb538315c7ac4bcfcdf0c1e9670846aa6","impliedFormat":1},{"version":"bd5f641cc4616eee49497a362c4cb401e9346265bc52670448c4452b4d9be401","impliedFormat":1},{"version":"46273e8c29816125d0d0b56ce9a849cc77f60f9a5ba627447501d214466f0ff3","impliedFormat":1},{"version":"d663134457d8d669ae0df34eabd57028bddc04fc444c4bc04bc5215afc91e1f4","impliedFormat":1},{"version":"e91f7b1344577a02f051b9b471f33044fef8334a76dc9e1de003d17595a5219b","impliedFormat":1},{"version":"3af3584f79c57853028ef9421ec172539e1fe01853296dc05a9d615ade4ffaf6","impliedFormat":1},{"version":"f82579d87701d639ff4e3930a9b24f4ee13ca74221a9a3a792feb47f01881a9c","impliedFormat":1},{"version":"d7e5d5245a8ba34a274717d085174b2c9827722778129b0081fefd341cca8f55","impliedFormat":1},{"version":"d9d32f94056181c31f553b32ce41d0ef75004912e27450738d57efcd2409c324","impliedFormat":1},{"version":"752513f35f6cff294ffe02d6027c41373adf7bfa35e593dbfd53d95c203635ee","impliedFormat":1},{"version":"6c800b281b9e89e69165fd11536195488de3ff53004e55905e6c0059a2d8591e","impliedFormat":1},{"version":"7d4254b4c6c67a29d5e7f65e67d72540480ac2cfb041ca484847f5ae70480b62","impliedFormat":1},{"version":"1a7e2ea171726446850ec72f4d1525d547ff7e86724cc9e7eec509725752a758","impliedFormat":1},{"version":"8c901126d73f09ecdea4785e9a187d1ac4e793e07da308009db04a7283ec2f37","impliedFormat":1},{"version":"c1de754ab5f3b0f4036d6893c74a0fc984c7fcb07936086f19bbe2974406775b","impliedFormat":1},{"version":"aab290b8e4b7c399f2c09b957666fc95335eb4522b2dd9ead1bf0cb64da6d6ee","impliedFormat":1},{"version":"94fe3281392e1015b22f39535878610b4fa6f1388dc8d78746be3bc4e4bb8950","impliedFormat":1},{"version":"2652448ac55a2010a1f71dd141f828b682298d39728f9871e1cdf8696ef443fd","impliedFormat":1},{"version":"06c25ddfc2242bd06c19f66c9eae4c46d937349a267810f89783680a1d7b5259","impliedFormat":1},{"version":"120599fd965257b1f4d0ff794bc696162832d9d8467224f4665f713a3119078b","impliedFormat":1},{"version":"5433f33b0a20300cca35d2f229a7fc20b0e8477c44be2affeb21cb464af60c76","impliedFormat":1},{"version":"db036c56f79186da50af66511d37d9fe77fa6793381927292d17f81f787bb195","impliedFormat":1},{"version":"bd4131091b773973ca5d2326c60b789ab1f5e02d8843b3587effe6e1ea7c9d86","impliedFormat":1},{"version":"c7f6485931085bf010fbaf46880a9b9ec1a285ad9dc8c695a9e936f5a48f34b4","impliedFormat":1},{"version":"14f6b927888a1112d662877a5966b05ac1bf7ed25d6c84386db4c23c95a5363b","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"0427df5c06fafc5fe126d14b9becd24160a288deff40e838bfbd92a35f8d0d00","impliedFormat":1},{"version":"90c54a02432d04e4246c87736e53a6a83084357acfeeba7a489c5422b22f5c7a","impliedFormat":1},{"version":"49c346823ba6d4b12278c12c977fb3a31c06b9ca719015978cb145eb86da1c61","impliedFormat":1},{"version":"bfac6e50eaa7e73bb66b7e052c38fdc8ccfc8dbde2777648642af33cf349f7f1","impliedFormat":1},{"version":"92f7c1a4da7fbfd67a2228d1687d5c2e1faa0ba865a94d3550a3941d7527a45d","impliedFormat":1},{"version":"f53b120213a9289d9a26f5af90c4c686dd71d91487a0aa5451a38366c70dc64b","impliedFormat":1},{"version":"83fe880c090afe485a5c02262c0b7cdd76a299a50c48d9bde02be8e908fb4ae6","impliedFormat":1},{"version":"0a372c2d12a259da78e21b25974d2878502f14d89c6d16b97bd9c5017ab1bc12","impliedFormat":1},{"version":"57d67b72e06059adc5e9454de26bbfe567d412b962a501d263c75c2db430f40e","impliedFormat":1},{"version":"6511e4503cf74c469c60aafd6589e4d14d5eb0a25f9bf043dcbecdf65f261972","impliedFormat":1},{"version":"ec1ca97598eda26b7a5e6c8053623acbd88e43be7c4d29c77ccd57abc4c43999","impliedFormat":1},{"version":"6e2261cd9836b2c25eecb13940d92c024ebed7f8efe23c4b084145cd3a13b8a6","impliedFormat":1},{"version":"a67b87d0281c97dfc1197ef28dfe397fc2c865ccd41f7e32b53f647184cc7307","impliedFormat":1},{"version":"771ffb773f1ddd562492a6b9aaca648192ac3f056f0e1d997678ff97dbb6bf9b","impliedFormat":1},{"version":"232f70c0cf2b432f3a6e56a8dc3417103eb162292a9fd376d51a3a9ea5fbbf6f","impliedFormat":1},{"version":"a47e6d954d22dd9ebb802e7e431b560ed7c581e79fb885e44dc92ed4f60d4c07","impliedFormat":1},{"version":"f019e57d2491c159d47a107fd90219a1734bdd2e25cd8d1db3c8fae5c6b414c4","impliedFormat":1},{"version":"8a0e762ceb20c7e72504feef83d709468a70af4abccb304f32d6b9bac1129b2c","impliedFormat":1},{"version":"d1c9bf292a54312888a77bb19dba5e2503ad803f5393beafd45d78d2f4fe9b48","impliedFormat":1},{"version":"9252d498a77517aab5d8d4b5eb9d71e4b225bbc7123df9713e08181de63180f6","impliedFormat":1},{"version":"cb8d8ef7b9ce8ed3e6f1c814fcbf3f90dab0cb8863079236784fc350746e27c4","impliedFormat":1},{"version":"35e6379c3f7cb27b111ad4c1aa69538fd8e788ab737b8ff7596a1b40e96f4f90","impliedFormat":1},{"version":"1fffe726740f9787f15b532e1dc870af3cd964dbe29e191e76121aa3dd8693f2","impliedFormat":1},{"version":"3be035da7bee86b4c3abf392e0edaa44fc6e45092995eefe36b39118c8a84068","affectsGlobalScope":true,"impliedFormat":1},{"version":"8f828825d077c2fa0ea606649faeb122749273a353daab23924fe674e98ba44c","impliedFormat":1},{"version":"2896c2e673a5d3bd9b4246811f79486a073cbb03950c3d252fba10003c57411a","impliedFormat":1},{"version":"616775f16134fa9d01fc677ad3f76e68c051a056c22ab552c64cc281a9686790","impliedFormat":1},{"version":"65c24a8baa2cca1de069a0ba9fba82a173690f52d7e2d0f1f7542d59d5eb4db0","impliedFormat":1},{"version":"f9fe6af238339a0e5f7563acee3178f51db37f32a2e7c09f85273098cee7ec49","impliedFormat":1},{"version":"407a06ba04eede4074eec470ecba2784cbb3bf4e7de56833b097dd90a2aa0651","impliedFormat":1},{"version":"77e71242e71ebf8528c5802993697878f0533db8f2299b4d36aa015bae08a79c","impliedFormat":1},{"version":"98a787be42bd92f8c2a37d7df5f13e5992da0d967fab794adbb7ee18370f9849","impliedFormat":1},{"version":"5c96bad5f78466785cdad664c056e9e2802d5482ca5f862ed19ba34ffbb7b3a4","impliedFormat":1},{"version":"81d8603ac527e75cfec72bb9391228b58f161c2b33514a9d814c7f3ebd3ef466","impliedFormat":1},{"version":"5f3dc10ae646f375776b4e028d2bed039a93eebbba105694d8b910feebbe8b9c","impliedFormat":1},{"version":"bb0cd7862b72f5eba39909c9889d566e198fcaddf7207c16737d0c2246112678","impliedFormat":1},{"version":"4545c1a1ceca170d5d83452dd7c4994644c35cf676a671412601689d9a62da35","impliedFormat":1},{"version":"320f4091e33548b554d2214ce5fc31c96631b513dffa806e2e3a60766c8c49d9","impliedFormat":1},{"version":"a2d648d333cf67b9aeac5d81a1a379d563a8ffa91ddd61c6179f68de724260ff","impliedFormat":1},{"version":"d90d5f524de38889d1e1dbc2aeef00060d779f8688c02766ddb9ca195e4a713d","impliedFormat":1},{"version":"a3f41ed1b4f2fc3049394b945a68ae4fdefd49fa1739c32f149d32c0545d67f5","impliedFormat":1},{"version":"bad68fd0401eb90fe7da408565c8aee9c7a7021c2577aec92fa1382e8876071a","impliedFormat":1},{"version":"47699512e6d8bebf7be488182427189f999affe3addc1c87c882d36b7f2d0b0e","impliedFormat":1},{"version":"fec01479923e169fb52bd4f668dbeef1d7a7ea6e6d491e15617b46f2cacfa37d","impliedFormat":1},{"version":"8a8fb3097ba52f0ae6530ec6ab34e43e316506eb1d9aa29420a4b1e92a81442d","impliedFormat":1},{"version":"44e09c831fefb6fe59b8e65ad8f68a7ecc0e708d152cfcbe7ba6d6080c31c61e","impliedFormat":1},{"version":"1c0a98de1323051010ce5b958ad47bc1c007f7921973123c999300e2b7b0ecc0","impliedFormat":1},{"version":"4655709c9cb3fd6db2b866cab7c418c40ed9533ce8ea4b66b5f17ec2feea46a9","impliedFormat":1},{"version":"87affad8e2243635d3a191fa72ef896842748d812e973b7510a55c6200b3c2a4","impliedFormat":1},{"version":"ad036a85efcd9e5b4f7dd5c1a7362c8478f9a3b6c3554654ca24a29aa850a9c5","impliedFormat":1},{"version":"fedebeae32c5cdd1a85b4e0504a01996e4a8adf3dfa72876920d3dd6e42978e7","impliedFormat":1},{"version":"3eecb25bb467a948c04874d70452b14ae7edb707660aac17dc053e42f2088b00","impliedFormat":1},{"version":"cdf21eee8007e339b1b9945abf4a7b44930b1d695cc528459e68a3adc39a622e","impliedFormat":1},{"version":"330896c1a2b9693edd617be24fbf9e5895d6e18c7955d6c08f028f272b37314d","impliedFormat":1},{"version":"1d9c0a9a6df4e8f29dc84c25c5aa0bb1da5456ebede7a03e03df08bb8b27bae6","impliedFormat":1},{"version":"84380af21da938a567c65ef95aefb5354f676368ee1a1cbb4cae81604a4c7d17","impliedFormat":1},{"version":"1af3e1f2a5d1332e136f8b0b95c0e6c0a02aaabd5092b36b64f3042a03debf28","impliedFormat":1},{"version":"30d8da250766efa99490fc02801047c2c6d72dd0da1bba6581c7e80d1d8842a4","impliedFormat":1},{"version":"03566202f5553bd2d9de22dfab0c61aa163cabb64f0223c08431fb3fc8f70280","impliedFormat":1},{"version":"5f0292a40df210ab94b9fb44c8b775c51e96777e14e073900e392b295ca1061b","impliedFormat":1},{"version":"bc9ee0192f056b3d5527bcd78dc3f9e527a9ba2bdc0a2c296fbc9027147df4b2","impliedFormat":1},{"version":"8627ad129bcf56e82adff0ab5951627c993937aa99f5949c33240d690088b803","impliedFormat":1},{"version":"1de80059b8078ea5749941c9f863aa970b4735bdbb003be4925c853a8b6b4450","impliedFormat":1},{"version":"1d079c37fa53e3c21ed3fa214a27507bda9991f2a41458705b19ed8c2b61173d","impliedFormat":1},{"version":"5bf5c7a44e779790d1eb54c234b668b15e34affa95e78eada73e5757f61ed76a","impliedFormat":1},{"version":"5835a6e0d7cd2738e56b671af0e561e7c1b4fb77751383672f4b009f4e161d70","impliedFormat":1},{"version":"5c634644d45a1b6bc7b05e71e05e52ec04f3d73d9ac85d5927f647a5f965181a","impliedFormat":1},{"version":"4b7f74b772140395e7af67c4841be1ab867c11b3b82a51b1aeb692822b76c872","impliedFormat":1},{"version":"27be6622e2922a1b412eb057faa854831b95db9db5035c3f6d4b677b902ab3b7","impliedFormat":1},{"version":"a68d4b3182e8d776cdede7ac9630c209a7bfbb59191f99a52479151816ef9f9e","impliedFormat":99},{"version":"39644b343e4e3d748344af8182111e3bbc594930fff0170256567e13bbdbebb0","impliedFormat":99},{"version":"ed7fd5160b47b0de3b1571c5c5578e8e7e3314e33ae0b8ea85a895774ee64749","impliedFormat":99},{"version":"63a7595a5015e65262557f883463f934904959da563b4f788306f699411e9bac","impliedFormat":1},{"version":"ecbaf0da125974be39c0aac869e403f72f033a4e7fd0d8cd821a8349b4159628","impliedFormat":1},{"version":"4ba137d6553965703b6b55fd2000b4e07ba365f8caeb0359162ad7247f9707a6","impliedFormat":1},{"version":"ceec3c81b2d81f5e3b855d9367c1d4c664ab5046dff8fd56552df015b7ccbe8f","affectsGlobalScope":true,"impliedFormat":1},{"version":"8fac4a15690b27612d8474fb2fc7cc00388df52d169791b78d1a3645d60b4c8b","affectsGlobalScope":true,"impliedFormat":1},{"version":"064ac1c2ac4b2867c2ceaa74bbdce0cb6a4c16e7c31a6497097159c18f74aa7c","impliedFormat":1},{"version":"3dc14e1ab45e497e5d5e4295271d54ff689aeae00b4277979fdd10fa563540ae","impliedFormat":1},{"version":"1d63055b690a582006435ddd3aa9c03aac16a696fac77ce2ed808f3e5a06efab","impliedFormat":1},{"version":"b789bf89eb19c777ed1e956dbad0925ca795701552d22e68fd130a032008b9f9","impliedFormat":1},"f4e8976c19fc926644d72610bf1058bd6bf52add97e46a02bc0b912a751625c0","22a573b4317573e346cca406719e7179d6ca78fe4cec1e4c8ba0ed55327b7696","9410765c9158e5d404dccc6b1ceec7e568c15ee3f546ab619db2ee9c73a7f308","064c8a503fe2259444ae577997cc714ccd50e84d45745c409411e30c5f3688b7","895f631ff461f5a2384d4e39ec1d9c7f7dbb4159fe68bcce62fc3fd0d08e64b6",{"version":"c76c02846ba7d40b9b3488f0e8d75d02cbdee2f0bc5fcd55dd3bd2e1457646ea","impliedFormat":99},{"version":"4ead13a482c539b77394b2a97e3b877b809eac596390371cea490286f53b996a","impliedFormat":99},{"version":"06db2f8ba1d1dfacf04529cb731081ab23f133f29c7608ebdfbcab356996827c","impliedFormat":99},{"version":"bdd14f07b4eca0b4b5203b85b8dbc4d084c749fa590bee5ea613e1641dcd3b29","impliedFormat":99},{"version":"3a582c6e8906f5b094ccf0de6cc6f4f8a54b05a34f52517aba5c9c7f704f6b28","impliedFormat":99},{"version":"ef13c73d6157a32933c612d476c1524dd674cf5b9a88571d7d6a0d147544d529","impliedFormat":99},{"version":"49ab4f1d153a252779958fc87b700743d32b5ffa42addd70ae23ad3f429daa5c","impliedFormat":99},{"version":"0528f6d21f7a02d4092895090d2dd86104bd5a3e79eced96d5a1a7dd90943d17","impliedFormat":99},{"version":"427fe2004642504828c1476d0af4270e6ad4db6de78c0b5da3e4c5ca95052a99","impliedFormat":1},{"version":"2eeffcee5c1661ddca53353929558037b8cf305ffb86a803512982f99bcab50d","impliedFormat":99},{"version":"9afb4cb864d297e4092a79ee2871b5d3143ea14153f62ef0bb04ede25f432030","affectsGlobalScope":true,"impliedFormat":99},{"version":"5c935b7fc4ddc1410ea1cd7cd4e35ed106a6e4920dd27a9480a40fd224359dc3","affectsGlobalScope":true,"impliedFormat":99},{"version":"3b89216a7e38a454985ad17bb2ff85792837dc812f2a89fa5f60ad0a2e216fa7","impliedFormat":99},{"version":"16fe60bb544cfedfd2b5bb2f7d0b3957be7978706d57d9f06edc9c0c8dbdba23","impliedFormat":99},{"version":"de4a612aa8f1704af486f701e21993c786ba7d8cfed55fffa6684026aea2346e","impliedFormat":99},{"version":"c73fdf42528325dd17940937ed787b15ae3445c6a2dae1a2b74bc4d87d337ca2","impliedFormat":99},{"version":"e8e17dfef3cfa9f0847ac93dd535a9896af7fb57c1a1b164484bb1b0ee4a25d8","impliedFormat":99},{"version":"7f2bb8f9aba83e5f5952cf362e405452e02ff420667434021e9a8be095b15fc1","impliedFormat":99},{"version":"638a22f8e16b31c37297483fa38cfc760ed309b16d4c606a7b4532f4394c9c0c","impliedFormat":99},{"version":"9394183f4c37b8591156f32e41223c9e0dd211eefe7499155d4cdf15268eaea8","impliedFormat":99},{"version":"cb9b6d9e3f32decbd816ffb20a392fe774ba7a2bd615b5c22ce645312f703ef0","impliedFormat":99},{"version":"b333e679ec61ac6bc9e696bf9adac47b20701568697f1a0e2a05674f97e02f5d","impliedFormat":99},{"version":"ac7293557679952437466a41e6e8a47614cb99a51d0440fc36ac7aa02d44ab93","impliedFormat":99},{"version":"7d3e062a778b8f5ea4f0cac7e925e31f88e6739812ebc5f827474324a4048f14","impliedFormat":99},{"version":"be030f8dc45fded610c82e51642b195a3dc80fa0ec63e1b822425050e1b04743","impliedFormat":99},{"version":"8c1fb5394cc1cf2943fa7a294632a4a24eb4fbd4a68aee00131dc93c02d2de09","impliedFormat":99},{"version":"f232e7548dd00bc8631f61bf8b0259288a3b68a21023f1f177427c05d905446b","impliedFormat":99},{"version":"2dca43f25e917d7f01f2963e665852c92ca18b2f939694cbfdc87c503210c0a6","impliedFormat":99},{"version":"4e003c868b0d8f8ad200b96cbc653e18e513fa23e1c19c4fe3cc25d4394efc47","impliedFormat":99},{"version":"8887e70871f697fa42ad7cdf32168db60ec2d6760c173c97973e35377fe5d83b","impliedFormat":99},{"version":"e0864480ea083087d705f9405bd6bf59b795e8474c3447f0d6413b2bce535a09","impliedFormat":99},{"version":"e67cbea16f1994af89efd700542dbf3828a46a52b29e4d67e801bd7869dc103c","impliedFormat":99},{"version":"f582b0fcbf1eea9b318ab92fb89ea9ab2ebb84f9b60af89328a91155e1afce72","impliedFormat":99},{"version":"402e5c534fb2b85fa771170595db3ac0dd532112c8fa44fc23f233bc6967488b","impliedFormat":1},{"version":"52dcc257df5119fb66d864625112ce5033ac51a4c2afe376a0b299d2f7f76e4a","impliedFormat":1},{"version":"e5bab5f871ef708d52d47b3e5d0aa72a08ee7a152f33931d9a60809711a2a9a3","impliedFormat":1},{"version":"e16dc2a81595736024a206c7d5c8a39bfe2e6039208ef29981d0d95434ba8fcf","impliedFormat":1},{"version":"cc4a4903fb698ca1d961d4c10dce658aa3a479faf40509d526f122b044eaf6a4","impliedFormat":1},{"version":"19ee8416e6473ed6c7adb868fa796b5653cf0fa2a337658e677eaa0d134388c3","impliedFormat":1},{"version":"1328ab4e442614b28cdb3d4b414cf68325c0da0dca07287a338d0654b7a00261","impliedFormat":1},{"version":"a039dc21f045919f3cbee2ec13812cc6cc3eebc99dae4be00973230f468d19a6","impliedFormat":1},{"version":"3fbe57af01460e49dcd29df55d6931e1672bc6f1be0fb073d11410bc16f9037d","impliedFormat":1},{"version":"f760be449e8562ec5c09bb5187e8e1eabf3c113c0c58cddda53ef8c69f3e2131","impliedFormat":1},{"version":"44325ed13294fce6ab825b82947bbeed2611db7dad9d9135260192f375e5a189","impliedFormat":1},{"version":"e392e8fb5b514eafc585601c1d781485aa6dd6a320e75daf1064a4c6918a1b45","impliedFormat":1},{"version":"46e4a36e8ddbdfb4e7330e11c81c970dc8b218611df9183d39c41c5f8c653b55","impliedFormat":1},{"version":"370bde134aa8c2abc926d0e99d3a4d5d5dba65c6ee65459137e4f02670cbf841","impliedFormat":1},{"version":"6332f565867cf4a740a70e30f31cefba37ef7cebcf74f22eab8d744fde6d193e","impliedFormat":1},{"version":"2977b7884aedc895a1d0c9c210c7cf3272c29d6959a08a6fa3ff71e0aff08175","impliedFormat":1},{"version":"17f2922d41ddd032830a91371c948cd9ce903b35c95adca72271a54584f19b0b","impliedFormat":1},{"version":"3eed76ede2a1a14d7c9bb0a642041282dcc264811139d3dd275c9fe14efc9840","impliedFormat":1},{"version":"e3cf0611709328b449ec13f8c436712d62003620ce480139fae46ce001c2ee9f","impliedFormat":1},{"version":"8d369483f0c2b9ee388129cfdb6a43bc8112b377e86a41884bd06e19ce04f4c1","impliedFormat":99},{"version":"3fd8a5aefd8c3feb3936ca66f5aa89dff7bf6e6537b4158dbd0f6e0d65ed3b9e","impliedFormat":1},{"version":"a18642ddf216f162052a16cba0944892c4c4c977d3306a87cb673d46abbb0cbf","impliedFormat":1},{"version":"41c41c6e90133bb2a14f7561f29944771886e5535945b2b372e2f6ed6987746e","impliedFormat":1},{"version":"4ec16d7a4e366c06a4573d299e15fe6207fc080f41beac5da06f4af33ea9761e","impliedFormat":99},{"version":"960bd764c62ac43edc24eaa2af958a4b4f1fa5d27df5237e176d0143b36a39c6","affectsGlobalScope":true,"impliedFormat":99},{"version":"c765b3bfab230cec7c051c6d90880270d3846746a186d2d02729fc7b10abf5a2","impliedFormat":99},{"version":"59f8dc89b9e724a6a667f52cdf4b90b6816ae6c9842ce176d38fcc973669009e","affectsGlobalScope":true,"impliedFormat":99},{"version":"a29a1d34dc79bdd96b6f8a9bf529199f8811b3d22f0c8be12c28c9898f9b383a","impliedFormat":99},{"version":"b5ce343886d23392be9c8280e9f24a87f1d7d3667f6672c2fe4aa61fa4ece7d4","impliedFormat":99},{"version":"72ce5b734c05da85c85a6f6dc05823b051d6aa41acaedeeb1d17c72f3b4efa72","impliedFormat":99},{"version":"b0857bb28fd5236ace84280f79a25093f919fd0eff13e47cc26ea03de60a7294","impliedFormat":99},{"version":"5e43e0824f10cd8c48e7a8c5c673638488925a12c31f0f9e0957965c290eb14c","impliedFormat":99},{"version":"53cf4076f42b29b8d411259d168d51b3a0274c42c8814e5b44dfa8803a35d4fc","impliedFormat":99},{"version":"a39461ee1f27cf3e6cfd63d21045713d26d521da55ea4d8efccb705f689e6dbb","impliedFormat":99},{"version":"61bb64660ee150f3ab618340e15cca0a81664801bede7c966ca0eca3a952fe63","impliedFormat":99},{"version":"42a12f2faa483c9b48195ed794d22698162274e755f6e07219c2351c4f08d732","impliedFormat":99},{"version":"ec0c42bb0f465e4993f2bc68a6ce9df9a2dcbc7b83e21748f82f1b69561938e3","impliedFormat":99},{"version":"f50ff37a9cbbe74475f426474d9827083c7c2c138a954d28f1690df338f69291","impliedFormat":99},{"version":"61fd6c17235d530c40f543dd7c40afab091d91c1ef890baeed30db6d82b04b28","impliedFormat":99},{"version":"bcbd3becd08b4515225880abea0dbfbbf0d1181ce3af8f18f72f61edbe4febfb","impliedFormat":99},{"version":"091767bc841f937654ed597d49e023ed59850355e746ae1a6f20ab31076ee1fb","impliedFormat":99},{"version":"19c6d6135af59693698d384050b45a8a049493500add442f58e4bd7c8a255ab6","impliedFormat":99},{"version":"6a0dba12d55314638a8c51108b20fe2f68f1364a619d098918bda91c22dec154","impliedFormat":99},{"version":"8124828a11be7db984fcdab052fd4ff756b18edcfa8d71118b55388176210923","impliedFormat":99},{"version":"2b39c6cf59088713babbfc3e20ee85f1375d40e66953156fa658346b8346f24f","impliedFormat":99},{"version":"69bf2422313487956e4dacf049f30cb91b34968912058d244cb19e4baa24da97","impliedFormat":99},{"version":"6987dfb4b0c4e02112cc4e548e7a77b3d9ddfeffa8c8a2db13ceac361a4567d9","impliedFormat":99},{"version":"5e2ba3d18d78aebbde1f34bde356e41e9c76eeaeaeee56a37036596a9eff4211","impliedFormat":99},{"version":"8280ae8ccc0493b32d1742d585357ab9f0a508ea050af25a5a20d64010d0a5cf","impliedFormat":99},{"version":"7adfd9f9056ecd4ae6c65fde2a98654960c662714c73f048478959d04c09e144","impliedFormat":99},{"version":"437b7613a30a2fcde463f7b707c6d5567a8823fbc51de50b8641bf5b1d126fad","impliedFormat":99},{"version":"63ea959e28c110923f495576e614fb8b36c09b6828b467b2c7cd7f03b03ccf9f","impliedFormat":99},{"version":"1601a95dbb33059fc3d12638ed2a9aecff899e339c5c0f3a0b28768866d385b4","impliedFormat":99},{"version":"56fc978580577d30f4c2cdb5b1eb9217b66ed66537dd27141256f426e4b8dd68","impliedFormat":99},{"version":"2c5413050a2580becf9d82dd7e3006b95623e96f145356bf73230cd635352f70","impliedFormat":99},{"version":"860bedc71ead192ea4a0ea5ef4686e65724d14b391ebd1a6671a7044e6bd8e15","impliedFormat":99},{"version":"7c0a845bee4a084cbb8654709f48e5f13e2f6d45e5e2dde7c57cadf79fd9e3d5","impliedFormat":99},{"version":"a9c8214ef27f5762c807802fd468b50fafae5c909d4376b67b3bfccaf8f99e13","impliedFormat":99},{"version":"94c8f4fa20a287054630c9521a9c5c7e8f74e806bcc8444503b6dc378853dd09","impliedFormat":99},{"version":"174e5bf2d8c80c676eb42959eaac341892bd946f18b68d2f5efe99a38b152fb3","impliedFormat":99},{"version":"7bbff6783e96c691a41a7cf12dd5486b8166a01b0c57d071dbcfca55c9525ec4","impliedFormat":99},"c9627d462e83c813fcabd7f8ed80cdc5cf283a72b9ac175baeb89c8091930202",{"version":"5a6237f90ea7b312ce8e331ad5ab88661ca01c64aad1fdfa4d8a9f2f64caf57d","impliedFormat":1},{"version":"67bd7f459d684b496170f8c6d48d309a4c94bc726b127e7c1704234c0d5c5f46","impliedFormat":1},{"version":"a3628f430f8d502a5c026a0c932a5c41e6361d8e0248287872cd8999bc534399","impliedFormat":1},{"version":"5244034d59b188756ec9bc13ce72e04c89cbc9cbd2b6c6dc3b1412c7cc0e1957","impliedFormat":99},{"version":"0deff63aaf571504405cb4be9de0bf0b445056d063d27d8ce9ab5a85da09d8c8","impliedFormat":1},{"version":"2b6c6039f4d2f656904d66f82231488f4852f861d27147884895097f74e3e812","impliedFormat":1},{"version":"cc6c527d304da87b8873bcf1cf9a47a12fe1630abaf5cbb2c60cbabd8e85e4c2","impliedFormat":1},{"version":"8d14d903616d2aad418dd902e2a7be61e8ba7b80b9ba33b2b1257bb79e961ca2","impliedFormat":1},{"version":"941959cd493fe9e8780f8a704791c83ffff2499447622f7ee63acc7bf08be0f9","impliedFormat":1},{"version":"1fcc4bb6d083b31e1587711ab5a8b0467b52a125f9735467774285bc8cc127e6","impliedFormat":1},{"version":"c938244bbaf0fe8eedb23df3f0da99dc945635043313cfeb0044eead923da54f","impliedFormat":1},{"version":"0e085cc503ad1332728d56244e9f7a603404beca17c0c5b2d815ed29e0727d4b","impliedFormat":1},{"version":"deda38d3245acb0404dd845dae172547c895c99c442082f176071cbb40d092f3","impliedFormat":1},{"version":"2776f7230a2ae50a27bc595893d0fcd8943869a8a3aaff99a2e3f86aafe54bdb","impliedFormat":1},{"version":"585951f20abc465c5acb3674fe5bad232c299f00d073d90c8cb1a416c807d41e","impliedFormat":1},{"version":"e6f3d02d69394dae0771c088b3c0b982cf15b6a91678c59f1d5fbd7c5e6ad8f8","impliedFormat":1},{"version":"ef182902b33ac9b9ad90c163b313722d2bc9d8c2cfefeb418b3205d70504a486","impliedFormat":1},{"version":"9e186460be8b3215058dbbb969c1726412ab117a08ab6ac6666835813dc36596","impliedFormat":1},{"version":"95bdd836ed77c23e530fcd3a0823df8fd611035590dfd8d38ee164c56f2bd2c4","impliedFormat":1},{"version":"059a18ce7a1e33c1b4b7796f72549bdd98d27f43f82f27fb336392281253d236","impliedFormat":1},{"version":"e689e94b2f63be1124a32f5dfe4a6951aa0d39efb2bae9a635539780ed6f8c82","impliedFormat":1},{"version":"c0e42e780d502d530ce67e30d09a3b81c5d37d500c1f7ef04f4bd806f648b96a","impliedFormat":1},{"version":"447b6a80636a59c918ed18af1019de1efa94109a086e8fd8f3d20eb9b9a6937b","impliedFormat":99},{"version":"54c77a931485f321c64d17523b3a9cb111c31d07d4ae735a10a2dc9b25e78ebd","impliedFormat":99},{"version":"05c9c065eadecdce0ee370455e3c36674bfb08673f1a268a398002a0d2d801b7","impliedFormat":1},{"version":"b0df6363b53f0b84a98f6e8ebaebd773bcc46f77d4b61af4574c7508c40f6c04","impliedFormat":1},{"version":"0eae63800777384563d5727e572982c220d47acf736dcdb569a2749a32378f19","impliedFormat":1},{"version":"9bf41a89bd0bbd4f8a23a7925d04f99267cb84a5a5b239185f3320edea329b9c","impliedFormat":1},{"version":"c8699f2b983bbc3117260c84d2f9f11c83eb2b396ea881a69d4cf10ac73a339f","impliedFormat":1},{"version":"b688a3daef72eae05635460146810781dab458476b855c4366371e17f1a0b546","impliedFormat":1},{"version":"eeb074610693bf33314fe67fa4b82f6bd26cdd54851d5aa79b98adc3a9090fea","impliedFormat":1},{"version":"964de3d129316ff79eccce67973270c01d0ed9c61947535ff8f35509a46fe536","impliedFormat":1},{"version":"e444a4edd02caac4c129adb1033df87601f443a38b3b505ab368da6b9c5c5560","impliedFormat":1},{"version":"626f96ecbe3b0ca52fe06b6d16b03520f51dfbc479ad1c2756f5f2eabfd78f48","impliedFormat":1},{"version":"170decb46fc69c7e82174fe44f308115628d033f11ee51c9d554f5ca735353f3","impliedFormat":1},{"version":"edfc95c78a5568c8d0db613579f93c1ed5766e82ed75c6f06d6a44fbbb492d14","impliedFormat":1},{"version":"4ae9b50481136302de9c77668621ed3a0b34998f3e091ca3701426f4fe369c8a","impliedFormat":1},{"version":"9ba9ecc57d2f52b3ed3ac229636ee9a36e92e18b80eeae11ffb546c12e56d5e5","impliedFormat":1},{"version":"17644c49b3a6c1907a292b491472a609f342d069c660043b96e398574e34b6a7","impliedFormat":1},{"version":"d182d419bb30a1408784ed95fbabd973dde7517641e04525f0ce761df5d193a5","impliedFormat":1},{"version":"1bc7e6c2be453958a63abf49f3021e2e68de535fbb293f2eb9d616ed1e6caa47","impliedFormat":99},"52a13d3eb975d611985880e3aa513f9cabb6d77e406cb338c8b2cb1a7ad53300","607703d777cc58309a24619eeb6fea42a35418050298f10656e6fa4180ecf667","6ee1b9dfb2e92c601854a070fb3b6cbba243ddd69b1e93fe819cef36cd537358","4270c88e16a1a8c82313d2c00cf48e3391d6cc45837e885246d74133e7f2c419","c29aef83588c47d1a221649054fbe48eccb288aeb757b8210d35de2062c34091","52132fb8543f5b30dc73c84c9d859f47235828e04273fc9d736fa2f634dff63e","3c29ee63cd68ed64b1dc8e7d7d5d9d4650b7d20d25b8d03a8673fd4ef8ec3b95","88b20e6856bb9a6503e215985e58e7ae86201c3406008f653f020d84551b98ff","860376c3d9f121d1d87847c41ecfa2ac32fa1ccfe8f4db64015ca21e0c08194c","5ab7342c9726a5a4e5478a455ac577f59111e53509709dd935ef3d1ef9cea99a","9594c2340f9e1938e6b716b16a70d823616517e3acb74639d1c678436a7d89e0","9ad8703b85341c13e4ef2bbfda15690bba66851bfe90dcb75ebfc4bf07b042cc","a6857b7bd69c561c11c5f573772359f7cb28806727d5d4d3c39676968443de5d","5b225585d541979495388cd097241c9108133175d56470cb1cb48455e05c31b6","bc4f53f6058f0ec00ba347c5dfe7a969285330a80ecd7e7b3e421c2e73d59888","92d5962ecd3ca1ac8bedad019a5c76f165c815dd79ec3e55c6b4fa095aacf505","05241b004f09a311388c8c3773c066ebbfd8378742e80e2b1b7290ccd7029144","8003926d946077bc5aa194e528661df5d4100568caed912bcbe4522b5e723556","2fa1062cfc6cd368fe485a7d7a84531fcdb68434e3513182834ce6fa6c26fd62","7f18336684f6a531af1c4550ab087731283e45a1242baef0da91ee061c858f56","8dd80e3a82b37c014afb6c4eb4214d18d6a6af63832950b6d10274292b411488","abc0a165e28dc51750d75f04a85954663357bc599a2dbf5bc8cb0bb97b1547bb","24f4eca8e25e5cac7373da19b9d006ae2d7207012ff47853e12c9995b6558a08","6f176b90281a49f858e4e9affffc440d147684c5c6dd782e4d1d6d4e14d873af","95b07309f30e8453e04a88e3776c7a48efc8b473fe3904935b46e8040ddee3a7","6fb24261a8542879dd2814c67988e2c6fb56e66e05166b86ebbbfd5e0e3368be","980fd9c30d12b5f0734b53b012536e4528c3dcf094426ec38668d354ab7b62bc","bdea2634236000d0b728a60a1b3b73fcd95892b825c32619ae4ae64e80ec7b76","efd3c467844efdc63f5e46512b2a8ba2d06adef01cae61bc93e24c6fee569545","05132d0d9f65c23b618c6bd8d1cee059b952cbb0891739706791a03b28a6beef","a794db618079dcb91d5e96afe9bd90ffc5fcefbf99179fb394c7029c6f42f91f","b6d3b8b16a539748c29e8d4c0677ba9f5c6cc9fee5edc5c6cede81e976fbbb39","59f27a9b00981a14e2dfaa1e9e61e8f7866262a213de033b118241d4e2d92a5d","aee9694e8f6ef273dfb2b669a76814de00067f66d4d135715b17f152312b5254","1bcfbbced6a924d6996d401fdfb919fd5bc90558890f3d1008deee6a9078bd01","878d6d91780d9615310379ef13fe793abc927b7989522c2e8005fca574484eb3","ecbbd68a0596329fac348b34074195c73dc3409a39728df53912037a6e1b7678","ef41a8f6117608c2aa8b043cdf2f1dc26cc44eab20baad42f9cb01daf78795eb","3cb40d31b61d7997c946beb73eb7e5054c95d36df6b03e735da53c5ba234989e","4a31006753b9936cc0d083fd66c7795880bdd94c486830b3a7dfbcfef26be4e7","8a0dafd83020740c23687c3645d98905c9f30f615ad612901deee39ca64acd00","95d7a443298b431fd7551f06eab2fe9f4cb56db865cd1e154bfea9c19ea276e8","a1bed48ea6adeadc93e88772feacd2bbef6cd88e4a282a53a33affe68bb403ac","c5800147cfcca5905133b304ba5f651678552b691b75ccfa9b51ee3a909a8c29","41ce3aadf1c6c3aaace6ecf51de5eec60c25adb7aec4808bba5c41755cd41179","5027eef57c706fd125902492af33473e482e67e6ed41023ad827312867b81266","61e395ebe04573fbda2fdd67491ab520792fedab79995d0fb20519709da02b76","b1bd9455ecfed06eff4d3e2bf9a0ad1c48c6cfb3dbea5b7d479c4826d503f71e","7784f7cdaa0dd11ea3e4948afec59a923eb54424c6f3ba5dea1340cf903ddf72","83ad223cd3c255be8894fd3ee831fec1a0e963feee55209623451ebd1dd1f2f8","9518c16070ee808b67b93d76b3ed2b1369d27a3b4732ee3bc9a7d34e4fc6bdc4","8860d449ff7e05d50d60516a6efcda1be60a5d680568a09a16d97e3020ea74d5","2f2a0bcf44120447bf26048c643e46b2632a0e72dd99b08961d197b06836b375","0ce5f58e7c90884770c434742fb17ee0727dbb7550cdfdcdd93652f7bc25daf0","e33f99ce2e3f429f7354476db22c7cce623eabc303fac8059548bb5f435b1ac5","03b8a6b6b4f8bf4fbdcb7e7bf8f1800bd77ba1c8e9353c309c76fba085ea12b8","f10d32d6a8cc4c1c7a7711a017fe768bd7361770462a419f5bc5256eb69638be","d56118f01d431e3ec7370e0de9825e6088a7fd6a37e9bc46be6e684f194e9e80","5a31e6c2fe503818e265106e2490e6ec7de3af082491f3fd07376e2945b65b07","9f2ab61c10dd8e78499dc95c938243c2471d1b78107f5ba240bbb5a923159bc4",{"version":"0e98bdca6b2f656ff783eccb891ad5b18b5e39d36a231b94bb407f46185a035f","affectsGlobalScope":true,"impliedFormat":1},{"version":"2b8241ee9d522539245316c7d9efba3a7f7fb67e89edb6b8375841c5204323c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"6dc855128df7aa80c5d937b26d853ec76375b9be022c8476735a82bcb205b582","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e38adf1d08fed1932323468c084f22f3b0ff96da903c213a52dce96e7c5314c","affectsGlobalScope":true,"impliedFormat":1},{"version":"033cc8d0cf4529bc62746a9a026e43454f06f86d560b533e2726e677caf43c5f","affectsGlobalScope":true,"impliedFormat":1},{"version":"56ed2fc77c5587ed572b52c0c679ab284a84254875628d39d63a1ad84aa47993","affectsGlobalScope":true,"impliedFormat":1},{"version":"da04a353ae1f194880392596c1c65bd16039d7cb7d8c95394c8cc833bbeb5600","affectsGlobalScope":true,"impliedFormat":1},{"version":"7f0b457714a6a7dc40d51506cf9e5ab38aec893d78d10dc853d51e4ece6c8a86","affectsGlobalScope":true,"impliedFormat":1},{"version":"42dc1c1fb9a082bfc981edb18b50e12f7fda5009a15468ef6e6f939e86300fbd","affectsGlobalScope":true,"impliedFormat":1},{"version":"4b36ac8539e453915ead7ddf25653d6a7691e6dac52003372c12244965480df2","affectsGlobalScope":true,"impliedFormat":1},{"version":"b98109e756e7e1adf0f305b3f1e9d65a40da0c71ec6d23ffddd9c0ea75cb312a","affectsGlobalScope":true,"impliedFormat":1},{"version":"b3bee285d6a28772aba2633b6bcd9cd53a517f7a4862cf7893197222e73cfddc","affectsGlobalScope":true,"impliedFormat":1},{"version":"122c612162cb2e09d70ebdd670941441e902a26ee79b37f006c5b9d38868ed32","affectsGlobalScope":true,"impliedFormat":1},{"version":"28d03f63a7a5931c8225059693c41a102b52b8e39ca2a034bca11df726d06fda","affectsGlobalScope":true,"impliedFormat":1},{"version":"07cc2729a92e8293f16fa19e56aaeb9f350b4442a24724d358073131222e0bae","affectsGlobalScope":true,"impliedFormat":1},{"version":"f98e2b5fcf96686f2432d1823f195a2ad443762006d7fbda7b4d8d25efd0e384","affectsGlobalScope":true,"impliedFormat":1},{"version":"d3f5b5ecd76cd87ee280a5e72e69f941481e62f12430db4f27aa885c3addfdc7","affectsGlobalScope":true,"impliedFormat":1},{"version":"598710556d7994badb8c5c72d65a602121488d233b70e1c1318faf476a3a76d6","affectsGlobalScope":true,"impliedFormat":1},{"version":"5dabdd06cdb220b33a81312a965f8cab510044ccc522dfac4704baf7ae8aaa79","affectsGlobalScope":true,"impliedFormat":1},{"version":"29c8673e8a6fe0116035c345438591056032a76cad5744c81b5feb039d26789a","affectsGlobalScope":true,"impliedFormat":1},{"version":"9569b7fdc41e43e971cdd193685b085d682a3f2c7243c9a41360521cb21265fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"a66a81b1b7e9582442c41807d62a7baee789e65a8ce6951e6a0b2553a94859a1","affectsGlobalScope":true,"impliedFormat":1},{"version":"f4a2170e218a95ea4352470799614733e6ac9576e9f2d10b57a986dc26763936","affectsGlobalScope":true,"impliedFormat":1},{"version":"1eb62bccdb763ded6f74a2ccd5eb939e3d63fc2a25677409d9c45bd982dec75e","affectsGlobalScope":true,"impliedFormat":1},{"version":"4bcb4739ebaa38c7c8bb85a5b40971ab83809c6f1f217e4d26c4418d9b9b07ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"f4f9f2b412304f6a4664dd395380965e704a66d10490ac990c398691e7c69823","affectsGlobalScope":true,"impliedFormat":1},{"version":"8f54dfac75c73a9e55bb938d2dab1b48fb6fa8fc677dc7a21c3f90e92dae38b0","affectsGlobalScope":true,"impliedFormat":1},{"version":"d48c79e8502a2fb6274d2f41e12fbf5e3c51e53e770994af88b42bf0c53333f0","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bac8c62839badb7cf43d2a507d8df73e61a5313bb6bf0eb0e373b51b1d94e1b","affectsGlobalScope":true,"impliedFormat":1},{"version":"5d94554e80c2392a2b51be4baad4619268158eccb18d23e5d7107849bc409485","affectsGlobalScope":true,"impliedFormat":1},{"version":"ceb1a78b91d40a8cef51b498546780d8842cd42811597af2c5584fa68defe048","affectsGlobalScope":true,"impliedFormat":1},{"version":"f699d663c17e6bad3d2860b6e03a09c79afc248d159e6f1cc1594b2489cc4e89","affectsGlobalScope":true,"impliedFormat":1},{"version":"baace3d380a208ebd640bdfdb70748ca60fbaead011b4a92900abf334188f6cd","affectsGlobalScope":true,"impliedFormat":1},"f78d7513062564f7ea4baef7329a9b55c011a0afe7878ac6b8ad35913f9b2ccb",{"version":"4ffba3c5848b4fe62ee59b754fd5f256ad9656a0db6d37b9a2a8cb40dfc7ac21","impliedFormat":99},{"version":"c76c02846ba7d40b9b3488f0e8d75d02cbdee2f0bc5fcd55dd3bd2e1457646ea","impliedFormat":99},{"version":"32b35cf0dc3a1b1a7118b61c34ce2ad1a29695851679f9ec34e0776f2ece2a69","impliedFormat":99},{"version":"b413fbc6658fe2774f8bf9a15cf4c53e586fc38a2d5256b3b9647da242c14389","impliedFormat":99},{"version":"59e5e964b84fdb2378e9455e4e59405030e4ed2b4c6f891ce395f17796af3cbb","impliedFormat":99},{"version":"c30a41267fc04c6518b17e55dcb2b810f267af4314b0b6d7df1c33a76ce1b330","impliedFormat":1},{"version":"72422d0bac4076912385d0c10911b82e4694fc106e2d70added091f88f0824ba","impliedFormat":1},{"version":"da251b82c25bee1d93f9fd80c5a61d945da4f708ca21285541d7aff83ecb8200","impliedFormat":1},{"version":"64db14db2bf37ac089766fdb3c7e1160fabc10e9929bc2deeede7237e4419fc8","impliedFormat":1},{"version":"98b94085c9f78eba36d3d2314affe973e8994f99864b8708122750788825c771","impliedFormat":1},{"version":"90ba95a763101bb61b8a799731a2ed60b5016b8135c1a2d5186862d4b534d4a1","impliedFormat":99},"9ca734393d8f24d6ad8ab2e1266843a680ba57d96401ec0fd350a2f79ef44690","5a423cc5633cdb0c16ca0d9d697e5d521a5a7427030d47dd58a07c8cfe129ec5","6b199c0b287858758ca08004a11a8fcfce16efd5daf8f6f4db5f2fb980fac681","d6f201e5f37291820905d3e18ee84e498c7e134e3cdac2b39d468cdfe1e8e7a7","054458ed76535e12e436bfa449af2b9d729189822b9f0fd788411db4f3fbf894","a66cea78ef25e4ef1826802d61dd373616209b0edd47c9300d01e1fd0790f349","e6dfd3e46b182198ccc68db2a2a94ab39e09a8792944752aeefe8263f978a633","b5f0fca2a1746a8f762b2177a5b11569797502cc75d81041e4e1c1383a72b6c7","f1afb55b252643f4d5b190dd3462ccd8b1950f8d5dc672314def96d60d8bb7aa","0e57a41170b6583fa95ab7628c072dfb59baedf6f5b7a1302f0571fde00c988d","ed70a405fb0f474ab25da41ff929a9fda75be7052a0d16b662721846e3ce8ef1","997a063b9c0c15b9fe20d6fb85bc27a41722f0d2ad1de16c7bfb4aea2653aded",{"version":"40eb4eb274d7def754b3352c23328af96a69261fe5e99d20df41f1d5de8d0f5e","impliedFormat":1},{"version":"c57b441e0c0a9cbdfa7d850dae1f8a387d6f81cbffbc3cd0465d530084c2417d","impliedFormat":99},"0e4311f8b36ec93a12a8cc74c270f44ce9e15985338f44a884eaf16f533536e1","e2e606a029f4df4d36c597ec7a55b3421de7176ec249501eaecdd300cbb72b68","7bd9cc3e747d49bbd4e6fd101d8c7943577f191853d10dcb1ae055e052eadf1c","7bbeaa61933d81bfe588b902d36c2d59e989d17dc2c7ed75a7534470e8164260","f5bf05e7d3b9bc3958bc5d7277cde4267144d50a70b6f5683c969f62d56f5b6e","98b1e6e259d7c6604cfaaa20b49f9f999cb72b3f358eb4fc960181758322f782","c77d45875886b2769667692f7ed7908bfb152464946c2a8dfd9bb60c6f8adaa3","4da03cdc5835198d05f0e341e3fb56932b6ca37fd6c38fe005b0292fcaac6e66","d2d79ea85998a3efb3804140205a5c7f79a21985d89f0e1ae695bf5a7f9fa71e","5978d5fd0756f132a54a6fd64f438f069f2433918d8735d8d9ab9148b893bc5b","74d58a5d40a6b54fe1b80be4cd23e1c6613d1ac8a4b847e16c244b31d3161af6","4ce09a266b2e5bf6af2061cdcc0f1bdd7a1a54456a95e29674e7aeb5165e3ca0","57384580bcf7806616971f9b069885a0b039db5e536a41145e0d0cb2e4aca09e","1188adc484712c2dd226b45b67e6f335108d1e2f478e14a24048bbf174f44832","2552a31fad45a9ed1bde87e51b038dc0e786cd364b597162263abbf57018949b","a9bc4aebdbefdcf2294d087c921f7649d1f501fc443dbec2f0352697edb5e828","60a9a62eda8ec2b76cf498abe0e655dd88950663d4a8013289dd8acac39e489a","ca279cb4ed58995f487bba76a227a45011885d41a36294f42c6271a8ecde2443","db7724ba725653115aafed10e4da4fa5f5cbe73422ff1dee5416bd77136e690d","9b207c1a3143ebffad09ee6c575621bd3380de680914f37bfa132677f12dfd74","5af959e828bc129e2f8e180376782c62b68968f0f8bf8e73f8e15f6c6ed0c5d0","e735049618615faae346275a42ea18e635bb358a46ed8ce8bd817d5732f48ead","973420024d30eaab8a5069574eecce71e9f17dd17916d9012451767c0f3046d0","80ae69f9252b750f5dfde9641f141860321c4a996fb448644c1ecf4d6b392c54","9e5f7e1a3054c6b0d8ca4bdf4a9f6f4362e8ef1507f13e4ea3430da1a78cc682","5e9aa88edf06430b46e6f39719e3d6f6510719dc0fa7548940e92063123fbef9","5cd3cc9075703b39b28d2d27c37febb0875689b7858f7a1cb9fa6cac0c6bb903","90dfabc3cbbf059a29e0cd653c8898df959250760f5c4b1b7f7ba9f774858551","2c3c5d3e35fbd4720d7657879bc79fe3e780c026175a199ada8758458c1ee426","4330fa22fd1227b9aa409f17a69a92fba01b8b99bc0a85416d97d23946e4ebff","25eec9b5f9d2388c1e2f26078f2d88f428fe4456d31de3d88bbabab8e0c09a6e","a4ecbda77942add73282a24fcdf565337385c1350dbe5dc7a5ab7ad8e717fb5d","b37185326ec1f014ce18c131ed337b29f5b1270c939c0537e42bfb4d37d775c5","241e965e4faa42bd922e9858ef5c44318f324b4fdfc678b8544bdafcec86b77b","559752d10d9a9ac3e629692eee1e677c09433859a6825e679216645ff783b8a1","587d837a008810451e3696c4c0791bf45c1d714589a9bf0cd6816724097cf252","716e6ca041324e2f8517e5c77c42ff3dcccf0075f379663f468e984a372f171e","3a71bfb9e4465b09ddcbe49755f2af30fb6f7ec146f445d42b463598e26e57ce","1688c896870c13ad0c451dbcfb844f0591e63bbfc2939f58d572a253a5802ea3","bd8b12b28153903c8a9c4d9f39eb0481b23483a520469c6dba4c1a1070d3707f","1c3b0db8bfea38f24abe683fb46d33d9fbb66b2d74bda6e9c533504d134cbd97","21162bcb493c7bfea5062e22317fef76e6485adc778a28064d2ca138de5b988c","a9fa0a19b28ccfd591a513fa6828e8a96d52a2ef428cfe95bbdcf1ffe912dbcf","4e6b0593530e66023cf762a3b8f0808dba2dadc8b89d562f1fbbf6988196ae3f","de1003d170c985e66fd4aec0293b3ac2ff78691d9193a49c70d0407d63575b97","150ae78fb3507d4b377f49a2b7cf032753886e7838826ceb5aa962f0eab698fa","5f0033797db8a0d2a402dcbca3ddb0031c130357095f0c08d7bceb8e43cd0c30","aba19256d8c2803af262289762f30068f8f727126d45fee7f3c616546a3e4ef4","01f199d716d498b871f95d664e038ae46e8d799c4cd324860cac688f19f0300f","45e7214dfceb613041b8a9280296ff6f7753b863f669862070c90197054711fe","50f28b040848cb33611c3d5d9d080fe61ccb062614222a9fe25320365e959292","128a7248fd5cef3876cd95ca2a221e90e4d622b28b930ba693f38b18d9d264b0","aeb2825995058b2271cd85cb3df2cbba6935d1c0d2f5ff480439dc3cd5635e80",{"version":"ae77d81a5541a8abb938a0efedf9ac4bea36fb3a24cc28cfa11c598863aba571","impliedFormat":1},{"version":"751764bb94219b4ce8f5475dc35d3de2e432fea01a0c9610cd7f69ad05e398c6","impliedFormat":1}],"root":[60,[478,482],577,[619,645],[647,678],712,[724,735],[738,790]],"options":{"allowJs":false,"esModuleInterop":true,"jsx":1,"module":99,"skipLibCheck":true,"strict":true,"target":9},"referencedMap":[[757,1],[758,2],[756,3],[759,4],[755,5],[760,6],[761,7],[762,8],[763,9],[764,10],[765,11],[766,12],[769,13],[768,14],[767,15],[771,16],[770,17],[772,18],[773,19],[774,20],[775,21],[778,22],[777,23],[776,24],[779,25],[782,26],[781,27],[780,28],[783,29],[784,30],[785,31],[786,32],[787,33],[788,34],[754,35],[789,36],[790,37],[752,38],[60,39],[753,40],[628,41],[635,42],[627,41],[636,43],[625,44],[637,45],[640,46],[641,47],[642,46],[643,46],[644,48],[645,49],[651,50],[650,41],[649,51],[656,41],[655,52],[657,53],[661,54],[662,55],[664,56],[670,57],[669,58],[668,59],[671,60],[674,61],[673,61],[672,62],[675,63],[743,64],[745,65],[748,66],[676,67],[749,68],[739,69],[740,68],[751,70],[677,67],[738,71],[742,72],[744,73],[747,74],[746,75],[741,76],[750,77],[479,39],[480,39],[678,39],[646,39],[647,78],[630,79],[629,79],[648,80],[653,81],[623,82],[663,83],[624,84],[638,85],[639,86],[622,87],[634,88],[620,89],[631,89],[665,90],[658,89],[666,91],[667,92],[621,93],[626,94],[660,95],[654,96],[659,97],[619,39],[712,39],[652,39],[632,89],[633,98],[481,99],[478,100],[482,101],[225,39],[499,39],[501,39],[502,102],[486,39],[614,103],[615,104],[613,105],[608,106],[617,107],[602,39],[603,108],[612,109],[607,110],[616,39],[611,111],[604,39],[605,39],[610,112],[606,109],[609,110],[579,113],[580,114],[578,39],[590,115],[584,39],[593,116],[585,39],[591,117],[589,117],[592,118],[588,119],[587,39],[586,120],[581,39],[599,121],[595,122],[583,39],[582,39],[594,123],[597,124],[598,125],[596,126],[601,127],[618,128],[791,39],[493,129],[491,39],[792,39],[122,130],[123,130],[124,131],[77,132],[125,133],[126,134],[127,135],[72,39],[75,136],[73,39],[74,39],[128,137],[129,138],[130,139],[131,140],[132,141],[133,142],[134,142],[135,143],[136,144],[137,145],[138,146],[78,39],[76,39],[139,147],[140,148],[141,149],[175,150],[142,151],[143,39],[144,152],[145,153],[146,154],[147,155],[148,156],[149,157],[150,158],[151,159],[152,160],[153,160],[154,161],[155,39],[156,162],[157,163],[159,164],[158,165],[160,166],[161,167],[162,168],[163,169],[164,170],[165,171],[166,172],[167,173],[168,174],[169,175],[170,176],[171,177],[172,178],[79,39],[80,39],[81,39],[119,179],[120,39],[121,39],[173,180],[174,181],[179,182],[335,183],[180,184],[178,185],[337,186],[336,187],[176,188],[333,39],[177,189],[61,39],[63,190],[332,183],[243,183],[494,191],[564,192],[565,193],[563,39],[487,39],[549,194],[548,195],[560,194],[551,196],[553,197],[572,197],[552,198],[484,199],[483,39],[489,200],[490,201],[569,202],[545,203],[547,204],[568,39],[566,203],[546,39],[488,201],[544,39],[492,39],[737,39],[62,39],[720,205],[722,206],[721,207],[719,208],[718,39],[679,39],[683,39],[684,39],[680,39],[681,39],[682,39],[685,39],[686,39],[687,39],[688,39],[689,39],[690,39],[710,39],[691,39],[692,209],[711,210],[694,211],[695,39],[697,39],[696,39],[698,39],[699,39],[700,39],[701,39],[702,39],[705,39],[703,39],[704,39],[706,39],[707,39],[708,39],[709,39],[693,211],[600,39],[536,39],[538,212],[537,39],[736,183],[70,213],[424,214],[429,38],[431,215],[201,216],[229,217],[407,218],[224,219],[212,39],[193,39],[199,39],[397,220],[260,221],[200,39],[366,222],[234,223],[235,224],[331,225],[394,226],[349,227],[401,228],[402,229],[400,230],[399,39],[398,231],[231,232],[202,233],[281,39],[282,234],[197,39],[213,235],[203,236],[265,235],[262,235],[186,235],[227,237],[226,39],[406,238],[416,39],[192,39],[307,239],[308,240],[302,183],[452,39],[310,39],[311,241],[303,242],[458,243],[456,244],[451,39],[393,245],[392,39],[450,246],[304,183],[345,247],[343,248],[453,39],[457,39],[455,249],[454,39],[344,250],[445,251],[448,252],[272,253],[271,254],[270,255],[461,183],[269,256],[254,39],[464,39],[467,39],[466,183],[468,257],[182,39],[403,258],[404,259],[405,260],[215,39],[191,261],[181,39],[323,183],[184,262],[322,263],[321,264],[312,39],[313,39],[320,39],[315,39],[318,265],[314,39],[316,266],[319,267],[317,266],[198,39],[189,39],[190,235],[244,268],[245,269],[242,270],[240,271],[241,272],[237,39],[329,241],[351,241],[423,273],[432,274],[436,275],[410,276],[409,39],[257,39],[469,277],[419,278],[305,279],[306,280],[297,281],[287,39],[328,282],[288,283],[330,284],[325,285],[324,39],[326,39],[342,286],[411,287],[412,288],[290,289],[294,290],[285,291],[389,292],[418,293],[264,294],[367,295],[187,296],[417,297],[183,219],[238,39],[246,298],[378,299],[236,39],[377,300],[71,39],[372,301],[214,39],[283,302],[368,39],[188,39],[247,39],[376,303],[196,39],[252,304],[293,305],[408,306],[292,39],[375,39],[239,39],[380,307],[381,308],[194,39],[383,309],[385,310],[384,311],[217,39],[374,296],[387,312],[373,313],[379,314],[205,39],[208,39],[206,39],[210,39],[207,39],[209,39],[211,315],[204,39],[359,316],[358,39],[364,317],[360,318],[363,319],[362,319],[365,317],[361,318],[251,320],[352,321],[415,322],[471,39],[440,323],[442,324],[289,39],[441,325],[413,287],[470,326],[309,287],[195,39],[291,327],[248,328],[249,329],[250,330],[280,331],[388,331],[266,331],[353,332],[267,332],[233,333],[232,39],[357,334],[356,335],[355,336],[354,337],[414,338],[301,339],[339,340],[300,341],[334,342],[338,343],[396,344],[395,345],[391,346],[348,347],[350,348],[347,349],[386,350],[341,39],[428,39],[340,351],[390,39],[253,352],[286,258],[284,353],[255,354],[258,355],[465,39],[256,356],[259,356],[426,39],[425,39],[427,39],[463,39],[261,357],[299,183],[69,39],[346,358],[230,39],[219,359],[295,39],[434,183],[444,360],[279,183],[438,241],[278,361],[421,362],[277,360],[185,39],[446,363],[275,183],[276,183],[268,39],[218,39],[274,364],[273,365],[216,366],[296,159],[263,159],[382,39],[370,367],[369,39],[430,39],[327,368],[298,183],[422,369],[64,183],[67,370],[68,371],[65,183],[66,39],[228,89],[223,372],[222,39],[221,373],[220,39],[420,374],[433,375],[435,376],[437,377],[439,378],[443,379],[477,380],[447,380],[476,381],[449,382],[459,383],[460,384],[462,385],[472,386],[475,261],[474,39],[473,387],[532,388],[530,389],[531,390],[519,391],[520,389],[527,392],[518,393],[523,394],[533,39],[524,395],[529,396],[535,397],[534,398],[517,399],[525,400],[526,401],[521,402],[528,388],[522,403],[541,404],[504,405],[505,406],[508,407],[500,408],[507,409],[503,410],[498,39],[509,411],[510,412],[371,413],[516,39],[561,39],[485,39],[58,39],[59,39],[10,39],[11,39],[13,39],[12,39],[2,39],[14,39],[15,39],[16,39],[17,39],[18,39],[19,39],[20,39],[21,39],[3,39],[22,39],[23,39],[4,39],[24,39],[28,39],[25,39],[26,39],[27,39],[29,39],[30,39],[31,39],[5,39],[32,39],[33,39],[34,39],[35,39],[6,39],[39,39],[36,39],[37,39],[38,39],[40,39],[7,39],[41,39],[46,39],[47,39],[42,39],[43,39],[44,39],[45,39],[8,39],[51,39],[48,39],[49,39],[50,39],[52,39],[9,39],[53,39],[54,39],[55,39],[57,39],[56,39],[1,39],[97,414],[107,415],[96,414],[117,416],[88,417],[87,418],[116,387],[110,419],[115,420],[90,421],[104,422],[89,423],[113,424],[85,425],[84,387],[114,426],[86,427],[91,428],[92,39],[95,428],[82,39],[118,429],[108,430],[99,431],[100,432],[102,433],[98,434],[101,435],[111,387],[93,436],[94,437],[103,438],[83,439],[106,430],[105,428],[109,39],[112,440],[496,441],[543,442],[512,443],[497,441],[495,39],[511,444],[542,39],[540,39],[513,39],[539,445],[506,446],[515,39],[514,447],[571,448],[576,449],[570,450],[562,451],[558,452],[554,453],[567,39],[555,196],[716,454],[713,455],[574,456],[573,457],[556,458],[715,459],[550,39],[557,460],[575,461],[723,462],[717,463],[714,39],[559,39],[724,464],[725,465],[726,466],[727,467],[728,468],[729,469],[730,470],[731,471],[732,472],[733,473],[734,474],[735,39],[577,475]],"semanticDiagnosticsPerFile":[[730,[{"start":368,"length":6,"code":2339,"category":1,"messageText":"Property 'crypto' does not exist on type '{}'."},{"start":876,"length":10,"code":2339,"category":1,"messageText":"Property 'randomUUID' does not exist on type '{ getRandomValues(bytes: Uint8Array): Uint8Array; }'."}]]],"affectedFilesPendingEmit":[757,758,756,759,755,760,761,762,763,764,765,766,769,768,767,771,770,772,773,774,775,778,777,776,779,782,781,780,783,784,785,786,787,788,754,789,790,753,628,635,627,636,625,637,640,641,642,643,644,645,651,650,649,656,655,657,661,662,664,670,669,668,671,674,673,672,675,743,745,748,676,749,739,740,751,677,738,742,744,747,746,741,750,479,480,678,647,630,629,648,653,623,663,624,638,639,622,634,620,631,665,658,666,667,621,626,660,654,659,619,712,652,632,633,481,482,724,725,726,727,728,729,730,731,732,733,734,577],"version":"5.9.3"} \ No newline at end of file +{"fileNames":["./node_modules/typescript/lib/lib.es5.d.ts","./node_modules/typescript/lib/lib.es2015.d.ts","./node_modules/typescript/lib/lib.es2016.d.ts","./node_modules/typescript/lib/lib.es2017.d.ts","./node_modules/typescript/lib/lib.es2018.d.ts","./node_modules/typescript/lib/lib.es2019.d.ts","./node_modules/typescript/lib/lib.es2020.d.ts","./node_modules/typescript/lib/lib.es2021.d.ts","./node_modules/typescript/lib/lib.es2022.d.ts","./node_modules/typescript/lib/lib.dom.d.ts","./node_modules/typescript/lib/lib.dom.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.core.d.ts","./node_modules/typescript/lib/lib.es2015.collection.d.ts","./node_modules/typescript/lib/lib.es2015.generator.d.ts","./node_modules/typescript/lib/lib.es2015.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.promise.d.ts","./node_modules/typescript/lib/lib.es2015.proxy.d.ts","./node_modules/typescript/lib/lib.es2015.reflect.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2016.array.include.d.ts","./node_modules/typescript/lib/lib.es2016.intl.d.ts","./node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","./node_modules/typescript/lib/lib.es2017.date.d.ts","./node_modules/typescript/lib/lib.es2017.object.d.ts","./node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2017.string.d.ts","./node_modules/typescript/lib/lib.es2017.intl.d.ts","./node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","./node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","./node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","./node_modules/typescript/lib/lib.es2018.intl.d.ts","./node_modules/typescript/lib/lib.es2018.promise.d.ts","./node_modules/typescript/lib/lib.es2018.regexp.d.ts","./node_modules/typescript/lib/lib.es2019.array.d.ts","./node_modules/typescript/lib/lib.es2019.object.d.ts","./node_modules/typescript/lib/lib.es2019.string.d.ts","./node_modules/typescript/lib/lib.es2019.symbol.d.ts","./node_modules/typescript/lib/lib.es2019.intl.d.ts","./node_modules/typescript/lib/lib.es2020.bigint.d.ts","./node_modules/typescript/lib/lib.es2020.date.d.ts","./node_modules/typescript/lib/lib.es2020.promise.d.ts","./node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2020.string.d.ts","./node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2020.intl.d.ts","./node_modules/typescript/lib/lib.es2020.number.d.ts","./node_modules/typescript/lib/lib.es2021.promise.d.ts","./node_modules/typescript/lib/lib.es2021.string.d.ts","./node_modules/typescript/lib/lib.es2021.weakref.d.ts","./node_modules/typescript/lib/lib.es2021.intl.d.ts","./node_modules/typescript/lib/lib.es2022.array.d.ts","./node_modules/typescript/lib/lib.es2022.error.d.ts","./node_modules/typescript/lib/lib.es2022.intl.d.ts","./node_modules/typescript/lib/lib.es2022.object.d.ts","./node_modules/typescript/lib/lib.es2022.string.d.ts","./node_modules/typescript/lib/lib.es2022.regexp.d.ts","./node_modules/typescript/lib/lib.decorators.d.ts","./node_modules/typescript/lib/lib.decorators.legacy.d.ts","./.next/types/routes.d.ts","./node_modules/@types/react/global.d.ts","./node_modules/csstype/index.d.ts","./node_modules/@types/react/index.d.ts","./node_modules/next/dist/styled-jsx/types/css.d.ts","./node_modules/next/dist/styled-jsx/types/macro.d.ts","./node_modules/next/dist/styled-jsx/types/style.d.ts","./node_modules/next/dist/styled-jsx/types/global.d.ts","./node_modules/next/dist/styled-jsx/types/index.d.ts","./node_modules/next/dist/shared/lib/amp.d.ts","./node_modules/next/amp.d.ts","./node_modules/next/dist/server/get-page-files.d.ts","./node_modules/@types/node/compatibility/disposable.d.ts","./node_modules/@types/node/compatibility/indexable.d.ts","./node_modules/@types/node/compatibility/iterators.d.ts","./node_modules/@types/node/compatibility/index.d.ts","./node_modules/@types/node/globals.typedarray.d.ts","./node_modules/@types/node/buffer.buffer.d.ts","./node_modules/@types/node/globals.d.ts","./node_modules/@types/node/web-globals/abortcontroller.d.ts","./node_modules/@types/node/web-globals/domexception.d.ts","./node_modules/@types/node/web-globals/events.d.ts","./node_modules/undici-types/header.d.ts","./node_modules/undici-types/readable.d.ts","./node_modules/undici-types/file.d.ts","./node_modules/undici-types/fetch.d.ts","./node_modules/undici-types/formdata.d.ts","./node_modules/undici-types/connector.d.ts","./node_modules/undici-types/client.d.ts","./node_modules/undici-types/errors.d.ts","./node_modules/undici-types/dispatcher.d.ts","./node_modules/undici-types/global-dispatcher.d.ts","./node_modules/undici-types/global-origin.d.ts","./node_modules/undici-types/pool-stats.d.ts","./node_modules/undici-types/pool.d.ts","./node_modules/undici-types/handlers.d.ts","./node_modules/undici-types/balanced-pool.d.ts","./node_modules/undici-types/agent.d.ts","./node_modules/undici-types/mock-interceptor.d.ts","./node_modules/undici-types/mock-agent.d.ts","./node_modules/undici-types/mock-client.d.ts","./node_modules/undici-types/mock-pool.d.ts","./node_modules/undici-types/mock-errors.d.ts","./node_modules/undici-types/proxy-agent.d.ts","./node_modules/undici-types/env-http-proxy-agent.d.ts","./node_modules/undici-types/retry-handler.d.ts","./node_modules/undici-types/retry-agent.d.ts","./node_modules/undici-types/api.d.ts","./node_modules/undici-types/interceptors.d.ts","./node_modules/undici-types/util.d.ts","./node_modules/undici-types/cookies.d.ts","./node_modules/undici-types/patch.d.ts","./node_modules/undici-types/websocket.d.ts","./node_modules/undici-types/eventsource.d.ts","./node_modules/undici-types/filereader.d.ts","./node_modules/undici-types/diagnostics-channel.d.ts","./node_modules/undici-types/content-type.d.ts","./node_modules/undici-types/cache.d.ts","./node_modules/undici-types/index.d.ts","./node_modules/@types/node/web-globals/fetch.d.ts","./node_modules/@types/node/web-globals/navigator.d.ts","./node_modules/@types/node/web-globals/storage.d.ts","./node_modules/@types/node/assert.d.ts","./node_modules/@types/node/assert/strict.d.ts","./node_modules/@types/node/async_hooks.d.ts","./node_modules/@types/node/buffer.d.ts","./node_modules/@types/node/child_process.d.ts","./node_modules/@types/node/cluster.d.ts","./node_modules/@types/node/console.d.ts","./node_modules/@types/node/constants.d.ts","./node_modules/@types/node/crypto.d.ts","./node_modules/@types/node/dgram.d.ts","./node_modules/@types/node/diagnostics_channel.d.ts","./node_modules/@types/node/dns.d.ts","./node_modules/@types/node/dns/promises.d.ts","./node_modules/@types/node/domain.d.ts","./node_modules/@types/node/events.d.ts","./node_modules/@types/node/fs.d.ts","./node_modules/@types/node/fs/promises.d.ts","./node_modules/@types/node/http.d.ts","./node_modules/@types/node/http2.d.ts","./node_modules/@types/node/https.d.ts","./node_modules/@types/node/inspector.d.ts","./node_modules/@types/node/inspector.generated.d.ts","./node_modules/@types/node/module.d.ts","./node_modules/@types/node/net.d.ts","./node_modules/@types/node/os.d.ts","./node_modules/@types/node/path.d.ts","./node_modules/@types/node/perf_hooks.d.ts","./node_modules/@types/node/process.d.ts","./node_modules/@types/node/punycode.d.ts","./node_modules/@types/node/querystring.d.ts","./node_modules/@types/node/readline.d.ts","./node_modules/@types/node/readline/promises.d.ts","./node_modules/@types/node/repl.d.ts","./node_modules/@types/node/sea.d.ts","./node_modules/@types/node/sqlite.d.ts","./node_modules/@types/node/stream.d.ts","./node_modules/@types/node/stream/promises.d.ts","./node_modules/@types/node/stream/consumers.d.ts","./node_modules/@types/node/stream/web.d.ts","./node_modules/@types/node/string_decoder.d.ts","./node_modules/@types/node/test.d.ts","./node_modules/@types/node/timers.d.ts","./node_modules/@types/node/timers/promises.d.ts","./node_modules/@types/node/tls.d.ts","./node_modules/@types/node/trace_events.d.ts","./node_modules/@types/node/tty.d.ts","./node_modules/@types/node/url.d.ts","./node_modules/@types/node/util.d.ts","./node_modules/@types/node/v8.d.ts","./node_modules/@types/node/vm.d.ts","./node_modules/@types/node/wasi.d.ts","./node_modules/@types/node/worker_threads.d.ts","./node_modules/@types/node/zlib.d.ts","./node_modules/@types/node/index.d.ts","./node_modules/@types/react/canary.d.ts","./node_modules/@types/react/experimental.d.ts","./node_modules/@types/react-dom/index.d.ts","./node_modules/@types/react-dom/canary.d.ts","./node_modules/@types/react-dom/experimental.d.ts","./node_modules/next/dist/lib/fallback.d.ts","./node_modules/next/dist/compiled/webpack/webpack.d.ts","./node_modules/next/dist/server/config.d.ts","./node_modules/next/dist/lib/load-custom-routes.d.ts","./node_modules/next/dist/shared/lib/image-config.d.ts","./node_modules/next/dist/build/webpack/plugins/subresource-integrity-plugin.d.ts","./node_modules/next/dist/server/body-streams.d.ts","./node_modules/next/dist/server/lib/cache-control.d.ts","./node_modules/next/dist/lib/setup-exception-listeners.d.ts","./node_modules/next/dist/lib/worker.d.ts","./node_modules/next/dist/lib/constants.d.ts","./node_modules/next/dist/client/components/app-router-headers.d.ts","./node_modules/next/dist/build/rendering-mode.d.ts","./node_modules/next/dist/server/lib/router-utils/build-prefetch-segment-data-route.d.ts","./node_modules/next/dist/server/require-hook.d.ts","./node_modules/next/dist/server/lib/experimental/ppr.d.ts","./node_modules/next/dist/build/webpack/plugins/app-build-manifest-plugin.d.ts","./node_modules/next/dist/lib/page-types.d.ts","./node_modules/next/dist/build/segment-config/app/app-segment-config.d.ts","./node_modules/next/dist/build/segment-config/pages/pages-segment-config.d.ts","./node_modules/next/dist/build/analysis/get-page-static-info.d.ts","./node_modules/next/dist/build/webpack/loaders/get-module-build-info.d.ts","./node_modules/next/dist/build/webpack/plugins/middleware-plugin.d.ts","./node_modules/next/dist/server/node-polyfill-crypto.d.ts","./node_modules/next/dist/server/node-environment-baseline.d.ts","./node_modules/next/dist/server/node-environment-extensions/error-inspect.d.ts","./node_modules/next/dist/server/node-environment-extensions/random.d.ts","./node_modules/next/dist/server/node-environment-extensions/date.d.ts","./node_modules/next/dist/server/node-environment-extensions/web-crypto.d.ts","./node_modules/next/dist/server/node-environment-extensions/node-crypto.d.ts","./node_modules/next/dist/server/node-environment.d.ts","./node_modules/next/dist/build/page-extensions-type.d.ts","./node_modules/next/dist/build/webpack/plugins/flight-manifest-plugin.d.ts","./node_modules/next/dist/server/instrumentation/types.d.ts","./node_modules/next/dist/lib/coalesced-function.d.ts","./node_modules/next/dist/shared/lib/router/utils/middleware-route-matcher.d.ts","./node_modules/next/dist/server/lib/router-utils/types.d.ts","./node_modules/next/dist/shared/lib/modern-browserslist-target.d.ts","./node_modules/next/dist/shared/lib/constants.d.ts","./node_modules/next/dist/trace/types.d.ts","./node_modules/next/dist/trace/trace.d.ts","./node_modules/next/dist/trace/shared.d.ts","./node_modules/next/dist/trace/index.d.ts","./node_modules/next/dist/build/load-jsconfig.d.ts","./node_modules/@next/env/dist/index.d.ts","./node_modules/next/dist/build/webpack/plugins/telemetry-plugin/use-cache-tracker-utils.d.ts","./node_modules/next/dist/build/webpack/plugins/telemetry-plugin/telemetry-plugin.d.ts","./node_modules/next/dist/telemetry/storage.d.ts","./node_modules/next/dist/build/build-context.d.ts","./node_modules/next/dist/shared/lib/bloom-filter.d.ts","./node_modules/next/dist/build/webpack-config.d.ts","./node_modules/next/dist/server/route-kind.d.ts","./node_modules/next/dist/server/route-definitions/route-definition.d.ts","./node_modules/next/dist/build/swc/generated-native.d.ts","./node_modules/next/dist/build/swc/types.d.ts","./node_modules/next/dist/server/dev/parse-version-info.d.ts","./node_modules/next/dist/next-devtools/shared/types.d.ts","./node_modules/next/dist/server/dev/dev-indicator-server-state.d.ts","./node_modules/next/dist/server/lib/parse-stack.d.ts","./node_modules/next/dist/next-devtools/server/shared.d.ts","./node_modules/next/dist/next-devtools/shared/stack-frame.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/utils/get-error-by-type.d.ts","./node_modules/@types/react/jsx-runtime.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/container/runtime-error/render-error.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/shared.d.ts","./node_modules/next/dist/server/dev/hot-reloader-types.d.ts","./node_modules/next/dist/server/lib/cache-handlers/types.d.ts","./node_modules/next/dist/server/response-cache/types.d.ts","./node_modules/next/dist/server/resume-data-cache/cache-store.d.ts","./node_modules/next/dist/server/resume-data-cache/resume-data-cache.d.ts","./node_modules/next/dist/server/render-result.d.ts","./node_modules/next/dist/server/lib/i18n-provider.d.ts","./node_modules/next/dist/server/web/next-url.d.ts","./node_modules/next/dist/compiled/@edge-runtime/cookies/index.d.ts","./node_modules/next/dist/server/web/spec-extension/cookies.d.ts","./node_modules/next/dist/server/web/spec-extension/request.d.ts","./node_modules/next/dist/server/after/builtin-request-context.d.ts","./node_modules/next/dist/server/web/spec-extension/fetch-event.d.ts","./node_modules/next/dist/server/web/spec-extension/response.d.ts","./node_modules/next/dist/build/segment-config/middleware/middleware-config.d.ts","./node_modules/next/dist/server/web/types.d.ts","./node_modules/next/dist/build/webpack/plugins/pages-manifest-plugin.d.ts","./node_modules/next/dist/shared/lib/router/utils/parse-url.d.ts","./node_modules/next/dist/server/base-http/node.d.ts","./node_modules/next/dist/build/webpack/plugins/next-font-manifest-plugin.d.ts","./node_modules/next/dist/server/route-definitions/locale-route-definition.d.ts","./node_modules/next/dist/server/route-definitions/pages-route-definition.d.ts","./node_modules/next/dist/shared/lib/mitt.d.ts","./node_modules/next/dist/client/with-router.d.ts","./node_modules/next/dist/client/router.d.ts","./node_modules/next/dist/client/route-loader.d.ts","./node_modules/next/dist/client/page-loader.d.ts","./node_modules/next/dist/shared/lib/router/router.d.ts","./node_modules/next/dist/shared/lib/router-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/loadable-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/loadable.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/image-config-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/hooks-client-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/head-manager-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-definitions/app-page-route-definition.d.ts","./node_modules/next/dist/build/webpack/loaders/metadata/types.d.ts","./node_modules/next/dist/build/webpack/loaders/next-app-loader/index.d.ts","./node_modules/next/dist/server/lib/app-dir-module.d.ts","./node_modules/next/dist/server/web/spec-extension/adapters/request-cookies.d.ts","./node_modules/next/dist/server/async-storage/draft-mode-provider.d.ts","./node_modules/next/dist/server/web/spec-extension/adapters/headers.d.ts","./node_modules/next/dist/server/app-render/cache-signal.d.ts","./node_modules/next/dist/server/app-render/dynamic-rendering.d.ts","./node_modules/next/dist/server/request/fallback-params.d.ts","./node_modules/next/dist/server/app-render/work-unit-async-storage-instance.d.ts","./node_modules/next/dist/server/response-cache/index.d.ts","./node_modules/next/dist/server/lib/lazy-result.d.ts","./node_modules/next/dist/server/lib/implicit-tags.d.ts","./node_modules/next/dist/server/app-render/work-unit-async-storage.external.d.ts","./node_modules/next/dist/shared/lib/deep-readonly.d.ts","./node_modules/next/dist/shared/lib/router/utils/parse-relative-url.d.ts","./node_modules/next/dist/server/app-render/app-render.d.ts","./node_modules/next/dist/shared/lib/server-inserted-html.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/amp-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/contexts/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/app-page/module.compiled.d.ts","./node_modules/next/dist/client/components/error-boundary.d.ts","./node_modules/next/dist/client/components/layout-router.d.ts","./node_modules/next/dist/client/components/render-from-template-context.d.ts","./node_modules/next/dist/server/app-render/action-async-storage-instance.d.ts","./node_modules/next/dist/server/app-render/action-async-storage.external.d.ts","./node_modules/next/dist/client/components/client-page.d.ts","./node_modules/next/dist/client/components/client-segment.d.ts","./node_modules/next/dist/server/request/search-params.d.ts","./node_modules/next/dist/client/components/hooks-server-context.d.ts","./node_modules/next/dist/client/components/http-access-fallback/error-boundary.d.ts","./node_modules/next/dist/lib/metadata/types/alternative-urls-types.d.ts","./node_modules/next/dist/lib/metadata/types/extra-types.d.ts","./node_modules/next/dist/lib/metadata/types/metadata-types.d.ts","./node_modules/next/dist/lib/metadata/types/manifest-types.d.ts","./node_modules/next/dist/lib/metadata/types/opengraph-types.d.ts","./node_modules/next/dist/lib/metadata/types/twitter-types.d.ts","./node_modules/next/dist/lib/metadata/types/metadata-interface.d.ts","./node_modules/next/dist/lib/metadata/types/resolvers.d.ts","./node_modules/next/dist/lib/metadata/types/icons.d.ts","./node_modules/next/dist/lib/metadata/resolve-metadata.d.ts","./node_modules/next/dist/lib/metadata/metadata.d.ts","./node_modules/next/dist/lib/framework/boundary-components.d.ts","./node_modules/next/dist/server/app-render/rsc/preloads.d.ts","./node_modules/next/dist/server/app-render/rsc/postpone.d.ts","./node_modules/next/dist/server/app-render/rsc/taint.d.ts","./node_modules/next/dist/shared/lib/segment-cache/segment-value-encoding.d.ts","./node_modules/next/dist/server/app-render/collect-segment-data.d.ts","./node_modules/next/dist/next-devtools/userspace/app/segment-explorer-node.d.ts","./node_modules/next/dist/server/app-render/entry-base.d.ts","./node_modules/next/dist/build/templates/app-page.d.ts","./node_modules/@types/react/jsx-dev-runtime.d.ts","./node_modules/@types/react/compiler-runtime.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/rsc/entrypoints.d.ts","./node_modules/@types/react-dom/client.d.ts","./node_modules/@types/react-dom/static.d.ts","./node_modules/@types/react-dom/server.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/ssr/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/app-page/module.d.ts","./node_modules/next/dist/server/web/adapter.d.ts","./node_modules/next/dist/server/use-cache/cache-life.d.ts","./node_modules/next/dist/server/app-render/types.d.ts","./node_modules/next/dist/client/components/router-reducer/router-reducer-types.d.ts","./node_modules/next/dist/client/flight-data-helpers.d.ts","./node_modules/next/dist/client/components/router-reducer/fetch-server-response.d.ts","./node_modules/next/dist/shared/lib/app-router-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-modules/pages/vendored/contexts/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/pages/module.compiled.d.ts","./node_modules/next/dist/build/templates/pages.d.ts","./node_modules/next/dist/server/route-modules/pages/module.d.ts","./node_modules/next/dist/next-devtools/userspace/pages/pages-dev-overlay-setup.d.ts","./node_modules/next/dist/server/render.d.ts","./node_modules/next/dist/server/route-definitions/pages-api-route-definition.d.ts","./node_modules/next/dist/server/route-matches/pages-api-route-match.d.ts","./node_modules/next/dist/server/route-matchers/route-matcher.d.ts","./node_modules/next/dist/server/route-matcher-providers/route-matcher-provider.d.ts","./node_modules/next/dist/server/route-matcher-managers/route-matcher-manager.d.ts","./node_modules/next/dist/server/normalizers/normalizer.d.ts","./node_modules/next/dist/server/normalizers/locale-route-normalizer.d.ts","./node_modules/next/dist/server/normalizers/request/pathname-normalizer.d.ts","./node_modules/next/dist/server/normalizers/request/suffix.d.ts","./node_modules/next/dist/server/normalizers/request/rsc.d.ts","./node_modules/next/dist/server/normalizers/request/prefetch-rsc.d.ts","./node_modules/next/dist/server/normalizers/request/next-data.d.ts","./node_modules/next/dist/server/normalizers/request/segment-prefix-rsc.d.ts","./node_modules/next/dist/build/static-paths/types.d.ts","./node_modules/next/dist/server/base-server.d.ts","./node_modules/next/dist/server/lib/async-callback-set.d.ts","./node_modules/next/dist/shared/lib/router/utils/route-regex.d.ts","./node_modules/next/dist/shared/lib/router/utils/route-matcher.d.ts","./node_modules/sharp/lib/index.d.ts","./node_modules/next/dist/server/image-optimizer.d.ts","./node_modules/next/dist/server/next-server.d.ts","./node_modules/next/dist/server/lib/types.d.ts","./node_modules/next/dist/server/lib/lru-cache.d.ts","./node_modules/next/dist/server/lib/dev-bundler-service.d.ts","./node_modules/next/dist/server/dev/static-paths-worker.d.ts","./node_modules/next/dist/server/dev/next-dev-server.d.ts","./node_modules/next/dist/server/next.d.ts","./node_modules/next/dist/server/lib/render-server.d.ts","./node_modules/next/dist/server/lib/router-server.d.ts","./node_modules/next/dist/shared/lib/router/utils/path-match.d.ts","./node_modules/next/dist/server/lib/router-utils/filesystem.d.ts","./node_modules/next/dist/server/lib/router-utils/setup-dev-bundler.d.ts","./node_modules/next/dist/server/lib/router-utils/router-server-context.d.ts","./node_modules/next/dist/server/route-modules/route-module.d.ts","./node_modules/next/dist/server/load-components.d.ts","./node_modules/next/dist/server/route-definitions/app-route-route-definition.d.ts","./node_modules/next/dist/server/async-storage/work-store.d.ts","./node_modules/next/dist/server/web/http.d.ts","./node_modules/next/dist/server/route-modules/app-route/shared-modules.d.ts","./node_modules/next/dist/client/components/redirect-status-code.d.ts","./node_modules/next/dist/client/components/redirect-error.d.ts","./node_modules/next/dist/build/templates/app-route.d.ts","./node_modules/next/dist/server/route-modules/app-route/module.d.ts","./node_modules/next/dist/server/route-modules/app-route/module.compiled.d.ts","./node_modules/next/dist/build/segment-config/app/app-segments.d.ts","./node_modules/next/dist/build/utils.d.ts","./node_modules/next/dist/build/turborepo-access-trace/types.d.ts","./node_modules/next/dist/build/turborepo-access-trace/result.d.ts","./node_modules/next/dist/build/turborepo-access-trace/helpers.d.ts","./node_modules/next/dist/build/turborepo-access-trace/index.d.ts","./node_modules/next/dist/export/routes/types.d.ts","./node_modules/next/dist/export/types.d.ts","./node_modules/next/dist/export/worker.d.ts","./node_modules/next/dist/build/worker.d.ts","./node_modules/next/dist/build/index.d.ts","./node_modules/next/dist/server/lib/incremental-cache/index.d.ts","./node_modules/next/dist/server/after/after.d.ts","./node_modules/next/dist/server/after/after-context.d.ts","./node_modules/next/dist/server/app-render/work-async-storage-instance.d.ts","./node_modules/next/dist/server/app-render/work-async-storage.external.d.ts","./node_modules/next/dist/server/request/params.d.ts","./node_modules/next/dist/server/route-matches/route-match.d.ts","./node_modules/next/dist/server/request-meta.d.ts","./node_modules/next/dist/cli/next-test.d.ts","./node_modules/next/dist/server/config-shared.d.ts","./node_modules/next/dist/server/base-http/index.d.ts","./node_modules/next/dist/server/api-utils/index.d.ts","./node_modules/next/dist/types.d.ts","./node_modules/next/dist/shared/lib/html-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/utils.d.ts","./node_modules/next/dist/pages/_app.d.ts","./node_modules/next/app.d.ts","./node_modules/next/dist/server/web/spec-extension/unstable-cache.d.ts","./node_modules/next/dist/server/web/spec-extension/revalidate.d.ts","./node_modules/next/dist/server/web/spec-extension/unstable-no-store.d.ts","./node_modules/next/dist/server/use-cache/cache-tag.d.ts","./node_modules/next/cache.d.ts","./node_modules/next/dist/shared/lib/runtime-config.external.d.ts","./node_modules/next/config.d.ts","./node_modules/next/dist/pages/_document.d.ts","./node_modules/next/document.d.ts","./node_modules/next/dist/shared/lib/dynamic.d.ts","./node_modules/next/dynamic.d.ts","./node_modules/next/dist/pages/_error.d.ts","./node_modules/next/error.d.ts","./node_modules/next/dist/shared/lib/head.d.ts","./node_modules/next/head.d.ts","./node_modules/next/dist/server/request/cookies.d.ts","./node_modules/next/dist/server/request/headers.d.ts","./node_modules/next/dist/server/request/draft-mode.d.ts","./node_modules/next/headers.d.ts","./node_modules/next/dist/shared/lib/get-img-props.d.ts","./node_modules/next/dist/client/image-component.d.ts","./node_modules/next/dist/shared/lib/image-external.d.ts","./node_modules/next/image.d.ts","./node_modules/next/dist/client/link.d.ts","./node_modules/next/link.d.ts","./node_modules/next/dist/client/components/redirect.d.ts","./node_modules/next/dist/client/components/not-found.d.ts","./node_modules/next/dist/client/components/forbidden.d.ts","./node_modules/next/dist/client/components/unauthorized.d.ts","./node_modules/next/dist/client/components/unstable-rethrow.server.d.ts","./node_modules/next/dist/client/components/unstable-rethrow.d.ts","./node_modules/next/dist/client/components/navigation.react-server.d.ts","./node_modules/next/dist/client/components/unrecognized-action-error.d.ts","./node_modules/next/dist/client/components/navigation.d.ts","./node_modules/next/navigation.d.ts","./node_modules/next/router.d.ts","./node_modules/next/dist/client/script.d.ts","./node_modules/next/script.d.ts","./node_modules/next/dist/server/web/spec-extension/user-agent.d.ts","./node_modules/next/dist/compiled/@edge-runtime/primitives/url.d.ts","./node_modules/next/dist/server/web/spec-extension/image-response.d.ts","./node_modules/next/dist/compiled/@vercel/og/satori/index.d.ts","./node_modules/next/dist/compiled/@vercel/og/emoji/index.d.ts","./node_modules/next/dist/compiled/@vercel/og/types.d.ts","./node_modules/next/dist/server/after/index.d.ts","./node_modules/next/dist/server/request/root-params.d.ts","./node_modules/next/dist/server/request/connection.d.ts","./node_modules/next/server.d.ts","./node_modules/next/types/global.d.ts","./node_modules/next/types/compiled.d.ts","./node_modules/next/types.d.ts","./node_modules/next/index.d.ts","./node_modules/next/image-types/global.d.ts","./next-env.d.ts","./next.config.ts","./node_modules/@vitest/spy/optional-types.d.ts","./node_modules/@vitest/spy/dist/index.d.ts","./node_modules/tinyrainbow/dist/index.d.ts","./node_modules/@standard-schema/spec/dist/index.d.ts","./node_modules/@vitest/pretty-format/dist/index.d.ts","./node_modules/@vitest/utils/dist/types.d-bcelap-c.d.ts","./node_modules/@vitest/utils/dist/diff.d.ts","./node_modules/@vitest/utils/dist/display.d.ts","./node_modules/@types/deep-eql/index.d.ts","./node_modules/assertion-error/index.d.ts","./node_modules/@types/chai/index.d.ts","./node_modules/@vitest/expect/dist/index.d.ts","./node_modules/vite/types/hmrpayload.d.ts","./node_modules/vite/dist/node/chunks/modulerunnertransport.d.ts","./node_modules/vite/types/customevent.d.ts","./node_modules/rolldown/dist/shared/logging-bsnejils.d.mts","./node_modules/@oxc-project/types/types.d.ts","./node_modules/rolldown/dist/shared/binding-dktddyoy.d.mts","./node_modules/@rolldown/pluginutils/dist/filter/index.d.mts","./node_modules/@rolldown/pluginutils/dist/index.d.mts","./node_modules/rolldown/dist/shared/define-config-bo24xyuk.d.mts","./node_modules/rolldown/dist/index.d.mts","./node_modules/rolldown/dist/parse-ast-index.d.mts","./node_modules/vite/types/internal/rolluptypecompat.d.ts","./node_modules/rolldown/dist/shared/constructors-dc4y1bfn.d.mts","./node_modules/rolldown/dist/plugins-index.d.mts","./node_modules/rolldown/dist/shared/transform-bpesea-x.d.mts","./node_modules/rolldown/dist/utils-index.d.mts","./node_modules/vite/types/hot.d.ts","./node_modules/vite/dist/node/module-runner.d.ts","./node_modules/vite/types/internal/esbuildoptions.d.ts","./node_modules/vite/types/metadata.d.ts","./node_modules/vite/types/internal/terseroptions.d.ts","./node_modules/source-map-js/source-map.d.ts","./node_modules/postcss/lib/previous-map.d.ts","./node_modules/postcss/lib/input.d.ts","./node_modules/postcss/lib/css-syntax-error.d.ts","./node_modules/postcss/lib/declaration.d.ts","./node_modules/postcss/lib/root.d.ts","./node_modules/postcss/lib/warning.d.ts","./node_modules/postcss/lib/lazy-result.d.ts","./node_modules/postcss/lib/no-work-result.d.ts","./node_modules/postcss/lib/processor.d.ts","./node_modules/postcss/lib/result.d.ts","./node_modules/postcss/lib/document.d.ts","./node_modules/postcss/lib/rule.d.ts","./node_modules/postcss/lib/node.d.ts","./node_modules/postcss/lib/comment.d.ts","./node_modules/postcss/lib/container.d.ts","./node_modules/postcss/lib/at-rule.d.ts","./node_modules/postcss/lib/list.d.ts","./node_modules/postcss/lib/postcss.d.ts","./node_modules/postcss/lib/postcss.d.mts","./node_modules/lightningcss/node/ast.d.ts","./node_modules/lightningcss/node/targets.d.ts","./node_modules/lightningcss/node/index.d.ts","./node_modules/vite/types/internal/lightningcssoptions.d.ts","./node_modules/vite/types/internal/csspreprocessoroptions.d.ts","./node_modules/rolldown/dist/filter-index.d.mts","./node_modules/vite/types/importglob.d.ts","./node_modules/vite/dist/node/index.d.ts","./node_modules/@vitest/utils/dist/types.d.ts","./node_modules/@vitest/utils/dist/helpers.d.ts","./node_modules/@vitest/utils/dist/timers.d.ts","./node_modules/@vitest/utils/dist/index.d.ts","./node_modules/@vitest/runner/dist/tasks.d-deyaimiu.d.ts","./node_modules/@vitest/runner/dist/index.d.ts","./node_modules/vitest/dist/chunks/traces.d.d2t_r8rx.d.ts","./node_modules/@vitest/snapshot/dist/environment.d-dojxxzv9.d.ts","./node_modules/@vitest/snapshot/dist/rawsnapshot.d-d_x3-62x.d.ts","./node_modules/@vitest/snapshot/dist/index.d.ts","./node_modules/vitest/dist/chunks/config.d.a1h_y6jt.d.ts","./node_modules/vitest/dist/chunks/environment.d.crsxczp1.d.ts","./node_modules/vitest/dist/chunks/rpc.d.b_8spu0w.d.ts","./node_modules/vitest/dist/chunks/worker.d.zphpo4yb.d.ts","./node_modules/vitest/dist/chunks/browser.d.bcoexmfg.d.ts","./node_modules/vitest/optional-types.d.ts","./node_modules/@vitest/runner/dist/utils.d.ts","./node_modules/tinybench/dist/index.d.ts","./node_modules/vitest/dist/chunks/benchmark.d.daahlpsq.d.ts","./node_modules/@vitest/mocker/dist/types.d-bji5eawu.d.ts","./node_modules/@vitest/mocker/dist/index.d-b41z0auw.d.ts","./node_modules/@vitest/mocker/dist/index.d.ts","./node_modules/@vitest/utils/dist/source-map.d.ts","./node_modules/vitest/dist/chunks/coverage.d.bztk59wp.d.ts","./node_modules/@vitest/utils/dist/serialize.d.ts","./node_modules/@vitest/utils/dist/error.d.ts","./node_modules/vitest/dist/browser.d.ts","./node_modules/vitest/browser/context.d.ts","./node_modules/@vitest/snapshot/dist/manager.d.ts","./node_modules/vitest/dist/chunks/reporters.d.ctluhkka.d.ts","./node_modules/vitest/dist/chunks/plugin.d.c0upjs_f.d.ts","./node_modules/vitest/dist/config.d.ts","./node_modules/vitest/config.d.ts","./vitest.config.ts","./lib/types.ts","./lib/billing.ts","./lib/usage.ts","./lib/video-settings.ts","./lib/auth/config.ts","./lib/auth/session.ts","./lib/auth/permissions.ts","./lib/content/seedance-starter/catalog.json","./lib/content/video-templates.ts","./lib/prompt/material-placeholders.ts","./lib/prompt/assembler.ts","./lib/server/runtime.ts","./lib/bailian/client.ts","./lib/client/browser-auth.ts","./lib/client/random-uuid-polyfill.ts","./lib/evolink/image-client.ts","./lib/jimeng/capabilities.ts","./lib/prompt/material-draft.ts","./lib/seedance/client.ts","./lib/server/auth/password.ts","./lib/server/ids.ts","./node_modules/pg-types/index.d.ts","./node_modules/pg-protocol/dist/messages.d.ts","./node_modules/pg-protocol/dist/serializer.d.ts","./node_modules/pg-protocol/dist/parser.d.ts","./node_modules/pg-protocol/dist/index.d.ts","./node_modules/@types/pg/lib/type-overrides.d.ts","./node_modules/@types/pg/index.d.ts","./node_modules/@types/pg/index.d.mts","./lib/server/database.ts","./lib/server/data-store.ts","./lib/server/account-store.ts","./lib/server/log-manager.ts","./lib/server/api.ts","./lib/volcengine/signature.ts","./lib/volcengine/visual-client.ts","./lib/server/app-settings.ts","./lib/server/billing-store.ts","./lib/server/billing-catalog.ts","./lib/server/seedance-billing.ts","./lib/server/billing-service.ts","./lib/server/mock-image.ts","./lib/server/storage.ts","./lib/server/generation-service.ts","./lib/server/image-template-input.ts","./lib/server/organization-client.ts","./lib/server/public-api-auth.ts","./lib/server/public-api-assets.ts","./lib/server/video-generation-service.ts","./lib/server/public-api-jobs.ts","./lib/server/public-api-response.ts","./lib/server/webhook.ts","./lib/server/task-manager.ts","./lib/server/usage-context.ts","./lib/server/usage-service.ts","./lib/server/auth/platform-session.ts","./lib/server/auth/platform-authorization-store.ts","./lib/server/auth/current-user.ts","./lib/server/auth/jwt.ts","./lib/server/auth/session-cookie.ts","./lib/server/auth/local.ts","./lib/server/auth/oauth.ts","./node_modules/gsap/types/animation.d.ts","./node_modules/gsap/types/custom-bounce.d.ts","./node_modules/gsap/types/custom-ease.d.ts","./node_modules/gsap/types/custom-wiggle.d.ts","./node_modules/gsap/types/css-plugin.d.ts","./node_modules/gsap/types/css-rule-plugin.d.ts","./node_modules/gsap/types/draggable.d.ts","./node_modules/gsap/types/draw-svg-plugin.d.ts","./node_modules/gsap/types/ease.d.ts","./node_modules/gsap/types/easel-plugin.d.ts","./node_modules/gsap/types/flip.d.ts","./node_modules/gsap/types/gs-dev-tools.d.ts","./node_modules/gsap/types/gsap-plugins.d.ts","./node_modules/gsap/types/gsap-utils.d.ts","./node_modules/gsap/types/utils/velocitytracker.d.ts","./node_modules/gsap/types/inertia-plugin.d.ts","./node_modules/gsap/types/morph-svg-plugin.d.ts","./node_modules/gsap/types/motion-path-plugin.d.ts","./node_modules/gsap/types/motion-path-helper.d.ts","./node_modules/gsap/types/observer.d.ts","./node_modules/gsap/types/physics-2d-plugin.d.ts","./node_modules/gsap/types/physics-props-plugin.d.ts","./node_modules/gsap/types/pixi-plugin.d.ts","./node_modules/gsap/types/scramble-text-plugin.d.ts","./node_modules/gsap/types/scroll-to-plugin.d.ts","./node_modules/gsap/types/scroll-trigger.d.ts","./node_modules/gsap/types/scroll-smoother.d.ts","./node_modules/gsap/types/split-text.d.ts","./node_modules/gsap/types/text-plugin.d.ts","./node_modules/gsap/types/timeline.d.ts","./node_modules/gsap/types/tween.d.ts","./node_modules/gsap/types/gsap-core.d.ts","./node_modules/gsap/types/index.d.ts","./lib/ui/motion.ts","./node_modules/vitest/dist/chunks/global.d.dvssrdq5.d.ts","./node_modules/vitest/optional-runtime-types.d.ts","./node_modules/vitest/dist/chunks/suite.d.udjtyagw.d.ts","./node_modules/vitest/dist/chunks/evaluatedmodules.d.bxj5omdx.d.ts","./node_modules/vitest/dist/runners.d.ts","./node_modules/expect-type/dist/utils.d.ts","./node_modules/expect-type/dist/overloads.d.ts","./node_modules/expect-type/dist/branding.d.ts","./node_modules/expect-type/dist/messages.d.ts","./node_modules/expect-type/dist/index.d.ts","./node_modules/vitest/dist/index.d.ts","./tests/account-store-postgres-auth.test.ts","./tests/account-store.test.ts","./tests/admin-accounts-organizations-contract.test.ts","./tests/admin-http-auth-compat.test.ts","./tests/admin-http-contract.test.ts","./tests/assets-contract.test.ts","./tests/assets-http-contract.test.ts","./tests/auth-login-panel.test.ts","./tests/auth-password-change-contract.test.ts","./tests/auth-permissions.test.ts","./tests/auth-platform-authorization-store.test.ts","./tests/auth-platform-http-auth-contract.test.ts","./tests/auth-platform-session-authorization-contract.test.ts","./tests/auth-session-contract.test.ts","./tests/auth-session.test.ts","./tests/bailian-client.test.ts","./tests/billing-go-core-contract.test.ts","./tests/billing-http-contract.test.ts","./tests/billing-postgres-mapping.test.ts","./tests/billing.test.ts","./tests/data-store-concurrency.test.ts","./tests/database-readiness-contract.test.ts","./tests/deploy-env.test.ts","./tests/evolink-image-client.test.ts","./tests/frontend-environment-copy.test.ts","./tests/go-command-contract.test.ts","./tests/image-templates.test.ts","./tests/jimeng-capabilities.test.ts","./tests/jobs-go-contract.test.ts","./tests/jobs-http-contract.test.ts","./tests/log-manager.test.ts","./tests/logs-go-contract.test.ts","./tests/material-draft.test.ts","./tests/organization-client.test.ts","./scripts/postgres-client.d.mts","./tests/postgres-client-config.test.ts","./tests/postgres-privilege-contract.test.ts","./tests/postgres-script-contract.test.ts","./tests/prompt-assembler.test.ts","./tests/providers-contract.test.ts","./tests/public-api-auth-contract.test.ts","./tests/random-uuid-polyfill.test.ts","./tests/seedance-client.test.ts","./tests/server-only-stub.ts","./tests/settings-go-contract.test.ts","./tests/static-frontend-architecture.test.ts","./tests/task-management.test.ts","./tests/usage-go-core-contract.test.ts","./tests/usage-http-contract.test.ts","./tests/usage-service.test.ts","./tests/video-settings.test.ts","./tests/volcengine-signature.test.ts","./tests/wallet-sql-contract.test.ts","./tests/webhook-go-contract.test.ts","./tests/worker-script.test.ts","./types/ali-oss.d.ts","./node_modules/lucide-react/dist/lucide-react.d.ts","./node_modules/clsx/clsx.d.mts","./components/account-usage-menu.tsx","./components/browser-auth.tsx","./components/app-shell.tsx","./app/layout.tsx","./app/page.tsx","./components/account-security-panel.tsx","./components/account-manager.tsx","./app/accounts/page.tsx","./app/assets/page.tsx","./app/auth/admin-login/page.tsx","./components/auth-login-panel.tsx","./app/auth/login/page.tsx","./app/billing/error.tsx","./components/billing-manager.tsx","./app/billing/page.tsx","./components/pagination.tsx","./components/create-studio.tsx","./app/create/page.tsx","./app/image-edit/page.tsx","./components/log-manager.tsx","./app/logs/page.tsx","./components/settings-panel.tsx","./app/settings/page.tsx","./components/usage-manager.tsx","./app/usage/page.tsx","./components/asset-manager.tsx","./.next/types/cache-life.d.ts","./.next/types/validator.ts","./.next/types/app/page.ts","./.next/types/app/accounts/page.ts","./.next/types/app/assets/page.ts","./.next/types/app/auth/admin-login/page.ts","./.next/types/app/auth/login/page.ts","./.next/types/app/billing/page.ts","./.next/types/app/create/page.ts","./.next/types/app/image-edit/page.ts","./.next/types/app/logs/page.ts","./.next/types/app/settings/page.ts","./.next/types/app/usage/page.ts","./node_modules/@types/aria-query/index.d.ts","./node_modules/@types/estree/index.d.ts"],"fileIdsList":[[77,125,142,143,318,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,747],[77,125,142,143,318,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,748],[77,125,142,143,318,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,749],[77,125,142,143,318,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,751],[77,125,142,143,318,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,754],[77,125,142,143,318,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,757],[77,125,142,143,318,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,758],[77,125,142,143,318,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,760],[77,125,142,143,318,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,744],[77,125,142,143,318,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,762],[77,125,142,143,318,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,764],[77,125,142,143,425,426,427,428,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[60,77,125,142,143,475,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,743,744,747,748,749,751,754,757,758,760,762,764],[77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,741,746],[77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,741],[77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,750],[63,77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,741,753],[63,77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,741,756],[77,125,142,143,462,476,589,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,741,742],[77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,741,759],[77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,741,761],[77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,741,763],[63,77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,738,745],[63,77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,738],[63,77,125,142,143,577,580,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,738],[63,77,125,142,143,447,449,459,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,670,738,739,740,741],[63,77,125,142,143,575,576,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,670,738,755],[63,77,125,142,143,447,588,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,670,738,741],[63,77,125,142,143,575,576,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,670,738],[63,77,125,142,143,459,580,588,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,575,576,578,584,585,592,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,670,738,739,755],[63,77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,670,738],[77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,738],[63,77,125,142,143,577,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,670,738],[77,125,142,143,580,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,575,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,575,585,586,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,582,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,583,584,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,584,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,578,585,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,138,142,143,147,473,575,586,594,595,604,605,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,472,607,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,138,142,143,147,575,579,586,587,590,591,593,606,610,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,443,579,580,581,586,630,631,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,130,142,143,579,580,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,472,575,579,580,606,634,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,472,579,580,586,633,634,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,130,142,143,169,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,473,604,606,630,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,575,580,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,472,579,580,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,575,612,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,575,576,605,612,613,614,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,138,142,143,147,473,575,586,595,604,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,137,142,143,473,603,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,575,586,587,590,591,605,610,615,616,617,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,130,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,130,138,142,143,147,586,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,575,605,621,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,130,142,143,575,585,590,605,618,621,623,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,608,621,624,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,138,142,143,147,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,578,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,138,142,143,147,575,586,595,605,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,737],[77,125,130,142,143,575,586,605,607,615,618,623,626,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,575,580,581,620,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,130,142,143,575,577,605,620,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,575,578,585,586,587,593,605,615,617,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,130,142,143,575,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,575,609,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[60,77,125,142,143,476,477,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,476,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,498,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,488,489,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,122,123,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,124,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,130,142,143,160,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,126,131,136,142,143,145,157,168,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,126,127,136,142,143,145,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[72,73,74,77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,128,142,143,169,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,129,130,137,142,143,146,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,130,142,143,157,165,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,131,133,136,142,143,145,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,124,125,132,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,133,134,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,135,136,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,124,125,136,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,136,137,138,142,143,157,168,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,136,137,138,142,143,152,157,160,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,118,125,133,136,139,142,143,145,157,168,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,136,137,139,140,142,143,145,157,165,168,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,141,142,143,157,165,168,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[75,76,77,78,79,80,81,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,136,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,144,168,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,133,136,142,143,145,157,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,146,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,147,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,124,125,142,143,148,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,150,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,151,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,136,142,143,152,153,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,152,154,169,171,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,137,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,136,142,143,157,158,160,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,159,160,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,157,158,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,160,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,161,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,122,125,142,143,157,162,168,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,136,142,143,163,164,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,163,164,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,130,142,143,145,157,165,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,166,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,145,167,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,151,168,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,157,170,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,144,171,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,172,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,118,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,118,125,136,138,142,143,148,157,160,168,170,171,173,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,157,174,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,602,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,136,142,143,157,165,175,596,597,600,601,602,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,67,77,125,142,143,176,177,178,180,420,468,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,67,77,125,142,143,176,177,178,179,335,420,468,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,67,77,125,142,143,176,177,179,180,420,468,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,180,335,336,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,180,335,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,67,77,125,142,143,177,178,179,180,420,468,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,67,77,125,142,143,176,178,179,180,420,468,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[61,62,77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,481,482,483,486,487,490,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,560,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,560,561,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,486,544,545,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,486,544,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,544,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,484,544,548,549,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,484,544,548,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,480,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,484,485,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,484,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,484,485,541,565,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,541,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,484,487,541,542,543,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,676,677],[77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,676,677,678,679],[77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,676,678],[77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,676],[77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669],[77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,533,534,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[69,77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,423,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,430,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,184,198,199,200,202,417,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,184,223,225,227,228,231,417,419,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,184,188,190,191,192,193,194,406,417,419,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,417,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,199,301,387,396,413,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,184,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,181,413,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,235,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,234,417,419,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,283,301,330,474,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,294,310,396,412,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,348,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,400,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,399,400,401,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,399,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[71,77,125,139,142,143,181,184,188,191,195,196,197,199,203,211,212,341,366,397,417,420,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,184,201,219,223,224,229,230,417,474,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,201,474,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,212,219,281,417,474,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,474,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,184,201,202,474,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,226,474,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,195,398,405,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,151,243,413,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,243,413,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,243,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,302,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,298,346,413,456,457,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,393,450,451,452,453,455,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,392,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,392,393,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,192,342,343,344,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,342,345,346,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,454,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,342,346,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,185,444,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,168,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,201,271,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,201,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,269,273,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,270,422,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,67,77,125,139,142,143,175,176,177,178,179,180,420,466,467,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,188,250,342,352,367,387,402,403,417,418,474,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,211,404,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,420,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,183,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,283,297,309,319,321,412,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,151,283,297,318,319,320,412,473,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,312,313,314,315,316,317,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,314,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,318,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,241,242,243,245,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,236,237,238,244,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,241,244,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,239,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,240,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,243,270,422,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,243,421,422,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,243,422,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,367,409,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,409,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,418,422,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,306,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,124,125,142,143,305,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,213,251,289,291,293,294,295,296,339,342,412,415,418,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,213,327,342,346,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,294,412,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,294,303,304,306,307,308,309,310,311,322,323,324,325,326,328,329,412,413,474,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,288,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,151,213,214,250,265,295,339,340,341,346,367,387,408,417,418,419,420,474,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,412,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,124,125,142,143,199,292,295,341,408,410,411,418,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,294,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,124,125,142,143,250,255,284,285,286,287,288,289,290,291,293,412,413,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,255,256,284,418,419,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,199,341,342,367,408,412,418,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,417,419,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,157,415,418,419,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,151,168,181,188,201,213,214,216,251,252,257,262,265,291,295,342,352,354,357,359,362,363,364,365,366,387,407,408,413,415,417,418,419,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,157,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,184,185,186,188,193,196,201,219,407,415,416,420,422,474,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,157,168,231,233,235,236,237,238,245,474,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,151,168,181,223,233,261,262,263,264,291,342,357,366,367,373,376,377,387,408,413,415,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,195,196,211,341,366,408,417,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,168,185,188,291,371,415,417,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,282,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,374,375,384,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,415,417,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,289,292,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,291,295,407,422,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,151,217,223,264,357,367,373,376,379,415,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,195,211,223,380,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,184,216,382,407,417,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,168,417,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,201,215,216,217,228,246,381,383,407,417,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[71,77,125,142,143,213,295,386,420,422,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,151,168,188,195,203,211,214,251,257,261,262,263,264,265,291,342,354,367,368,370,372,387,407,408,413,414,415,422,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,157,195,373,378,384,415,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,206,207,208,209,210,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,252,358,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,360,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,358,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,360,361,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,188,191,192,250,418,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,151,183,185,213,251,265,295,350,351,387,415,419,420,422,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,151,168,187,192,291,351,414,418,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,284,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,285,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,286,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,413,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,232,248,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,188,232,251,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,247,248,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,249,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,232,233,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,232,266,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,232,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,252,356,414,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,355,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,233,413,414,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,353,414,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,233,413,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,339,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,188,193,251,280,283,289,291,295,297,300,331,334,338,342,386,407,415,418,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,274,277,278,279,298,299,346,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,178,180,243,332,333,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,178,180,243,332,333,337,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,395,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,199,256,294,295,306,310,342,386,388,389,390,391,393,394,397,407,412,417,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,346,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,350,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,251,267,347,349,352,386,415,420,422,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,274,275,276,277,278,279,298,299,346,421,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[71,77,125,139,142,143,151,168,214,232,233,265,291,295,384,385,387,407,408,417,418,420,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,256,258,261,408,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,252,417,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,255,294,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,254,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,256,257,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,253,255,417,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,139,142,143,187,256,258,259,260,417,418,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,342,343,345,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,218,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,185,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,413,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,71,77,125,142,143,265,295,420,422,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,185,444,445,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,273,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,151,168,183,230,268,270,272,422,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,201,413,418,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,369,413,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,342,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,137,139,142,143,151,183,219,225,273,420,421,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,77,125,142,143,176,177,178,179,180,420,468,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,64,65,66,67,77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,220,221,222,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,220,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[63,67,77,125,139,141,142,143,151,175,176,177,178,179,180,181,183,214,318,379,417,419,422,468,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,432,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,434,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,436,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,438,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,440,441,442,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,446,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[68,70,77,125,142,143,424,429,431,433,435,437,439,443,447,449,459,460,462,472,473,474,475,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,448,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,458,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,270,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,461,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,124,125,142,143,256,258,259,261,309,413,463,464,465,468,469,470,471,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,175,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,597,598,599,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,157,597,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,528,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,526,528,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,517,525,526,527,529,531,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,515,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,518,523,528,531,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,514,531,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,518,519,522,523,524,531,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,518,519,520,522,523,531,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,515,516,517,518,519,523,524,525,527,528,529,531,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,531,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,513,515,516,517,518,519,520,522,523,524,525,526,527,528,529,530,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,513,531,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,518,520,521,523,524,531,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,522,531,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,523,524,528,531,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,516,526,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,500,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,495,497,500,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,496,497,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,497,500,504,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,496,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,497,500,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,495,496,497,499,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,495,497,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,496,497,506,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,157,175,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,90,94,125,142,143,168,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,90,125,142,143,157,168,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,85,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,87,90,125,142,143,165,168,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,145,165,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,85,125,142,143,175,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,87,90,125,142,143,145,168,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,82,83,86,89,125,136,142,143,157,168,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,90,97,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,82,88,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,90,111,112,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,86,90,125,142,143,160,168,175,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,111,125,142,143,175,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,84,85,125,142,143,175,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,90,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,84,85,86,87,88,89,90,91,92,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,112,113,114,115,116,117,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,90,105,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,90,97,98,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,88,90,98,99,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,89,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,82,85,90,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,90,94,98,99,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,94,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,88,90,93,125,142,143,168,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,82,87,90,97,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,157,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,85,90,111,125,142,143,173,175,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,492,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,136,137,139,140,141,142,143,145,157,165,168,174,175,492,493,494,501,502,503,505,507,509,510,511,512,532,536,537,538,539,540,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,492,493,494,508,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,494,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,535,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,501,511,540,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,501,540,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,567,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,491,572,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,671],[77,125,142,143,481,484,486,487,542,543,544,546,547,550,551,563,564,566,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,671],[77,125,142,143,546,557,558,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,671],[77,125,142,143,546,547,554,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,671],[77,125,142,143,484,486,546,547,550,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,671],[77,125,142,143,509,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,484,491,546,547,550,559,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,671],[77,125,142,143,540,570,572,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,128,137,142,143,157,484,486,491,540,544,546,547,550,551,554,555,556,559,562,563,564,568,569,572,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,671],[77,125,142,143,509,546,547,550,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,671],[77,125,142,143,546,557,558,559,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,671],[77,125,142,143,509,546,551,552,553,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,671],[77,125,128,137,142,143,157,484,486,491,509,540,544,546,547,550,551,552,553,554,555,556,557,558,559,562,563,564,568,569,570,571,572,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,671],[77,125,142,143,481,484,486,491,509,544,546,547,550,551,552,553,554,555,557,558,559,562,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,671,672,673,674,675,680],[77,125,142,143,484,486,546,547,550,551,557,558,559,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,671,673],[77,125,142,143,603,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669],[77,125,142,143,606,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,146,147,575,605,606,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,606,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,575,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,147,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,142,143,580,581,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,142,143,631,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,580,581,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,580,630,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,579,580,634,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,130,142,143,579,580,633,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,142,143,587,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,142,143,612,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,146,147,576,605,612,615,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,146,147,586,605,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,126,138,142,143,146,147,169,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,142,143,590,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,146,147,584,605,619,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,142,143,591,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,146,147,624,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,146,147,607,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,142,143,592,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,142,143,620,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,142,143,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681,716],[77,125,142,143,585,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,621,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,142,143,171,589,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,142,143,593,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,147,168,479,588,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,146,147,586,605,618,621,622,624,626,627,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,146,147,575,577,605,629,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,142,143,578,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,142,143,609,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,137,142,143,168,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,138,142,143,575,626,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,126,138,142,143,168,169,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669,681],[77,125,142,143,573,638,639,640,641,642,643,644,645,646,647,648,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,668,669]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"6e19568de4b7dc08d30aac343c12ef8a94d5f56fc91c9387a53faa7ab38d5e93","affectsGlobalScope":true},{"version":"7e29f41b158de217f94cb9676bf9cbd0cd9b5a46e1985141ed36e075c52bf6ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac51dd7d31333793807a6abaa5ae168512b6131bd41d9c5b98477fc3b7800f9f","impliedFormat":1},{"version":"dc0a7f107690ee5cd8afc8dbf05c4df78085471ce16bdd9881642ec738bc81fe","impliedFormat":1},{"version":"acd8fd5090ac73902278889c38336ff3f48af6ba03aa665eb34a75e7ba1dccc4","impliedFormat":1},{"version":"d6258883868fb2680d2ca96bc8b1352cab69874581493e6d52680c5ffecdb6cc","impliedFormat":1},{"version":"1b61d259de5350f8b1e5db06290d31eaebebc6baafd5f79d314b5af9256d7153","impliedFormat":1},{"version":"f258e3960f324a956fc76a3d3d9e964fff2244ff5859dcc6ce5951e5413ca826","impliedFormat":1},{"version":"643f7232d07bf75e15bd8f658f664d6183a0efaca5eb84b48201c7671a266979","impliedFormat":1},{"version":"0f6666b58e9276ac3a38fdc80993d19208442d6027ab885580d93aec76b4ef00","impliedFormat":1},{"version":"05fd364b8ef02fb1e174fbac8b825bdb1e5a36a016997c8e421f5fab0a6da0a0","impliedFormat":1},{"version":"631eff75b0e35d1b1b31081d55209abc43e16b49426546ab5a9b40bdd40b1f60","impliedFormat":1},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"b52476feb4a0cbcb25e5931b930fc73cb6643fb1a5060bf8a3dda0eeae5b4b68","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"13f5c844119c43e51ce777c509267f14d6aaf31eafb2c2b002ca35584cd13b29","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"9855e02d837744303391e5623a531734443a5f8e6e8755e018c41d63ad797db2","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"c906fb15bd2aabc9ed1e3f44eb6a8661199d6c320b3aa196b826121552cb3695","impliedFormat":1},{"version":"22295e8103f1d6d8ea4b5d6211e43421fe4564e34d0dd8e09e520e452d89e659","impliedFormat":1},{"version":"58647d85d0f722a1ce9de50955df60a7489f0593bf1a7015521efe901c06d770","impliedFormat":1},{"version":"73b5fa37db36eeac90c4d752e39586f1b57187400c4f5280fd05f16437287a45","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6f137d651076822d4fe884287e68fd61785a0d3d1fdb250a5059b691fa897db","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"bceb58df66ab8fb00170df20cd813978c5ab84be1d285710c4eb005d8e9d8efb","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"814118df420c4e38fe5ae1b9a3bafb6e9c2aa40838e528cde908381867be6466","impliedFormat":1},{"version":"a3fc63c0d7b031693f665f5494412ba4b551fe644ededccc0ab5922401079c95","impliedFormat":1},{"version":"80523c00b8544a2000ae0143e4a90a00b47f99823eb7926c1e03c494216fc363","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"746911b62b329587939560deb5c036aca48aece03147b021fa680223255d5183","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"c8d3e5a18ba35629954e48c4cc8f11dc88224650067a172685c736b27a34a4dc","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"2b55d426ff2b9087485e52ac4bc7cfafe1dc420fc76dad926cd46526567c501a","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"47613031a5a31510831304405af561b0ffaedb734437c595256bb61a90f9311b","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"8a1a0d0a4a06a8d278947fcb66bf684f117bf147f89b06e50662d79a53be3e9f","affectsGlobalScope":true,"impliedFormat":1},{"version":"358765d5ea8afd285d4fd1532e78b88273f18cb3f87403a9b16fef61ac9fdcfe","impliedFormat":1},{"version":"9f55299850d4f0921e79b6bf344b47c420ce0f507b9dcf593e532b09ea7eeea1","impliedFormat":1},{"version":"2beff543f6e9a9701df88daeee3cdd70a34b4a1c11cb4c734472195a5cb2af54","impliedFormat":1},{"version":"2e07abf27aa06353d46f4448c0bbac73431f6065eef7113128a5cd804d0c384d","impliedFormat":1},{"version":"be1cc4d94ea60cbe567bc29ed479d42587bf1e6cba490f123d329976b0fe4ee5","impliedFormat":1},{"version":"42bc0e1a903408137c3df2b06dfd7e402cdab5bbfa5fcfb871b22ebfdb30bd0b","impliedFormat":1},{"version":"9894dafe342b976d251aac58e616ac6df8db91fb9d98934ff9dd103e9e82578f","impliedFormat":1},{"version":"413df52d4ea14472c2fa5bee62f7a40abd1eb49be0b9722ee01ee4e52e63beb2","impliedFormat":1},{"version":"db6d2d9daad8a6d83f281af12ce4355a20b9a3e71b82b9f57cddcca0a8964a96","impliedFormat":1},{"version":"829b9e6028b29e6a8b1c01ddb713efe59da04d857089298fa79acbdb3cfcfdef","impliedFormat":1},{"version":"24f8562308dd8ba6013120557fa7b44950b619610b2c6cb8784c79f11e3c4f90","impliedFormat":1},{"version":"5f90b8c733a1bda63e42160b15a2301051e83a6f9d5332a59d16eb12f463270d","impliedFormat":1},{"version":"a86f82d646a739041d6702101afa82dcb935c416dd93cbca7fd754fd0282ce1f","impliedFormat":1},{"version":"ad0d1d75d129b1c80f911be438d6b61bfa8703930a8ff2be2f0e1f8a91841c64","impliedFormat":1},{"version":"ce75b1aebb33d510ff28af960a9221410a3eaf7f18fc5f21f9404075fba77256","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"496bbf339f3838c41f164238543e9fe5f1f10659cb30b68903851618464b98ba","impliedFormat":1},{"version":"5178eb4415a172c287c711dc60a619e110c3fd0b7de01ed0627e51a5336aa09c","impliedFormat":1},{"version":"ca6e5264278b53345bc1ce95f42fb0a8b733a09e3d6479c6ccfca55cdc45038c","impliedFormat":1},{"version":"9e2739b32f741859263fdba0244c194ca8e96da49b430377930b8f721d77c000","impliedFormat":1},{"version":"fb1d8e814a3eeb5101ca13515e0548e112bd1ff3fb358ece535b93e94adf5a3a","impliedFormat":1},{"version":"ffa495b17a5ef1d0399586b590bd281056cee6ce3583e34f39926f8dcc6ecdb5","impliedFormat":1},{"version":"98b18458acb46072947aabeeeab1e410f047e0cacc972943059ca5500b0a5e95","impliedFormat":1},{"version":"361e2b13c6765d7f85bb7600b48fde782b90c7c41105b7dab1f6e7871071ba20","impliedFormat":1},{"version":"c86fe861cf1b4c46a0fb7d74dffe596cf679a2e5e8b1456881313170f092e3fa","impliedFormat":1},{"version":"b6db56e4903e9c32e533b78ac85522de734b3d3a8541bf24d256058d464bf04b","impliedFormat":1},{"version":"24daa0366f837d22c94a5c0bad5bf1fd0f6b29e1fae92dc47c3072c3fdb2fbd5","impliedFormat":1},{"version":"570bb5a00836ffad3e4127f6adf581bfc4535737d8ff763a4d6f4cc877e60d98","impliedFormat":1},{"version":"889c00f3d32091841268f0b994beba4dceaa5df7573be12c2c829d7c5fbc232c","impliedFormat":1},{"version":"65f43099ded6073336e697512d9b80f2d4fec3182b7b2316abf712e84104db00","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"acf5a2ac47b59ca07afa9abbd2b31d001bf7448b041927befae2ea5b1951d9f9","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"d71291eff1e19d8762a908ba947e891af44749f3a2cbc5bd2ec4b72f72ea795f","impliedFormat":1},{"version":"c0480e03db4b816dff2682b347c95f2177699525c54e7e6f6aa8ded890b76be7","impliedFormat":1},{"version":"27ab780875bcbb65e09da7496f2ca36288b0c541abaa75c311450a077d54ec15","impliedFormat":1},{"version":"b620391fe8060cf9bedc176a4d01366e6574d7a71e0ac0ab344a4e76576fcbb8","impliedFormat":1},{"version":"380647d8f3b7f852cca6d154a376dbf8ac620a2f12b936594504a8a852e71d2f","impliedFormat":1},{"version":"208c9af9429dd3c76f5927b971263174aaa4bc7621ddec63f163640cbd3c473c","impliedFormat":1},{"version":"6459054aabb306821a043e02b89d54da508e3a6966601a41e71c166e4ea1474f","impliedFormat":1},{"version":"a23185bc5ef590c287c28a91baf280367b50ae4ea40327366ad01f6f4a8edbc5","impliedFormat":1},{"version":"bb37588926aba35c9283fe8d46ebf4e79ffe976343105f5c6d45f282793352b2","impliedFormat":1},{"version":"002eae065e6960458bda3cf695e578b0d1e2785523476f8a9170b103c709cd4f","impliedFormat":1},{"version":"c83bb0c9c5645a46c68356c2f73fdc9de339ce77f7f45a954f560c7e0b8d5ebb","impliedFormat":1},{"version":"05c97cddbaf99978f83d96de2d8af86aded9332592f08ce4a284d72d0952c391","impliedFormat":1},{"version":"72179f9dd22a86deaad4cc3490eb0fe69ee084d503b686985965654013f1391b","impliedFormat":1},{"version":"2e6114a7dd6feeef85b2c80120fdbfb59a5529c0dcc5bfa8447b6996c97a69f5","impliedFormat":1},{"version":"7b6ff760c8a240b40dab6e4419b989f06a5b782f4710d2967e67c695ef3e93c4","impliedFormat":1},{"version":"c8f004e6036aa1c764ad4ec543cf89a5c1893a9535c80ef3f2b653e370de45e6","impliedFormat":1},{"version":"dd80b1e600d00f5c6a6ba23f455b84a7db121219e68f89f10552c54ba46e4dc9","impliedFormat":1},{"version":"b064c36f35de7387d71c599bfcf28875849a1dbc733e82bd26cae3d1cd060521","impliedFormat":1},{"version":"6a148329edecbda07c21098639ef4254ef7869fb25a69f58e5d6a8b7b69d4236","impliedFormat":1},{"version":"8de9fe97fa9e00ec00666fa77ab6e91b35d25af8ca75dabcb01e14ad3299b150","impliedFormat":1},{"version":"f63ab283a1c8f5c79fabe7ca4ef85f9633339c4f0e822fce6a767f9d59282af2","impliedFormat":1},{"version":"dba114fb6a32b355a9cfc26ca2276834d72fe0e94cd2c3494005547025015369","impliedFormat":1},{"version":"a54c996c8870ef1728a2c1fa9b8eaec0bf4a8001cd2583c02dd5869289465b10","impliedFormat":1},{"version":"3e7efde639c6a6c3edb9847b3f61e308bf7a69685b92f665048c45132f51c218","impliedFormat":1},{"version":"df45ca1176e6ac211eae7ddf51336dc075c5314bc5c253651bae639defd5eec5","impliedFormat":1},{"version":"3754982006a3b32c502cff0867ca83584f7a43b1035989ca73603f400de13c96","impliedFormat":1},{"version":"a30ae9bb8a8fa7b90f24b8a0496702063ae4fe75deb27da731ed4a03b2eb6631","impliedFormat":1},{"version":"f974e4a06953682a2c15d5bd5114c0284d5abf8bc0fe4da25cb9159427b70072","impliedFormat":1},{"version":"50256e9c31318487f3752b7ac12ff365c8949953e04568009c8705db802776fb","impliedFormat":1},{"version":"7d73b24e7bf31dfb8a931ca6c4245f6bb0814dfae17e4b60c9e194a631fe5f7b","impliedFormat":1},{"version":"413586add0cfe7369b64979d4ec2ed56c3f771c0667fbde1bf1f10063ede0b08","impliedFormat":1},{"version":"06472528e998d152375ad3bd8ebcb69ff4694fd8d2effaf60a9d9f25a37a097a","impliedFormat":1},{"version":"50b5bc34ce6b12eccb76214b51aadfa56572aa6cc79c2b9455cdbb3d6c76af1d","impliedFormat":1},{"version":"b7e16ef7f646a50991119b205794ebfd3a4d8f8e0f314981ebbe991639023d0e","impliedFormat":1},{"version":"42c169fb8c2d42f4f668c624a9a11e719d5d07dacbebb63cbcf7ef365b0a75b3","impliedFormat":1},{"version":"a401617604fa1f6ce437b81689563dfdc377069e4c58465dbd8d16069aede0a5","impliedFormat":1},{"version":"e9dd71cf12123419c60dab867d44fbee5c358169f99529121eaef277f5c83531","impliedFormat":1},{"version":"5b6a189ba3a0befa1f5d9cb028eb9eec2af2089c32f04ff50e2411f63d70f25d","impliedFormat":1},{"version":"d6e73f8010935b7b4c7487b6fb13ea197cc610f0965b759bec03a561ccf8423a","impliedFormat":1},{"version":"174f3864e398f3f33f9a446a4f403d55a892aa55328cf6686135dfaf9e171657","impliedFormat":1},{"version":"824c76aec8d8c7e65769688cbee102238c0ef421ed6686f41b2a7d8e7e78a931","impliedFormat":1},{"version":"75b868be3463d5a8cfc0d9396f0a3d973b8c297401d00bfb008a42ab16643f13","impliedFormat":1},{"version":"15a234e5031b19c48a69ccc1607522d6e4b50f57d308ecb7fe863d44cd9f9eb3","impliedFormat":1},{"version":"d682336018141807fb602709e2d95a192828fcb8d5ba06dda3833a8ea98f69e3","impliedFormat":1},{"version":"6124e973eab8c52cabf3c07575204efc1784aca6b0a30c79eb85fe240a857efa","impliedFormat":1},{"version":"0d891735a21edc75df51f3eb995e18149e119d1ce22fd40db2b260c5960b914e","impliedFormat":1},{"version":"3b414b99a73171e1c4b7b7714e26b87d6c5cb03d200352da5342ab4088a54c85","impliedFormat":1},{"version":"4fbd3116e00ed3a6410499924b6403cc9367fdca303e34838129b328058ede40","impliedFormat":1},{"version":"b01bd582a6e41457bc56e6f0f9de4cb17f33f5f3843a7cf8210ac9c18472fb0f","impliedFormat":1},{"version":"0a437ae178f999b46b6153d79095b60c42c996bc0458c04955f1c996dc68b971","impliedFormat":1},{"version":"74b2a5e5197bd0f2e0077a1ea7c07455bbea67b87b0869d9786d55104006784f","impliedFormat":1},{"version":"4a7baeb6325920044f66c0f8e5e6f1f52e06e6d87588d837bdf44feb6f35c664","impliedFormat":1},{"version":"6dcf60530c25194a9ee0962230e874ff29d34c59605d8e069a49928759a17e0a","impliedFormat":1},{"version":"7274fbffbd7c9589d8d0ffba68157237afd5cecff1e99881ea3399127e60572f","impliedFormat":1},{"version":"1a42d2ec31a1fe62fdc51591768695ed4a2dc64c01be113e7ff22890bebb5e3f","impliedFormat":1},{"version":"1a82deef4c1d39f6882f28d275cad4c01f907b9b39be9cbc472fcf2cf051e05b","impliedFormat":1},{"version":"c5426dbfc1cf90532f66965a7aa8c1136a78d4d0f96d8180ecbfc11d7722f1a5","impliedFormat":1},{"version":"65a15fc47900787c0bd18b603afb98d33ede930bed1798fc984d5ebb78b26cf9","impliedFormat":1},{"version":"9d202701f6e0744adb6314d03d2eb8fc994798fc83d91b691b75b07626a69801","impliedFormat":1},{"version":"de9d2df7663e64e3a91bf495f315a7577e23ba088f2949d5ce9ec96f44fba37d","impliedFormat":1},{"version":"c7af78a2ea7cb1cd009cfb5bdb48cd0b03dad3b54f6da7aab615c2e9e9d570c5","impliedFormat":1},{"version":"1ee45496b5f8bdee6f7abc233355898e5bf9bd51255db65f5ff7ede617ca0027","impliedFormat":1},{"version":"0c7c947ff881c4274c0800deaa0086971e0bfe51f89a33bd3048eaa3792d4876","affectsGlobalScope":true,"impliedFormat":1},{"version":"db01d18853469bcb5601b9fc9826931cc84cc1a1944b33cad76fd6f1e3d8c544","affectsGlobalScope":true,"impliedFormat":1},{"version":"a8f8e6ab2fa07b45251f403548b78eaf2022f3c2254df3dc186cb2671fe4996d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fa6c12a7c0f6b84d512f200690bfc74819e99efae69e4c95c4cd30f6884c526e","impliedFormat":1},{"version":"f1c32f9ce9c497da4dc215c3bc84b722ea02497d35f9134db3bb40a8d918b92b","impliedFormat":1},{"version":"b73c319af2cc3ef8f6421308a250f328836531ea3761823b4cabbd133047aefa","affectsGlobalScope":true,"impliedFormat":1},{"version":"e433b0337b8106909e7953015e8fa3f2d30797cea27141d1c5b135365bb975a6","impliedFormat":1},{"version":"15b36126e0089bfef173ab61329e8286ce74af5e809d8a72edcafd0cc049057f","impliedFormat":1},{"version":"ddff7fc6edbdc5163a09e22bf8df7bef75f75369ebd7ecea95ba55c4386e2441","impliedFormat":1},{"version":"106c6025f1d99fd468fd8bf6e5bda724e11e5905a4076c5d29790b6c3745e50c","impliedFormat":1},{"version":"a57b1802794433adec9ff3fed12aa79d671faed86c49b09e02e1ac41b4f1d33a","impliedFormat":1},{"version":"ad10d4f0517599cdeca7755b930f148804e3e0e5b5a3847adce0f1f71bbccd74","impliedFormat":1},{"version":"1042064ece5bb47d6aba91648fbe0635c17c600ebdf567588b4ca715602f0a9d","impliedFormat":1},{"version":"c49469a5349b3cc1965710b5b0f98ed6c028686aa8450bcb3796728873eb923e","impliedFormat":1},{"version":"4a889f2c763edb4d55cb624257272ac10d04a1cad2ed2948b10ed4a7fda2a428","impliedFormat":1},{"version":"7bb79aa2fead87d9d56294ef71e056487e848d7b550c9a367523ee5416c44cfa","impliedFormat":1},{"version":"72d63643a657c02d3e51cd99a08b47c9b020a565c55f246907050d3c8a5e77fb","impliedFormat":1},{"version":"1d415445ea58f8033ba199703e55ff7483c52ac6742075b803bd3e7bbe9f5d61","impliedFormat":1},{"version":"d6406c629bb3efc31aedb2de809bef471e475c86c7e67f3ef9b676b5d7e0d6b2","impliedFormat":1},{"version":"27ff4196654e6373c9af16b6165120e2dd2169f9ad6abb5c935af5abd8c7938c","impliedFormat":1},{"version":"71d8ba39a9e024d9e4bb922464d18542ed8d2c25ee78efa7890c27213cc6e5d3","impliedFormat":1},{"version":"8c030e515014c10a2b98f9f48408e3ba18023dfd3f56e3312c6c2f3ae1f55a16","impliedFormat":1},{"version":"dafc31e9e8751f437122eb8582b93d477e002839864410ff782504a12f2a550c","impliedFormat":1},{"version":"754498c5208ce3c5134f6eabd49b25cf5e1a042373515718953581636491f3c3","impliedFormat":1},{"version":"9c82171d836c47486074e4ca8e059735bf97b205e70b196535b5efd40cbe1bc5","impliedFormat":1},{"version":"f56bdc6884648806d34bc66d31cdb787c4718d04105ce2cd88535db214631f82","impliedFormat":1},{"version":"633d58a237f4bb25ec7d565e4ffa32cecdcee8660ac12189c4351c52557cee9e","impliedFormat":1},{"version":"2e4f37ffe8862b14d8e24ae8763daaa8340c0df0b859d9a9733def0eee7562d9","impliedFormat":1},{"version":"13283350547389802aa35d9f2188effaeac805499169a06ef5cd77ce2a0bd63f","impliedFormat":1},{"version":"ce791f6ea807560f08065d1af6014581eeb54a05abd73294777a281b6dfd73c2","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"49f95e989b4632c6c2a578cc0078ee19a5831832d79cc59abecf5160ea71abad","impliedFormat":1},{"version":"9666533332f26e8995e4d6fe472bdeec9f15d405693723e6497bf94120c566c8","impliedFormat":1},{"version":"ce0df82a9ae6f914ba08409d4d883983cc08e6d59eb2df02d8e4d68309e7848b","impliedFormat":1},{"version":"796273b2edc72e78a04e86d7c58ae94d370ab93a0ddf40b1aa85a37a1c29ecd7","impliedFormat":1},{"version":"5df15a69187d737d6d8d066e189ae4f97e41f4d53712a46b2710ff9f8563ec9f","impliedFormat":1},{"version":"e17cd049a1448de4944800399daa4a64c5db8657cc9be7ef46be66e2a2cd0e7c","impliedFormat":1},{"version":"43fa6ea8714e18adc312b30450b13562949ba2f205a1972a459180fa54471018","impliedFormat":1},{"version":"6e89c2c177347d90916bad67714d0fb473f7e37fb3ce912f4ed521fe2892cd0d","impliedFormat":1},{"version":"43ba4f2fa8c698f5c304d21a3ef596741e8e85a810b7c1f9b692653791d8d97a","impliedFormat":1},{"version":"4d4927cbee21750904af7acf940c5e3c491b4d5ebc676530211e389dd375607a","impliedFormat":1},{"version":"72105519d0390262cf0abe84cf41c926ade0ff475d35eb21307b2f94de985778","impliedFormat":1},{"version":"8a97e578a9bc40eb4f1b0ca78f476f2e9154ecbbfd5567ee72943bab37fc156a","impliedFormat":1},{"version":"c857e0aae3f5f444abd791ec81206020fbcc1223e187316677e026d1c1d6fe08","impliedFormat":1},{"version":"ccf6dd45b708fb74ba9ed0f2478d4eb9195c9dfef0ff83a6092fa3cf2ff53b4f","impliedFormat":1},{"version":"2d7db1d73456e8c5075387d4240c29a2a900847f9c1bff106a2e490da8fbd457","impliedFormat":1},{"version":"2b15c805f48e4e970f8ec0b1915f22d13ca6212375e8987663e2ef5f0205e832","impliedFormat":1},{"version":"f22d05663d873ee7a600faf78abb67f3f719d32266803440cf11d5db7ac0cab2","impliedFormat":1},{"version":"d93c544ad20197b3976b0716c6d5cd5994e71165985d31dcab6e1f77feb4b8f2","impliedFormat":1},{"version":"35069c2c417bd7443ae7c7cafd1de02f665bf015479fec998985ffbbf500628c","impliedFormat":1},{"version":"a8b1c79a833ee148251e88a2553d02ce1641d71d2921cce28e79678f3d8b96aa","impliedFormat":1},{"version":"126d4f950d2bba0bd45b3a86c76554d4126c16339e257e6d2fabf8b6bf1ce00c","impliedFormat":1},{"version":"7e0b7f91c5ab6e33f511efc640d36e6f933510b11be24f98836a20a2dc914c2d","impliedFormat":1},{"version":"045b752f44bf9bbdcaffd882424ab0e15cb8d11fa94e1448942e338c8ef19fba","impliedFormat":1},{"version":"2894c56cad581928bb37607810af011764a2f511f575d28c9f4af0f2ef02d1ab","impliedFormat":1},{"version":"0a72186f94215d020cb386f7dca81d7495ab6c17066eb07d0f44a5bf33c1b21a","impliedFormat":1},{"version":"2d3cc2211f352f46ea6b7cf2c751c141ffcdf514d6e7ae7ee20b7b6742da313f","impliedFormat":1},{"version":"c75445151ff8b77d9923191efed7203985b1a9e09eccf4b054e7be864e27923d","impliedFormat":1},{"version":"0aedb02516baf3e66b2c1db9fef50666d6ed257edac0f866ea32f1aa05aa474f","impliedFormat":1},{"version":"fa8a8fbf91ee2a4779496225f0312aac6635b0f21aa09cdafa4283fe32d519c5","affectsGlobalScope":true,"impliedFormat":1},{"version":"0e8aef93d79b000deb6ec336b5645c87de167168e184e84521886f9ecc69a4b5","impliedFormat":1},{"version":"56ccb49443bfb72e5952f7012f0de1a8679f9f75fc93a5c1ac0bafb28725fc5f","impliedFormat":1},{"version":"20fa37b636fdcc1746ea0738f733d0aed17890d1cd7cb1b2f37010222c23f13e","impliedFormat":1},{"version":"d90b9f1520366d713a73bd30c5a9eb0040d0fb6076aff370796bc776fd705943","impliedFormat":1},{"version":"bc03c3c352f689e38c0ddd50c39b1e65d59273991bfc8858a9e3c0ebb79c023b","impliedFormat":1},{"version":"19df3488557c2fc9b4d8f0bac0fd20fb59aa19dec67c81f93813951a81a867f8","affectsGlobalScope":true,"impliedFormat":1},{"version":"b25350193e103ae90423c5418ddb0ad1168dc9c393c9295ef34980b990030617","affectsGlobalScope":true,"impliedFormat":1},{"version":"bef86adb77316505c6b471da1d9b8c9e428867c2566270e8894d4d773a1c4dc2","impliedFormat":1},{"version":"de7052bfee2981443498239a90c04ea5cc07065d5b9bb61b12cb6c84313ad4ef","impliedFormat":1},{"version":"a3e7d932dc9c09daa99141a8e4800fc6c58c625af0d4bbb017773dc36da75426","impliedFormat":1},{"version":"43e96a3d5d1411ab40ba2f61d6a3192e58177bcf3b133a80ad2a16591611726d","impliedFormat":1},{"version":"4a2edd238d9104eac35b60d727f1123de5062f452b70ed8e0366cb36387dfdfd","impliedFormat":1},{"version":"ca921bf56756cb6fe957f6af693a35251b134fb932dc13f3dfff0bb7106f80b4","impliedFormat":1},{"version":"fee92c97f1aa59eb7098a0cc34ff4df7e6b11bae71526aca84359a2575f313d8","impliedFormat":1},{"version":"0bd0297484aacea217d0b76e55452862da3c5d9e33b24430e0719d1161657225","impliedFormat":1},{"version":"2ab6d334bcbf2aff3acfc4fd8c73ecd82b981d3c3aa47b3f3b89281772286904","impliedFormat":1},{"version":"d07cbc787a997d83f7bde3877fec5fb5b12ce8c1b7047eb792996ed9726b4dde","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"4805f6161c2c8cefb8d3b8bd96a080c0fe8dbc9315f6ad2e53238f9a79e528a6","impliedFormat":1},{"version":"b83cb14474fa60c5f3ec660146b97d122f0735627f80d82dd03e8caa39b4388c","impliedFormat":1},{"version":"f374cb24e93e7798c4d9e83ff872fa52d2cdb36306392b840a6ddf46cb925cb6","impliedFormat":1},{"version":"49179c6a23701c642bd99abe30d996919748014848b738d8e85181fc159685ff","impliedFormat":1},{"version":"b73cbf0a72c8800cf8f96a9acfe94f3ad32ca71342a8908b8ae484d61113f647","impliedFormat":1},{"version":"bae6dd176832f6423966647382c0d7ba9e63f8c167522f09a982f086cd4e8b23","impliedFormat":1},{"version":"20865ac316b8893c1a0cc383ccfc1801443fbcc2a7255be166cf90d03fac88c9","impliedFormat":1},{"version":"c9958eb32126a3843deedda8c22fb97024aa5d6dd588b90af2d7f2bfac540f23","impliedFormat":1},{"version":"461d0ad8ae5f2ff981778af912ba71b37a8426a33301daa00f21c6ccb27f8156","impliedFormat":1},{"version":"e927c2c13c4eaf0a7f17e6022eee8519eb29ef42c4c13a31e81a611ab8c95577","impliedFormat":1},{"version":"fcafff163ca5e66d3b87126e756e1b6dfa8c526aa9cd2a2b0a9da837d81bbd72","impliedFormat":1},{"version":"70246ad95ad8a22bdfe806cb5d383a26c0c6e58e7207ab9c431f1cb175aca657","impliedFormat":1},{"version":"f00f3aa5d64ff46e600648b55a79dcd1333458f7a10da2ed594d9f0a44b76d0b","impliedFormat":1},{"version":"772d8d5eb158b6c92412c03228bd9902ccb1457d7a705b8129814a5d1a6308fc","impliedFormat":1},{"version":"45490817629431853543adcb91c0673c25af52a456479588b6486daba34f68bb","impliedFormat":1},{"version":"802e797bcab5663b2c9f63f51bdf67eff7c41bc64c0fd65e6da3e7941359e2f7","impliedFormat":1},{"version":"8b4327413e5af38cd8cb97c59f48c3c866015d5d642f28518e3a891c469f240e","impliedFormat":1},{"version":"8514c62ce38e58457d967e9e73f128eedc1378115f712b9eef7127f7c88f82ae","impliedFormat":1},{"version":"f1289e05358c546a5b664fbb35a27738954ec2cc6eb4137350353099d154fc62","impliedFormat":1},{"version":"4b20fcf10a5413680e39f5666464859fc56b1003e7dfe2405ced82371ebd49b6","impliedFormat":1},{"version":"1d17ba45cfbe77a9c7e0df92f7d95f3eefd49ee23d1104d0548b215be56945ad","impliedFormat":1},{"version":"f7d628893c9fa52ba3ab01bcb5e79191636c4331ee5667ecc6373cbccff8ae12","impliedFormat":1},{"version":"1d879125d1ec570bf04bc1f362fdbe0cb538315c7ac4bcfcdf0c1e9670846aa6","impliedFormat":1},{"version":"bd5f641cc4616eee49497a362c4cb401e9346265bc52670448c4452b4d9be401","impliedFormat":1},{"version":"46273e8c29816125d0d0b56ce9a849cc77f60f9a5ba627447501d214466f0ff3","impliedFormat":1},{"version":"d663134457d8d669ae0df34eabd57028bddc04fc444c4bc04bc5215afc91e1f4","impliedFormat":1},{"version":"e91f7b1344577a02f051b9b471f33044fef8334a76dc9e1de003d17595a5219b","impliedFormat":1},{"version":"3af3584f79c57853028ef9421ec172539e1fe01853296dc05a9d615ade4ffaf6","impliedFormat":1},{"version":"f82579d87701d639ff4e3930a9b24f4ee13ca74221a9a3a792feb47f01881a9c","impliedFormat":1},{"version":"d7e5d5245a8ba34a274717d085174b2c9827722778129b0081fefd341cca8f55","impliedFormat":1},{"version":"d9d32f94056181c31f553b32ce41d0ef75004912e27450738d57efcd2409c324","impliedFormat":1},{"version":"752513f35f6cff294ffe02d6027c41373adf7bfa35e593dbfd53d95c203635ee","impliedFormat":1},{"version":"6c800b281b9e89e69165fd11536195488de3ff53004e55905e6c0059a2d8591e","impliedFormat":1},{"version":"7d4254b4c6c67a29d5e7f65e67d72540480ac2cfb041ca484847f5ae70480b62","impliedFormat":1},{"version":"1a7e2ea171726446850ec72f4d1525d547ff7e86724cc9e7eec509725752a758","impliedFormat":1},{"version":"8c901126d73f09ecdea4785e9a187d1ac4e793e07da308009db04a7283ec2f37","impliedFormat":1},{"version":"c1de754ab5f3b0f4036d6893c74a0fc984c7fcb07936086f19bbe2974406775b","impliedFormat":1},{"version":"aab290b8e4b7c399f2c09b957666fc95335eb4522b2dd9ead1bf0cb64da6d6ee","impliedFormat":1},{"version":"94fe3281392e1015b22f39535878610b4fa6f1388dc8d78746be3bc4e4bb8950","impliedFormat":1},{"version":"2652448ac55a2010a1f71dd141f828b682298d39728f9871e1cdf8696ef443fd","impliedFormat":1},{"version":"06c25ddfc2242bd06c19f66c9eae4c46d937349a267810f89783680a1d7b5259","impliedFormat":1},{"version":"120599fd965257b1f4d0ff794bc696162832d9d8467224f4665f713a3119078b","impliedFormat":1},{"version":"5433f33b0a20300cca35d2f229a7fc20b0e8477c44be2affeb21cb464af60c76","impliedFormat":1},{"version":"db036c56f79186da50af66511d37d9fe77fa6793381927292d17f81f787bb195","impliedFormat":1},{"version":"bd4131091b773973ca5d2326c60b789ab1f5e02d8843b3587effe6e1ea7c9d86","impliedFormat":1},{"version":"c7f6485931085bf010fbaf46880a9b9ec1a285ad9dc8c695a9e936f5a48f34b4","impliedFormat":1},{"version":"14f6b927888a1112d662877a5966b05ac1bf7ed25d6c84386db4c23c95a5363b","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"0427df5c06fafc5fe126d14b9becd24160a288deff40e838bfbd92a35f8d0d00","impliedFormat":1},{"version":"90c54a02432d04e4246c87736e53a6a83084357acfeeba7a489c5422b22f5c7a","impliedFormat":1},{"version":"49c346823ba6d4b12278c12c977fb3a31c06b9ca719015978cb145eb86da1c61","impliedFormat":1},{"version":"bfac6e50eaa7e73bb66b7e052c38fdc8ccfc8dbde2777648642af33cf349f7f1","impliedFormat":1},{"version":"92f7c1a4da7fbfd67a2228d1687d5c2e1faa0ba865a94d3550a3941d7527a45d","impliedFormat":1},{"version":"f53b120213a9289d9a26f5af90c4c686dd71d91487a0aa5451a38366c70dc64b","impliedFormat":1},{"version":"83fe880c090afe485a5c02262c0b7cdd76a299a50c48d9bde02be8e908fb4ae6","impliedFormat":1},{"version":"0a372c2d12a259da78e21b25974d2878502f14d89c6d16b97bd9c5017ab1bc12","impliedFormat":1},{"version":"57d67b72e06059adc5e9454de26bbfe567d412b962a501d263c75c2db430f40e","impliedFormat":1},{"version":"6511e4503cf74c469c60aafd6589e4d14d5eb0a25f9bf043dcbecdf65f261972","impliedFormat":1},{"version":"ec1ca97598eda26b7a5e6c8053623acbd88e43be7c4d29c77ccd57abc4c43999","impliedFormat":1},{"version":"6e2261cd9836b2c25eecb13940d92c024ebed7f8efe23c4b084145cd3a13b8a6","impliedFormat":1},{"version":"a67b87d0281c97dfc1197ef28dfe397fc2c865ccd41f7e32b53f647184cc7307","impliedFormat":1},{"version":"771ffb773f1ddd562492a6b9aaca648192ac3f056f0e1d997678ff97dbb6bf9b","impliedFormat":1},{"version":"232f70c0cf2b432f3a6e56a8dc3417103eb162292a9fd376d51a3a9ea5fbbf6f","impliedFormat":1},{"version":"a47e6d954d22dd9ebb802e7e431b560ed7c581e79fb885e44dc92ed4f60d4c07","impliedFormat":1},{"version":"f019e57d2491c159d47a107fd90219a1734bdd2e25cd8d1db3c8fae5c6b414c4","impliedFormat":1},{"version":"8a0e762ceb20c7e72504feef83d709468a70af4abccb304f32d6b9bac1129b2c","impliedFormat":1},{"version":"d1c9bf292a54312888a77bb19dba5e2503ad803f5393beafd45d78d2f4fe9b48","impliedFormat":1},{"version":"9252d498a77517aab5d8d4b5eb9d71e4b225bbc7123df9713e08181de63180f6","impliedFormat":1},{"version":"cb8d8ef7b9ce8ed3e6f1c814fcbf3f90dab0cb8863079236784fc350746e27c4","impliedFormat":1},{"version":"35e6379c3f7cb27b111ad4c1aa69538fd8e788ab737b8ff7596a1b40e96f4f90","impliedFormat":1},{"version":"1fffe726740f9787f15b532e1dc870af3cd964dbe29e191e76121aa3dd8693f2","impliedFormat":1},{"version":"3be035da7bee86b4c3abf392e0edaa44fc6e45092995eefe36b39118c8a84068","affectsGlobalScope":true,"impliedFormat":1},{"version":"8f828825d077c2fa0ea606649faeb122749273a353daab23924fe674e98ba44c","impliedFormat":1},{"version":"2896c2e673a5d3bd9b4246811f79486a073cbb03950c3d252fba10003c57411a","impliedFormat":1},{"version":"616775f16134fa9d01fc677ad3f76e68c051a056c22ab552c64cc281a9686790","impliedFormat":1},{"version":"65c24a8baa2cca1de069a0ba9fba82a173690f52d7e2d0f1f7542d59d5eb4db0","impliedFormat":1},{"version":"f9fe6af238339a0e5f7563acee3178f51db37f32a2e7c09f85273098cee7ec49","impliedFormat":1},{"version":"407a06ba04eede4074eec470ecba2784cbb3bf4e7de56833b097dd90a2aa0651","impliedFormat":1},{"version":"77e71242e71ebf8528c5802993697878f0533db8f2299b4d36aa015bae08a79c","impliedFormat":1},{"version":"98a787be42bd92f8c2a37d7df5f13e5992da0d967fab794adbb7ee18370f9849","impliedFormat":1},{"version":"5c96bad5f78466785cdad664c056e9e2802d5482ca5f862ed19ba34ffbb7b3a4","impliedFormat":1},{"version":"81d8603ac527e75cfec72bb9391228b58f161c2b33514a9d814c7f3ebd3ef466","impliedFormat":1},{"version":"5f3dc10ae646f375776b4e028d2bed039a93eebbba105694d8b910feebbe8b9c","impliedFormat":1},{"version":"bb0cd7862b72f5eba39909c9889d566e198fcaddf7207c16737d0c2246112678","impliedFormat":1},{"version":"4545c1a1ceca170d5d83452dd7c4994644c35cf676a671412601689d9a62da35","impliedFormat":1},{"version":"320f4091e33548b554d2214ce5fc31c96631b513dffa806e2e3a60766c8c49d9","impliedFormat":1},{"version":"a2d648d333cf67b9aeac5d81a1a379d563a8ffa91ddd61c6179f68de724260ff","impliedFormat":1},{"version":"d90d5f524de38889d1e1dbc2aeef00060d779f8688c02766ddb9ca195e4a713d","impliedFormat":1},{"version":"a3f41ed1b4f2fc3049394b945a68ae4fdefd49fa1739c32f149d32c0545d67f5","impliedFormat":1},{"version":"bad68fd0401eb90fe7da408565c8aee9c7a7021c2577aec92fa1382e8876071a","impliedFormat":1},{"version":"47699512e6d8bebf7be488182427189f999affe3addc1c87c882d36b7f2d0b0e","impliedFormat":1},{"version":"fec01479923e169fb52bd4f668dbeef1d7a7ea6e6d491e15617b46f2cacfa37d","impliedFormat":1},{"version":"8a8fb3097ba52f0ae6530ec6ab34e43e316506eb1d9aa29420a4b1e92a81442d","impliedFormat":1},{"version":"44e09c831fefb6fe59b8e65ad8f68a7ecc0e708d152cfcbe7ba6d6080c31c61e","impliedFormat":1},{"version":"1c0a98de1323051010ce5b958ad47bc1c007f7921973123c999300e2b7b0ecc0","impliedFormat":1},{"version":"4655709c9cb3fd6db2b866cab7c418c40ed9533ce8ea4b66b5f17ec2feea46a9","impliedFormat":1},{"version":"87affad8e2243635d3a191fa72ef896842748d812e973b7510a55c6200b3c2a4","impliedFormat":1},{"version":"ad036a85efcd9e5b4f7dd5c1a7362c8478f9a3b6c3554654ca24a29aa850a9c5","impliedFormat":1},{"version":"fedebeae32c5cdd1a85b4e0504a01996e4a8adf3dfa72876920d3dd6e42978e7","impliedFormat":1},{"version":"3eecb25bb467a948c04874d70452b14ae7edb707660aac17dc053e42f2088b00","impliedFormat":1},{"version":"cdf21eee8007e339b1b9945abf4a7b44930b1d695cc528459e68a3adc39a622e","impliedFormat":1},{"version":"330896c1a2b9693edd617be24fbf9e5895d6e18c7955d6c08f028f272b37314d","impliedFormat":1},{"version":"1d9c0a9a6df4e8f29dc84c25c5aa0bb1da5456ebede7a03e03df08bb8b27bae6","impliedFormat":1},{"version":"84380af21da938a567c65ef95aefb5354f676368ee1a1cbb4cae81604a4c7d17","impliedFormat":1},{"version":"1af3e1f2a5d1332e136f8b0b95c0e6c0a02aaabd5092b36b64f3042a03debf28","impliedFormat":1},{"version":"30d8da250766efa99490fc02801047c2c6d72dd0da1bba6581c7e80d1d8842a4","impliedFormat":1},{"version":"03566202f5553bd2d9de22dfab0c61aa163cabb64f0223c08431fb3fc8f70280","impliedFormat":1},{"version":"5f0292a40df210ab94b9fb44c8b775c51e96777e14e073900e392b295ca1061b","impliedFormat":1},{"version":"bc9ee0192f056b3d5527bcd78dc3f9e527a9ba2bdc0a2c296fbc9027147df4b2","impliedFormat":1},{"version":"8627ad129bcf56e82adff0ab5951627c993937aa99f5949c33240d690088b803","impliedFormat":1},{"version":"1de80059b8078ea5749941c9f863aa970b4735bdbb003be4925c853a8b6b4450","impliedFormat":1},{"version":"1d079c37fa53e3c21ed3fa214a27507bda9991f2a41458705b19ed8c2b61173d","impliedFormat":1},{"version":"5bf5c7a44e779790d1eb54c234b668b15e34affa95e78eada73e5757f61ed76a","impliedFormat":1},{"version":"5835a6e0d7cd2738e56b671af0e561e7c1b4fb77751383672f4b009f4e161d70","impliedFormat":1},{"version":"5c634644d45a1b6bc7b05e71e05e52ec04f3d73d9ac85d5927f647a5f965181a","impliedFormat":1},{"version":"4b7f74b772140395e7af67c4841be1ab867c11b3b82a51b1aeb692822b76c872","impliedFormat":1},{"version":"27be6622e2922a1b412eb057faa854831b95db9db5035c3f6d4b677b902ab3b7","impliedFormat":1},{"version":"a68d4b3182e8d776cdede7ac9630c209a7bfbb59191f99a52479151816ef9f9e","impliedFormat":99},{"version":"39644b343e4e3d748344af8182111e3bbc594930fff0170256567e13bbdbebb0","impliedFormat":99},{"version":"ed7fd5160b47b0de3b1571c5c5578e8e7e3314e33ae0b8ea85a895774ee64749","impliedFormat":99},{"version":"63a7595a5015e65262557f883463f934904959da563b4f788306f699411e9bac","impliedFormat":1},{"version":"ecbaf0da125974be39c0aac869e403f72f033a4e7fd0d8cd821a8349b4159628","impliedFormat":1},{"version":"4ba137d6553965703b6b55fd2000b4e07ba365f8caeb0359162ad7247f9707a6","impliedFormat":1},{"version":"ceec3c81b2d81f5e3b855d9367c1d4c664ab5046dff8fd56552df015b7ccbe8f","affectsGlobalScope":true,"impliedFormat":1},{"version":"8fac4a15690b27612d8474fb2fc7cc00388df52d169791b78d1a3645d60b4c8b","affectsGlobalScope":true,"impliedFormat":1},{"version":"064ac1c2ac4b2867c2ceaa74bbdce0cb6a4c16e7c31a6497097159c18f74aa7c","impliedFormat":1},{"version":"3dc14e1ab45e497e5d5e4295271d54ff689aeae00b4277979fdd10fa563540ae","impliedFormat":1},{"version":"1d63055b690a582006435ddd3aa9c03aac16a696fac77ce2ed808f3e5a06efab","impliedFormat":1},{"version":"b789bf89eb19c777ed1e956dbad0925ca795701552d22e68fd130a032008b9f9","impliedFormat":1},"f4e8976c19fc926644d72610bf1058bd6bf52add97e46a02bc0b912a751625c0",{"version":"c14bf5b7270b58ce2d96aadad2a3ce80b4b783bdc6caa7f7d765d09cc0b95e3e","signature":"435a1e418e8338be3f39614b96b81a9aa2700bc8c27bc6b98f064ff9ce17c363"},{"version":"c76c02846ba7d40b9b3488f0e8d75d02cbdee2f0bc5fcd55dd3bd2e1457646ea","impliedFormat":99},{"version":"4ead13a482c539b77394b2a97e3b877b809eac596390371cea490286f53b996a","impliedFormat":99},{"version":"06db2f8ba1d1dfacf04529cb731081ab23f133f29c7608ebdfbcab356996827c","impliedFormat":99},{"version":"bdd14f07b4eca0b4b5203b85b8dbc4d084c749fa590bee5ea613e1641dcd3b29","impliedFormat":99},{"version":"3a582c6e8906f5b094ccf0de6cc6f4f8a54b05a34f52517aba5c9c7f704f6b28","impliedFormat":99},{"version":"ef13c73d6157a32933c612d476c1524dd674cf5b9a88571d7d6a0d147544d529","impliedFormat":99},{"version":"49ab4f1d153a252779958fc87b700743d32b5ffa42addd70ae23ad3f429daa5c","impliedFormat":99},{"version":"0528f6d21f7a02d4092895090d2dd86104bd5a3e79eced96d5a1a7dd90943d17","impliedFormat":99},{"version":"427fe2004642504828c1476d0af4270e6ad4db6de78c0b5da3e4c5ca95052a99","impliedFormat":1},{"version":"2eeffcee5c1661ddca53353929558037b8cf305ffb86a803512982f99bcab50d","impliedFormat":99},{"version":"9afb4cb864d297e4092a79ee2871b5d3143ea14153f62ef0bb04ede25f432030","affectsGlobalScope":true,"impliedFormat":99},{"version":"5c935b7fc4ddc1410ea1cd7cd4e35ed106a6e4920dd27a9480a40fd224359dc3","affectsGlobalScope":true,"impliedFormat":99},{"version":"3b89216a7e38a454985ad17bb2ff85792837dc812f2a89fa5f60ad0a2e216fa7","impliedFormat":99},{"version":"16fe60bb544cfedfd2b5bb2f7d0b3957be7978706d57d9f06edc9c0c8dbdba23","impliedFormat":99},{"version":"de4a612aa8f1704af486f701e21993c786ba7d8cfed55fffa6684026aea2346e","impliedFormat":99},{"version":"c73fdf42528325dd17940937ed787b15ae3445c6a2dae1a2b74bc4d87d337ca2","impliedFormat":99},{"version":"e8e17dfef3cfa9f0847ac93dd535a9896af7fb57c1a1b164484bb1b0ee4a25d8","impliedFormat":99},{"version":"7f2bb8f9aba83e5f5952cf362e405452e02ff420667434021e9a8be095b15fc1","impliedFormat":99},{"version":"638a22f8e16b31c37297483fa38cfc760ed309b16d4c606a7b4532f4394c9c0c","impliedFormat":99},{"version":"9394183f4c37b8591156f32e41223c9e0dd211eefe7499155d4cdf15268eaea8","impliedFormat":99},{"version":"cb9b6d9e3f32decbd816ffb20a392fe774ba7a2bd615b5c22ce645312f703ef0","impliedFormat":99},{"version":"b333e679ec61ac6bc9e696bf9adac47b20701568697f1a0e2a05674f97e02f5d","impliedFormat":99},{"version":"ac7293557679952437466a41e6e8a47614cb99a51d0440fc36ac7aa02d44ab93","impliedFormat":99},{"version":"7d3e062a778b8f5ea4f0cac7e925e31f88e6739812ebc5f827474324a4048f14","impliedFormat":99},{"version":"be030f8dc45fded610c82e51642b195a3dc80fa0ec63e1b822425050e1b04743","impliedFormat":99},{"version":"8c1fb5394cc1cf2943fa7a294632a4a24eb4fbd4a68aee00131dc93c02d2de09","impliedFormat":99},{"version":"f232e7548dd00bc8631f61bf8b0259288a3b68a21023f1f177427c05d905446b","impliedFormat":99},{"version":"2dca43f25e917d7f01f2963e665852c92ca18b2f939694cbfdc87c503210c0a6","impliedFormat":99},{"version":"4e003c868b0d8f8ad200b96cbc653e18e513fa23e1c19c4fe3cc25d4394efc47","impliedFormat":99},{"version":"8887e70871f697fa42ad7cdf32168db60ec2d6760c173c97973e35377fe5d83b","impliedFormat":99},{"version":"e0864480ea083087d705f9405bd6bf59b795e8474c3447f0d6413b2bce535a09","impliedFormat":99},{"version":"e67cbea16f1994af89efd700542dbf3828a46a52b29e4d67e801bd7869dc103c","impliedFormat":99},{"version":"f582b0fcbf1eea9b318ab92fb89ea9ab2ebb84f9b60af89328a91155e1afce72","impliedFormat":99},{"version":"402e5c534fb2b85fa771170595db3ac0dd532112c8fa44fc23f233bc6967488b","impliedFormat":1},{"version":"52dcc257df5119fb66d864625112ce5033ac51a4c2afe376a0b299d2f7f76e4a","impliedFormat":1},{"version":"e5bab5f871ef708d52d47b3e5d0aa72a08ee7a152f33931d9a60809711a2a9a3","impliedFormat":1},{"version":"e16dc2a81595736024a206c7d5c8a39bfe2e6039208ef29981d0d95434ba8fcf","impliedFormat":1},{"version":"cc4a4903fb698ca1d961d4c10dce658aa3a479faf40509d526f122b044eaf6a4","impliedFormat":1},{"version":"19ee8416e6473ed6c7adb868fa796b5653cf0fa2a337658e677eaa0d134388c3","impliedFormat":1},{"version":"1328ab4e442614b28cdb3d4b414cf68325c0da0dca07287a338d0654b7a00261","impliedFormat":1},{"version":"a039dc21f045919f3cbee2ec13812cc6cc3eebc99dae4be00973230f468d19a6","impliedFormat":1},{"version":"3fbe57af01460e49dcd29df55d6931e1672bc6f1be0fb073d11410bc16f9037d","impliedFormat":1},{"version":"f760be449e8562ec5c09bb5187e8e1eabf3c113c0c58cddda53ef8c69f3e2131","impliedFormat":1},{"version":"44325ed13294fce6ab825b82947bbeed2611db7dad9d9135260192f375e5a189","impliedFormat":1},{"version":"e392e8fb5b514eafc585601c1d781485aa6dd6a320e75daf1064a4c6918a1b45","impliedFormat":1},{"version":"46e4a36e8ddbdfb4e7330e11c81c970dc8b218611df9183d39c41c5f8c653b55","impliedFormat":1},{"version":"370bde134aa8c2abc926d0e99d3a4d5d5dba65c6ee65459137e4f02670cbf841","impliedFormat":1},{"version":"6332f565867cf4a740a70e30f31cefba37ef7cebcf74f22eab8d744fde6d193e","impliedFormat":1},{"version":"2977b7884aedc895a1d0c9c210c7cf3272c29d6959a08a6fa3ff71e0aff08175","impliedFormat":1},{"version":"17f2922d41ddd032830a91371c948cd9ce903b35c95adca72271a54584f19b0b","impliedFormat":1},{"version":"3eed76ede2a1a14d7c9bb0a642041282dcc264811139d3dd275c9fe14efc9840","impliedFormat":1},{"version":"e3cf0611709328b449ec13f8c436712d62003620ce480139fae46ce001c2ee9f","impliedFormat":1},{"version":"8d369483f0c2b9ee388129cfdb6a43bc8112b377e86a41884bd06e19ce04f4c1","impliedFormat":99},{"version":"3fd8a5aefd8c3feb3936ca66f5aa89dff7bf6e6537b4158dbd0f6e0d65ed3b9e","impliedFormat":1},{"version":"a18642ddf216f162052a16cba0944892c4c4c977d3306a87cb673d46abbb0cbf","impliedFormat":1},{"version":"41c41c6e90133bb2a14f7561f29944771886e5535945b2b372e2f6ed6987746e","impliedFormat":1},{"version":"4ec16d7a4e366c06a4573d299e15fe6207fc080f41beac5da06f4af33ea9761e","impliedFormat":99},{"version":"960bd764c62ac43edc24eaa2af958a4b4f1fa5d27df5237e176d0143b36a39c6","affectsGlobalScope":true,"impliedFormat":99},{"version":"c765b3bfab230cec7c051c6d90880270d3846746a186d2d02729fc7b10abf5a2","impliedFormat":99},{"version":"59f8dc89b9e724a6a667f52cdf4b90b6816ae6c9842ce176d38fcc973669009e","affectsGlobalScope":true,"impliedFormat":99},{"version":"a29a1d34dc79bdd96b6f8a9bf529199f8811b3d22f0c8be12c28c9898f9b383a","impliedFormat":99},{"version":"b5ce343886d23392be9c8280e9f24a87f1d7d3667f6672c2fe4aa61fa4ece7d4","impliedFormat":99},{"version":"72ce5b734c05da85c85a6f6dc05823b051d6aa41acaedeeb1d17c72f3b4efa72","impliedFormat":99},{"version":"b0857bb28fd5236ace84280f79a25093f919fd0eff13e47cc26ea03de60a7294","impliedFormat":99},{"version":"5e43e0824f10cd8c48e7a8c5c673638488925a12c31f0f9e0957965c290eb14c","impliedFormat":99},{"version":"53cf4076f42b29b8d411259d168d51b3a0274c42c8814e5b44dfa8803a35d4fc","impliedFormat":99},{"version":"a39461ee1f27cf3e6cfd63d21045713d26d521da55ea4d8efccb705f689e6dbb","impliedFormat":99},{"version":"61bb64660ee150f3ab618340e15cca0a81664801bede7c966ca0eca3a952fe63","impliedFormat":99},{"version":"42a12f2faa483c9b48195ed794d22698162274e755f6e07219c2351c4f08d732","impliedFormat":99},{"version":"ec0c42bb0f465e4993f2bc68a6ce9df9a2dcbc7b83e21748f82f1b69561938e3","impliedFormat":99},{"version":"f50ff37a9cbbe74475f426474d9827083c7c2c138a954d28f1690df338f69291","impliedFormat":99},{"version":"61fd6c17235d530c40f543dd7c40afab091d91c1ef890baeed30db6d82b04b28","impliedFormat":99},{"version":"bcbd3becd08b4515225880abea0dbfbbf0d1181ce3af8f18f72f61edbe4febfb","impliedFormat":99},{"version":"091767bc841f937654ed597d49e023ed59850355e746ae1a6f20ab31076ee1fb","impliedFormat":99},{"version":"19c6d6135af59693698d384050b45a8a049493500add442f58e4bd7c8a255ab6","impliedFormat":99},{"version":"6a0dba12d55314638a8c51108b20fe2f68f1364a619d098918bda91c22dec154","impliedFormat":99},{"version":"8124828a11be7db984fcdab052fd4ff756b18edcfa8d71118b55388176210923","impliedFormat":99},{"version":"2b39c6cf59088713babbfc3e20ee85f1375d40e66953156fa658346b8346f24f","impliedFormat":99},{"version":"69bf2422313487956e4dacf049f30cb91b34968912058d244cb19e4baa24da97","impliedFormat":99},{"version":"6987dfb4b0c4e02112cc4e548e7a77b3d9ddfeffa8c8a2db13ceac361a4567d9","impliedFormat":99},{"version":"5e2ba3d18d78aebbde1f34bde356e41e9c76eeaeaeee56a37036596a9eff4211","impliedFormat":99},{"version":"8280ae8ccc0493b32d1742d585357ab9f0a508ea050af25a5a20d64010d0a5cf","impliedFormat":99},{"version":"7adfd9f9056ecd4ae6c65fde2a98654960c662714c73f048478959d04c09e144","impliedFormat":99},{"version":"437b7613a30a2fcde463f7b707c6d5567a8823fbc51de50b8641bf5b1d126fad","impliedFormat":99},{"version":"63ea959e28c110923f495576e614fb8b36c09b6828b467b2c7cd7f03b03ccf9f","impliedFormat":99},{"version":"1601a95dbb33059fc3d12638ed2a9aecff899e339c5c0f3a0b28768866d385b4","impliedFormat":99},{"version":"56fc978580577d30f4c2cdb5b1eb9217b66ed66537dd27141256f426e4b8dd68","impliedFormat":99},{"version":"2c5413050a2580becf9d82dd7e3006b95623e96f145356bf73230cd635352f70","impliedFormat":99},{"version":"860bedc71ead192ea4a0ea5ef4686e65724d14b391ebd1a6671a7044e6bd8e15","impliedFormat":99},{"version":"7c0a845bee4a084cbb8654709f48e5f13e2f6d45e5e2dde7c57cadf79fd9e3d5","impliedFormat":99},{"version":"a9c8214ef27f5762c807802fd468b50fafae5c909d4376b67b3bfccaf8f99e13","impliedFormat":99},{"version":"94c8f4fa20a287054630c9521a9c5c7e8f74e806bcc8444503b6dc378853dd09","impliedFormat":99},{"version":"174e5bf2d8c80c676eb42959eaac341892bd946f18b68d2f5efe99a38b152fb3","impliedFormat":99},{"version":"7bbff6783e96c691a41a7cf12dd5486b8166a01b0c57d071dbcfca55c9525ec4","impliedFormat":99},{"version":"a3ded4dbeb73f96c973db537ac048d255af536e52a500acc21339ce003378de8","signature":"4b96dd19fd2949d28ce80e913412b0026dc421e5bf6c31d87c7b5eb11b5753b4"},{"version":"5610f2b0ff6cd3cfa4c22261f9e80089b704fb0e0bc269dd27b31b3301699337","signature":"eb494645aea332a4e3a75874b90ba5087448bb5c65ae28b2b8d05a716b4b2540"},{"version":"74a914ffaed90e653ffa56461a16e97ca407160e97117ac9b94905b202b5da54","signature":"24cf1de79511f04c4013f1ffbd04cc5f04c047f1aace617f49eda7f2e9f6abfd"},{"version":"6f0a323d58b45c97ba0b5e08edd23fcc22a9c9fcfc1f2b8a586cbad8073dfb20","signature":"560f62f2ba3600ae921beca0fc6c571e18abd42a9bd5719d0af75f1bea375b5b"},{"version":"6ab7ed1c07b1ab492db83aebb33315dbc8068ce624b0b29d50da287eb674a085","signature":"a72a0e724e39319e851bbaa5c7f0cd39d4e4972309bc9fcc70b0676c47c9bc3e"},{"version":"7f57e34f57905d3e06e8a23954cee63b7ae9bfc554eb9e269b76b827c84f8589","signature":"c22d03f12bbd5a230b814219e6b8d82d3b7c1491876d21ed4850c6598c5525c1"},{"version":"e7c9c33ed552748d99e6df42cc45b3bec9d6244a2b2195d49ed94b094037a0be","signature":"84b248194b1853f42e6d3571d9e76c40e8638fd0173f4180ce560a231f9d7075"},{"version":"bce57e6ae16b3f62e20bfc7ff96ddab7b41a942f9cd069e7ce85a16c4ba39878","signature":"1698fbcf30cf66cb4322eba7a6723d4c8c498ce34f52b70faa3b4946eaabc2cb"},{"version":"bdea2634236000d0b728a60a1b3b73fcd95892b825c32619ae4ae64e80ec7b76","signature":"e94d49f2a5c11180c28606d59c04e8057163c062d1c54577f3e24ba649a6531e"},{"version":"efd3c467844efdc63f5e46512b2a8ba2d06adef01cae61bc93e24c6fee569545","signature":"7c673e405456d412fbe01bd7c5d0a7e2530b90b5c199cc87b78ff168510b692b"},{"version":"1b89fe4d49d10f17b3bae5ae2e7d350f848ba0e3c55acb9a312d5ce42f4d270d","signature":"c4b837eb0b0040c25477ea04bf85357d92e34eac65583ce39c19526344a7beb7"},{"version":"8f3d1e4e2d77b53d95fe74cf1771932cc40f3fe58365de117494e0ceb46921c9","signature":"4eb126e8a43cafe802a102e557ae8e78e74af8930b95452d071b3d91efd54afa"},{"version":"ffd75662777b0fd286107fa71a95113c9e00a0bc69e9b6a559a16857fff4e2f1","signature":"550c26018df53a8056cceb71d394299267c980916358d69cbdc9df9ccacabd63"},{"version":"432a15b7075e6c9289fc9f93eb9248f8a4bc3b091c9ec4391e9b0cb0b71f5ea5","signature":"43dc0b79b3dc9a50733ac3751b65348df4827fba725c678930416df2fbbbec5c"},{"version":"590bc071971a22ad12d4bd3443176edd340c8c47e48758ca2b68219570560337","signature":"52d60f6cda1f26ec66773d4e3f300be0274d998a21f86b886ebf96c83e59b564"},{"version":"9f2ab61c10dd8e78499dc95c938243c2471d1b78107f5ba240bbb5a923159bc4","signature":"a2dcc028e681fa3d0349b946b7c88cf916c2a30143fc4b0af978c8361f11a5b4"},{"version":"6a0c42d76271e7bd85fb64139d75afb2789a1c12de8c6fa2133613388d05d91b","signature":"794fd618a28550767e1ca02ed6d22e4dd31ebd897016f5217bae186c932a6542"},{"version":"e593c2041d9f68522ca0fd06547733223606116826bfabea1b376ad6bb17ab9b","signature":"6dd40ffc7caa807d84a3b191513a5bb3dc0d3d3700beaadbd558edb06856d519"},{"version":"f480db8e3f535ec387568c64fa0e5f915b52d0b4167e2855fe1f6733820a16bf","signature":"2da80c58760cc1a3b39d017d9cfa68e32271f327a6840c67e05004f130c10a9b"},{"version":"2cb63e7ee88ee7e5bf6d75ef55ffd16f8a71257157bbd72c8944ce03b6ff03fd","signature":"35fd8c82aa28653f7541d1a85f6deacc9c36c77da2a9e1befe2bcdae52f180b2"},{"version":"cd783b7d08354e9e8e629c07c316c9a7f2c14a50f72842a090133e0221aa896a","signature":"be4f514b6b758fba286856e88bf567ac600fa86fd108fcf8537d73cfc65f2f3a"},{"version":"607703d777cc58309a24619eeb6fea42a35418050298f10656e6fa4180ecf667","signature":"c59423f8ed778d96803db9f65b1001de9630b7a42be4d42a665aa5dda6104574"},{"version":"f60e3e3060207ac982da13363181fd7ee4beecc19a7c569f0d6bb034331066c2","impliedFormat":1},{"version":"4a20a0a39aca8738cc5088f9dea2969bf2af3ca1341c56071f513059b122d150","impliedFormat":1},{"version":"a33c98f95c099c2a9a383b156c8f2a16605843d29455a954c1431bcbbc1ce35a","impliedFormat":1},{"version":"effa1fd4980f6dff4e81ed67009b847d34449087504319f9a0dd081e8cf23a31","impliedFormat":1},{"version":"c2c9f431f788b434e6ae327844ef6712bb6a6a88ad08acf20bf6cfeb41d154ba","impliedFormat":1},{"version":"798367363a3274220cbed839b883fe2f52ba7197b25e8cb2ac59c1e1fd8af6b7","impliedFormat":1},{"version":"cb850fef5e66935c65a230a1a0dae219286feb6510a092fecd3cbe1e1eb2b5b1","impliedFormat":1},{"version":"5aea76ab98173f2c230b1f78dc010da403da622c105c468ace9fe24e3b77883c","impliedFormat":99},{"version":"5c13239820ff6046f3bbbdea21ceb327bc54c732f4255ad7197972fa09d2590c","signature":"5fb9241a33d25dc2b91e8654fba95802ec208e7a1ac2931b9693423f7f27cdfe"},{"version":"b8d1a2e548cff91361f136a589e8d1957e238c0058a937773539c6c3984c1dd9","signature":"5be4d734cee3ef71b340c0d767e626b7225277a10135b6b33a9ca0a3148c41d3"},{"version":"9f6faeb245121e7bbec36f087bcbb9f41e894cbb3019141ae5f2e40d7bc94a94","signature":"c582529dbb8713331d0d641d6496b2553e0e4b552a6f6550b3ba5ddef9610c22"},{"version":"fa3a5743c96e2a9af042d516cf2c69fcd41e9654c6039f4f905e85c2a985a8d3","signature":"dc14691987c4fc1f0e0c7ff24277b3f7fd512d02050c1f171861ff8d571266be"},{"version":"b1ae12370a885507c0f62a182b0ffcdaf9f4535acc2df14937e236021c702aa2","signature":"000315e88d20a17de241e118a002a07ecd0e3cfd2eab4e88b8fbab130c171037"},{"version":"5b225585d541979495388cd097241c9108133175d56470cb1cb48455e05c31b6","signature":"8a282967f41121b7c23c4691270777549937c373f9c574e371495ed931ff9973"},{"version":"bc4f53f6058f0ec00ba347c5dfe7a969285330a80ecd7e7b3e421c2e73d59888","signature":"ab2df2c6307e2123c86a7ebb6ebe05d0797bed2cc9ffe105fc5776bf9cefc04f"},{"version":"1a73ed7bd6c93b3cd45df8f9233c0cb882c236aee37cec3bde40b255599f3190","signature":"5f216b877d038d008a1d29f9a5b40bb761aa0403029cb8947cf3bd5ad2ea314a"},{"version":"827b0a79f1fa50337949f0b24e9faffecc82f195010db1e3cf04dd6ee09ac247","signature":"61626cffdd7761e15c12f357ce1ff657e90fdde79a41ec9a223e762da7b742e0"},{"version":"3ff8461a35778883e1f465d5b3cf83480ad0485d65dc5927be275ddfd1d18d43","signature":"e5919c018f029dd716cd88b7ba8afd0c5da66b2d953abf6304be98b6b76921f2"},{"version":"df57eb7dea2904e94b409b7417fd8663f9db3358655142e2f638c6933a0c2ab9","signature":"4a54aa0f76a4491749e95e8a7c39d28c1e2d75580a0ba3c7dbe465a3fb833484"},{"version":"c5d62b075a8c7ef0bcd1e4ea163e8aeeae6f406bb6953a5d1ce697165c79e678","signature":"42299961f4d5e28f1684380b113f21b863d8bf1e9b07cedd424cbc872b59f5db"},{"version":"a6857b7bd69c561c11c5f573772359f7cb28806727d5d4d3c39676968443de5d","signature":"f5988c676b67d56ae0314a245bce0b7c4937ac1c9e4e9bd4e6f489d8e0b3dc1c"},{"version":"cc9e9b8c22d99ee194f4ba080696fc27ca6c66de9c795d5fba8674b8b8c55cdb","signature":"965212774f118fe001bb27fddb4e96ba739532072cd856638a39f8e40a7235e1"},{"version":"ff6d4e3946eb86c42c98ff8ae640b32a2a59dfbbd0a8c7778ee95da657f3e6e0","signature":"0c4cdcd9b81eb8bc6972602502c8ec4e692fe58705c5fb015bc59ff2818b4ec1"},{"version":"7f896d9fe63e3c32f37216aa1853ca12ffd99a6aa406b3442e400a935fbfed99","signature":"baa77fd344257d9a3eb1167af3543277598758978bd55602671dde4935cd05a0"},{"version":"717a3679294c3abb9e48fef5009a5c63d3b5617bcf98c14420d0218c60095555","signature":"1cf4fa1f30c731c624dea92e34b5e0664ac0b3b60939388a8ca4fd3311a66b16"},{"version":"e50685dd74860246f13332e12d21813deecef6b7f1b0cf3be4bc59a2e0a8db88","signature":"8bd29979549657f55e6a0f37ec3b0f7736089bc1c832accf3cc6cdcc0b3e9bf0"},{"version":"bfb2bcca9c293ebc4bf74ae2a706ae3b33df037078e9bb549675ff1bc903a1a0","signature":"4365970f534867675101be6e7a6b2f1fbdabb8015627fd526aa7dcc24b442243"},{"version":"9d5b62bb89dc856a24d1998df7dcf953832b6d932df99c3620f86152ace51966","signature":"3968a6fa1a7dce5d907f3a783b01079dbbc6a6bc69ee7687cb85e22a9f1e3a38"},{"version":"4bbb46db0071ce07313338d2e4d1f638b5fc3003fffe329ae9aa0a17e75f8378","signature":"e25e686b331aca74135ae5217744279da26aa1f0a28d6a2772f36493c2223615"},{"version":"7784f7cdaa0dd11ea3e4948afec59a923eb54424c6f3ba5dea1340cf903ddf72","signature":"321aab8c2e0328f2ce7559626e544325c014c661ff9988cb22d35b00f10013ed"},{"version":"8a0dafd83020740c23687c3645d98905c9f30f615ad612901deee39ca64acd00","signature":"df2be157cd11ae10b5a0ec7cfd617e8ee3f295525eeb18a775a834a1567ee1bc"},{"version":"ecd213a0f999dc3fc186510d75efb409b31cffd4cda3e3b193ece485eb416425","signature":"0793e78338009cbbcf17cede8e07c3fb6ead4cc5e2a2dd7db7f25d6a313076b9"},{"version":"71b09e489ca3d21e9ed1e65cb2efca537fe09afa4fdab2532aea3ea474b6d329","signature":"7c65daaa0b5c2bb4ebeb3edfe6eff6db69f8aaf84a300385b32d7f82117c18fc"},{"version":"62b11b77a5f5462219a4d2065abdb5785640b6d5d0aa2116a9fb791dc9c99b36","signature":"96e22e8e555db656a972854e3e05a14d245f62b82b37bfd138f8e05bbca857e2"},{"version":"e5380bbcd915b0a2f529fc1e14166bd1d3b9b7c45242014d275acd90b5b55b0b","signature":"63cb517e407d7a399f48907832055404291507d0eb92e9022c93997a2a74a8e7"},{"version":"a6a825091acfc8b0b8a3e2067f3ecb7f69127eb18a6c3d67adc50dbad102ebe6","signature":"5f3b9213b948c451a2179a81fd407a1df5dcddd2efeadeb5660aad1f38388683"},{"version":"9d50a70644fcfcdb7ce6714e78963ae02faadef4b8f3085eccb6b603637cc0ad","signature":"7444c6fb363dc3a78e062263bc117d359fe7ef8aa879a3c2929db556d4608f74"},{"version":"4be12d3c36d2aaf9bc74bc01b2cc8cf946ff2c377f2b1646a123e974b821ac51","signature":"3ca7dab47ec6b3a03599c83742448d0ce9792683911f9cf381d5d67b00b2bf86"},{"version":"fe25be5be272855a51cac18c4494373bf5b0479f351694547ebee25c85cfafa7","signature":"cf5d89db7dfea2ed4d83a0b715a11e296b8fd179abaaccb73d859ce7f924efbb"},{"version":"830dbb0b1b509b8a3701d21d993b39eef6860a7add66bf58f62c9226d633512c","signature":"31d27c121e9b1de492e3f7bdc3a2e006569e74531d6c239c042b607f58e6734a"},{"version":"d21c931d8bdd57fa812fc3c494e637d2db75da0ca0bdebb22b047ace0e6899a4","signature":"2c63de8d39ae500889575403d5e04f39d9c631645d3b86d686449ec9413700ae"},{"version":"0e98bdca6b2f656ff783eccb891ad5b18b5e39d36a231b94bb407f46185a035f","affectsGlobalScope":true,"impliedFormat":1},{"version":"2b8241ee9d522539245316c7d9efba3a7f7fb67e89edb6b8375841c5204323c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"6dc855128df7aa80c5d937b26d853ec76375b9be022c8476735a82bcb205b582","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e38adf1d08fed1932323468c084f22f3b0ff96da903c213a52dce96e7c5314c","affectsGlobalScope":true,"impliedFormat":1},{"version":"033cc8d0cf4529bc62746a9a026e43454f06f86d560b533e2726e677caf43c5f","affectsGlobalScope":true,"impliedFormat":1},{"version":"56ed2fc77c5587ed572b52c0c679ab284a84254875628d39d63a1ad84aa47993","affectsGlobalScope":true,"impliedFormat":1},{"version":"da04a353ae1f194880392596c1c65bd16039d7cb7d8c95394c8cc833bbeb5600","affectsGlobalScope":true,"impliedFormat":1},{"version":"7f0b457714a6a7dc40d51506cf9e5ab38aec893d78d10dc853d51e4ece6c8a86","affectsGlobalScope":true,"impliedFormat":1},{"version":"42dc1c1fb9a082bfc981edb18b50e12f7fda5009a15468ef6e6f939e86300fbd","affectsGlobalScope":true,"impliedFormat":1},{"version":"4b36ac8539e453915ead7ddf25653d6a7691e6dac52003372c12244965480df2","affectsGlobalScope":true,"impliedFormat":1},{"version":"b98109e756e7e1adf0f305b3f1e9d65a40da0c71ec6d23ffddd9c0ea75cb312a","affectsGlobalScope":true,"impliedFormat":1},{"version":"b3bee285d6a28772aba2633b6bcd9cd53a517f7a4862cf7893197222e73cfddc","affectsGlobalScope":true,"impliedFormat":1},{"version":"122c612162cb2e09d70ebdd670941441e902a26ee79b37f006c5b9d38868ed32","affectsGlobalScope":true,"impliedFormat":1},{"version":"28d03f63a7a5931c8225059693c41a102b52b8e39ca2a034bca11df726d06fda","affectsGlobalScope":true,"impliedFormat":1},{"version":"07cc2729a92e8293f16fa19e56aaeb9f350b4442a24724d358073131222e0bae","affectsGlobalScope":true,"impliedFormat":1},{"version":"f98e2b5fcf96686f2432d1823f195a2ad443762006d7fbda7b4d8d25efd0e384","affectsGlobalScope":true,"impliedFormat":1},{"version":"d3f5b5ecd76cd87ee280a5e72e69f941481e62f12430db4f27aa885c3addfdc7","affectsGlobalScope":true,"impliedFormat":1},{"version":"598710556d7994badb8c5c72d65a602121488d233b70e1c1318faf476a3a76d6","affectsGlobalScope":true,"impliedFormat":1},{"version":"5dabdd06cdb220b33a81312a965f8cab510044ccc522dfac4704baf7ae8aaa79","affectsGlobalScope":true,"impliedFormat":1},{"version":"29c8673e8a6fe0116035c345438591056032a76cad5744c81b5feb039d26789a","affectsGlobalScope":true,"impliedFormat":1},{"version":"9569b7fdc41e43e971cdd193685b085d682a3f2c7243c9a41360521cb21265fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"a66a81b1b7e9582442c41807d62a7baee789e65a8ce6951e6a0b2553a94859a1","affectsGlobalScope":true,"impliedFormat":1},{"version":"f4a2170e218a95ea4352470799614733e6ac9576e9f2d10b57a986dc26763936","affectsGlobalScope":true,"impliedFormat":1},{"version":"1eb62bccdb763ded6f74a2ccd5eb939e3d63fc2a25677409d9c45bd982dec75e","affectsGlobalScope":true,"impliedFormat":1},{"version":"4bcb4739ebaa38c7c8bb85a5b40971ab83809c6f1f217e4d26c4418d9b9b07ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"f4f9f2b412304f6a4664dd395380965e704a66d10490ac990c398691e7c69823","affectsGlobalScope":true,"impliedFormat":1},{"version":"8f54dfac75c73a9e55bb938d2dab1b48fb6fa8fc677dc7a21c3f90e92dae38b0","affectsGlobalScope":true,"impliedFormat":1},{"version":"d48c79e8502a2fb6274d2f41e12fbf5e3c51e53e770994af88b42bf0c53333f0","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bac8c62839badb7cf43d2a507d8df73e61a5313bb6bf0eb0e373b51b1d94e1b","affectsGlobalScope":true,"impliedFormat":1},{"version":"5d94554e80c2392a2b51be4baad4619268158eccb18d23e5d7107849bc409485","affectsGlobalScope":true,"impliedFormat":1},{"version":"ceb1a78b91d40a8cef51b498546780d8842cd42811597af2c5584fa68defe048","affectsGlobalScope":true,"impliedFormat":1},{"version":"f699d663c17e6bad3d2860b6e03a09c79afc248d159e6f1cc1594b2489cc4e89","affectsGlobalScope":true,"impliedFormat":1},{"version":"baace3d380a208ebd640bdfdb70748ca60fbaead011b4a92900abf334188f6cd","affectsGlobalScope":true,"impliedFormat":1},{"version":"f78d7513062564f7ea4baef7329a9b55c011a0afe7878ac6b8ad35913f9b2ccb","signature":"53587c7b0d16473ffbcdff1fdf690fd7f22e561353027631183d990be034be66"},{"version":"4ffba3c5848b4fe62ee59b754fd5f256ad9656a0db6d37b9a2a8cb40dfc7ac21","impliedFormat":99},{"version":"c76c02846ba7d40b9b3488f0e8d75d02cbdee2f0bc5fcd55dd3bd2e1457646ea","impliedFormat":99},{"version":"32b35cf0dc3a1b1a7118b61c34ce2ad1a29695851679f9ec34e0776f2ece2a69","impliedFormat":99},{"version":"b413fbc6658fe2774f8bf9a15cf4c53e586fc38a2d5256b3b9647da242c14389","impliedFormat":99},{"version":"59e5e964b84fdb2378e9455e4e59405030e4ed2b4c6f891ce395f17796af3cbb","impliedFormat":99},{"version":"c30a41267fc04c6518b17e55dcb2b810f267af4314b0b6d7df1c33a76ce1b330","impliedFormat":1},{"version":"72422d0bac4076912385d0c10911b82e4694fc106e2d70added091f88f0824ba","impliedFormat":1},{"version":"da251b82c25bee1d93f9fd80c5a61d945da4f708ca21285541d7aff83ecb8200","impliedFormat":1},{"version":"64db14db2bf37ac089766fdb3c7e1160fabc10e9929bc2deeede7237e4419fc8","impliedFormat":1},{"version":"98b94085c9f78eba36d3d2314affe973e8994f99864b8708122750788825c771","impliedFormat":1},{"version":"90ba95a763101bb61b8a799731a2ed60b5016b8135c1a2d5186862d4b534d4a1","impliedFormat":99},{"version":"f327b1fe16c7122015bbfd65d92e9927b2c2dd7ddd0843c7f955e04e3d0353d7","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"38d345b5cf32834e532b946e48c3ff1da2e27ecba5653adee1e05d355ec40ca3","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"fd10626205ef49504b35e844acdba11b318e59844128358189e192e84a8216b0","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"7cc49ddf8df811951dd30c100a41320da66ce7449f7020e95cebb2ecb5a69447","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"3a9d6d1eef8345318b83137f6bd9418ee6ff19b76ebd5865149098828bc100a7","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"8dd38b7260a227f7b0b0160a47d70e5d38d88a386a9c0b24218aa49b1b233425","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"2630330b69ff9315d93bd7c07eb6b8b31a13e33fed65c88a90803f7090608c89","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"b83c945fe5f1b2f5732ad1a4c674be2d091bfa0f7a3225074850ede5755b3936","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"6b268509fe4db31f43f93ba5701a71bf82bfb5b77d1bdef44830d796c15a5328","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"083eb769a5adb7a47f9657c45f4428d7b513f45b987103cef38a0b0f0153dc84","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"45fc48e2ce95e2403b6c52ec62b371c328c696a71de78b1cc755305237e33b59","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"b090b009adeddd8591ebec033ef0be7644b311911ce3a1866f5e8fd6db8edf59","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"cac2d47a2caf046712fa8de78c4b2a2f59c981a1ef9f43fbd60ea8e2d8725cc6","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"df97bf74360f61b92592dba925d6c6c941f82690b55b8fa531984db025d8e4b6","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"d32c984ee3d21fa51f3128d4878b8781ae3a7da427516c1b4f0fec435a156972","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"7ea868f89e0b5b00233bbbbb88a4493edd9ef49e4f3657c65527806a0f7277ea","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"73fb86c1c3fa96650207d6dcf36a49954b748c6d8740aaf2f3aae66fcb010040","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"20e4b04a89bf9cb12387f97deb47aeef3fc4541461606c39c020e040dd8ade27","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"9cf4e32e6c36c81547e8fef1e9f8cca59a60fff412d47f5b5a2373e6d9d0f7aa","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"bb2c411d55b6fbe601737043597cc5b436d5dc2afcab8a883e20a9bdba2d3bee","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"45f2a0b036171f138c954c64946c8fd7bee7e5b5b805c6a349270ca2a5887ff1","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"93e1db83049db117b035d1e219f6a1168c7326daea602b51b8733f72e9dc24e0","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"6b199c0b287858758ca08004a11a8fcfce16efd5daf8f6f4db5f2fb980fac681","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"d0d3741379f0b462230044ab98a955a95340cfbb48a0e0a229bd4d921a36d1b5","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"9acbbe7f28c386902ba42d930cef869284eb7233df36ab00e9e0cb4e6f4868da","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"c5c9e23ae1643822bd66bf57715d51ff68dc778668d860aa5be26cef4bf616aa","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"677699f60621cd69cf5b91d1be3610ddb9727e380968ce69a51143e7607cc2f0","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"654f164876d3775bbc890257f885ccc275dad29675d70049b4869400c2f80bde","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"93c20852640c5982f53a9752e16890d1f4fcaf2de1af07bc412b20c276d86707","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"d043e32f985f04e66aabe4c725480f209aaf8611ea9dd4c7c03af98f93a85a1a","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"60c0cb2c48f34123c205544179929750a2d000f70cbb85898041e85447be8af9","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"8de7e3fbf1e02b7b26b5c837d7d112a936f85439e4f16f92d4ac94f375ddfc33","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"e1003824ecbbf07b6e2bedb9b16095303b28158402627866b0f0fb54b5c496d1","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"da2ec1eedd7961090f41840209b072f47bb6fff72c71ade05632cf5173b29efb","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"7e0dd85d63e1757f9c3f6863eba996d5a677bf58813167198969615b709c0262","impliedFormat":99},{"version":"581d7cdb8161677d23978241bb3a94754232af5d49623fe2f6b77314a07b19ac","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"2ee04650d89c573b7218af5a813e8090fd2de6ada557f6f5416b67ec79c32180","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"fffd032210e0062b781c755cf000e76561b29bb4e79b8bccf977ae1c9113edf8","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"a66cea78ef25e4ef1826802d61dd373616209b0edd47c9300d01e1fd0790f349","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"ed627c2b51e81db029eaca5b406f0b32f3efdc13b20918b8b8e92b80b5052645","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"e5572c4d4b904c7efbc7c1bbfe46370ef57435444c8eec79d91f9012523ba617","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"ab6835a24c5af81fe31bc1fe322bcb797e1add0c2ee41c33c4ada35096c5e1f1","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"5fff4549c0e6113a8a48bbdba2f31281c910d7b294d25e9555fbadf2128514d8","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"f761c91419d0a89422a0004ef1a92929dd4d2d5e5c16758654d8b0467d1998c6","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"728f63fb091bfe163787cd2f90d3811693c2ac5310f90cdc8b4d5442a9f6bf9d","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"1aa34f2d2f424daa76591b9c78a857db673d914c48407a939bd9e8cd90cd79c4","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"6d7e4589d55eafc97c79c32eae383908cbe13ceb96af15baf7f77b5cd34cad36","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"2709188303e125c809a5f37c426b5737535d1b4366c2a6a9e61dcb49ebb0b9af","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"145bf56d7343fd929fc8d8f80ed245130bcdbaa040bf96565a94ab4a657b08b2","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"9b93ea3ddf60348ceee3cb2be8d9057c26659701f887e7ad9cf4b2cbfe67881b","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"f1afb55b252643f4d5b190dd3462ccd8b1950f8d5dc672314def96d60d8bb7aa","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"0e57a41170b6583fa95ab7628c072dfb59baedf6f5b7a1302f0571fde00c988d","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"ef5751c91444e9a216cbe4f9e55276f1649f80cd27947f9707875fd923cf6ce8","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"42d532ab36fcd61a37db8923f6cef8b69a68f9c54d7bed7a5a0ab855848fc0f2","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"595805f0828a225043a6a91e8937fd63875130cd3a09358e64bb454376ec0567","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},"997a063b9c0c15b9fe20d6fb85bc27a41722f0d2ad1de16c7bfb4aea2653aded",{"version":"40eb4eb274d7def754b3352c23328af96a69261fe5e99d20df41f1d5de8d0f5e","impliedFormat":1},{"version":"c57b441e0c0a9cbdfa7d850dae1f8a387d6f81cbffbc3cd0465d530084c2417d","impliedFormat":99},{"version":"bffcbcc82ee713f3b38e878a01a4662a19f11d520efbcc4ab99409e47828a665","signature":"6bd166c10c0e06cb089874ee706a4059bfbf85c9b8e169c6e3ccf396e36ae322"},{"version":"8b49672caacd3d225345e8dc4ddf9ce0e410be0d9660b2a22b7f33b8d3c748bb","signature":"7502c8274fcd2d159e95384482f2e83bd87c0c808252fd48658705b10ea976e9"},"fa1263802c2d9329e00131d7dc75300c0b8c0b456dcb6e894626d2ef70e1eac3","a691d0762eba9737096ae31a4073748169ccb31d4fd0122f68f893a996ca8de8","ff7b97c3e045be26e3869ac27a723331271cffc3e721c7289639568551335129",{"version":"deeebee41d577052cc4fdb567265236d0da84ea1db963c0216ed2f8768f7633e","signature":"672dc0785fe4fa8f216c90200a0af74f87e7aeaf1874e1f514923a8bc3b150e8"},{"version":"6d8085805e4f55a37467f677c9b9ad6e9165a6d97c0c2212f5f79fa0ff001a63","signature":"898040512e1083e2fe3bb8915aa06e6f82d43cddeeecee8f7150d32fee6c4406"},"0b4d8fe0e8120581fc7dbf1398c69805c08c164f3c827785744eb79a8e3fa09e","cacb25d0d10a3641192fcbcef8a748a7e9be7a853d0c70b685b9db40d4893dc9","af0e6ac8740b4158ee17cf87b1dbe30b8940f48e7e0294a9e72f63633d0b4284",{"version":"41a7914db618eae84e41d77a208f65d050935a1e07f87d315814703e8ab81cf4","signature":"51402428c1ff55867578c3ab5585c6317de3b7cf804808b4d1515aa1b332a990"},"ec95375eccda38a9cd8314c4aa6bcf2bcc08764fceefc4e367d9773ebdc8c352",{"version":"ac58845350d8d53209f25762330277e5b7c4fe15cc25c138c45c8ecded68f520","signature":"c127a95fde18ad630e97342346dbaa5cf9ac5f5a2a3d0dd211a2553ffa2817b7"},{"version":"c5a59de7839fa01231ce144c13bf0e81b7d4eea30dead15ca4da82177e5139dd","signature":"78afbc90dbcc306b314e73222d7f20d5261649ad9c0546929c9544cd61bed0dd"},"469cda976a84618d982843c730b58cead5129fd3c75907aaa32c0d831b4b073c",{"version":"7bbeaa61933d81bfe588b902d36c2d59e989d17dc2c7ed75a7534470e8164260","signature":"29d48431940197684451782209081e024932ccf1cb7ecfab2107526c2d27df7d"},{"version":"cf4a561ca7f125967e44243eeb505a86687222c70eb12bba4bc20324908f9562","signature":"9147a2408efaaff845e3013ce3daf4051e8899c2d2df359c7627411aecb2d471"},"d79510d4cd175a097c80af14600f986da0e4ae0e51264391e2fe7300c45744ff","9a03fba2d1480533363ae021bc42e74c0d9dbdc17b6e7d9ec0294e3072344c2f",{"version":"4d9bed9cbf0e47e28b70438c83d140ac86f25a9e3f78dc6a08bec8d3d1211550","signature":"37143f4b3dd01f5b891402d8d74cd26516974e7310d529253fafaac5df7f3d82"},"e2b471f709a87672cf8d704bea55e78659ba149f6c22b547e0c437bf47197803",{"version":"6a112a828b98a516ac27f00cbb17d0bb71fbd4d0c4901d0f2e2141336d3cb7dc","signature":"4cdb9001ce118849d2abd47634c90ea8148f5b5b0a2b0ba5aa9f78fa743bd8f8"},"c6906e07fdc5ad49277e5baec8f9c8630787775914323b8dd6ca7af4e041db2e",{"version":"f421359bdd27c2eb216b63042860ed44385eb98cdd414a1820be3ede2d092d2a","signature":"890f1568bfea541d3b44afad3263a50b8ebe19ad583cf83a764dffc4fdea1bec"},"4dbe59f32060c5006891f0b573882e3541b0d39f2001e51604839a69dbe24267",{"version":"64e041a9bb5e04df496d023023b7120fea202fea2b79281704873ba791ce9d23","signature":"a42d45ea644d0c4f7517171e9287a867acc214052c0d7d1a111b87d462fe352b"},"2552a31fad45a9ed1bde87e51b038dc0e786cd364b597162263abbf57018949b","0f71c3c39bc54bc2b075d2d62307468d2457392c00c8192b597c7f8bfae004d4","60a9a62eda8ec2b76cf498abe0e655dd88950663d4a8013289dd8acac39e489a","e15ce9f91d5c2b8ace1e914d615257c97ee386ffe37880101883392799c55efd","5f0033797db8a0d2a402dcbca3ddb0031c130357095f0c08d7bceb8e43cd0c30","5ab7f873a2b391a17525a68ed0b24fb33ce5c3d69450cfa049d22853d22ae736","aba19256d8c2803af262289762f30068f8f727126d45fee7f3c616546a3e4ef4","449b3fb2e034493019b95b7cc4edabfab0bd25e62cb0a1f5e2c8303f9d01f78f","01f199d716d498b871f95d664e038ae46e8d799c4cd324860cac688f19f0300f","50f28b040848cb33611c3d5d9d080fe61ccb062614222a9fe25320365e959292","3cd3628e44cd19dfda1c7a20007151bcc1ac305ca9a643fde585cab4d0f2944c","128a7248fd5cef3876cd95ca2a221e90e4d622b28b930ba693f38b18d9d264b0","29256c47157a9fbbed5181b0a92703a018d80aabfd24c658d4b6c161ff7cd4c2",{"version":"ae77d81a5541a8abb938a0efedf9ac4bea36fb3a24cc28cfa11c598863aba571","impliedFormat":1},{"version":"751764bb94219b4ce8f5475dc35d3de2e432fea01a0c9610cd7f69ad05e398c6","impliedFormat":1}],"root":[60,478,479,[574,581],[583,595],[604,636],670,[682,715],[717,737],[740,778]],"options":{"allowJs":false,"esModuleInterop":true,"jsx":1,"module":99,"skipLibCheck":true,"strict":true,"target":9},"referencedMap":[[769,1],[770,2],[771,3],[772,4],[773,5],[774,6],[775,7],[776,8],[768,9],[777,10],[778,11],[766,12],[60,13],[767,14],[747,15],[748,16],[749,16],[751,17],[752,18],[754,19],[757,20],[758,16],[743,21],[760,22],[744,16],[762,23],[764,24],[746,25],[745,26],[740,27],[742,28],[765,29],[750,30],[753,31],[741,32],[756,33],[759,34],[755,35],[761,34],[763,36],[579,13],[581,37],[580,38],[587,39],[576,38],[588,37],[589,13],[582,13],[583,40],[590,38],[591,38],[585,41],[592,42],[584,13],[593,43],[606,44],[608,45],[611,46],[632,47],[633,48],[635,49],[636,50],[594,51],[631,52],[630,53],[634,54],[613,55],[615,56],[612,57],[605,57],[604,58],[618,59],[595,60],[619,38],[607,61],[616,60],[620,13],[622,62],[621,60],[624,63],[625,64],[586,65],[614,66],[617,67],[627,68],[628,69],[629,70],[623,71],[626,72],[575,13],[670,13],[577,38],[578,13],[609,60],[610,73],[478,74],[479,75],[225,13],[496,13],[498,13],[499,76],[483,13],[779,13],[490,77],[488,13],[780,13],[122,78],[123,78],[124,79],[77,80],[125,81],[126,82],[127,83],[72,13],[75,84],[73,13],[74,13],[128,85],[129,86],[130,87],[131,88],[132,89],[133,90],[134,90],[135,91],[136,92],[137,93],[138,94],[78,13],[76,13],[139,95],[140,96],[141,97],[175,98],[142,99],[143,13],[144,100],[145,101],[146,102],[147,103],[148,104],[149,105],[150,106],[151,107],[152,108],[153,108],[154,109],[155,13],[156,110],[157,111],[159,112],[158,113],[160,114],[161,115],[162,116],[163,117],[164,118],[165,119],[166,120],[167,121],[168,122],[169,51],[170,123],[171,124],[172,125],[79,13],[80,13],[81,13],[119,126],[120,13],[121,13],[173,127],[174,128],[603,129],[602,130],[601,129],[179,131],[335,18],[180,132],[178,133],[337,134],[336,135],[176,136],[333,13],[177,137],[61,13],[63,138],[332,18],[243,18],[491,139],[561,140],[562,141],[560,13],[484,13],[546,142],[545,143],[557,142],[548,144],[550,145],[569,145],[549,146],[481,147],[480,13],[486,148],[487,149],[566,150],[542,151],[544,152],[565,13],[563,151],[543,13],[485,149],[541,13],[489,13],[739,13],[62,13],[678,153],[680,154],[679,155],[677,156],[676,13],[637,13],[641,13],[642,13],[638,13],[639,13],[640,13],[643,13],[644,13],[645,13],[646,13],[647,13],[648,13],[668,13],[649,13],[650,157],[669,158],[652,159],[653,13],[655,13],[654,13],[656,13],[657,13],[658,13],[659,13],[660,13],[663,13],[661,13],[662,13],[664,13],[665,13],[666,13],[667,13],[651,159],[533,13],[535,160],[534,13],[738,18],[70,161],[424,162],[429,12],[431,163],[201,164],[229,165],[407,166],[224,167],[212,13],[193,13],[199,13],[397,168],[260,169],[200,13],[366,170],[234,171],[235,172],[331,173],[394,174],[349,175],[401,176],[402,177],[400,178],[399,13],[398,179],[231,180],[202,181],[281,13],[282,182],[197,13],[213,183],[203,184],[265,183],[262,183],[186,183],[227,185],[226,13],[406,186],[416,13],[192,13],[307,187],[308,188],[302,18],[452,13],[310,13],[311,189],[303,190],[458,191],[456,192],[451,13],[393,193],[392,13],[450,194],[304,18],[345,195],[343,196],[453,13],[457,13],[455,197],[454,13],[344,198],[445,199],[448,200],[272,201],[271,202],[270,203],[461,18],[269,204],[254,13],[464,13],[467,13],[466,18],[468,205],[182,13],[403,206],[404,207],[405,208],[215,13],[191,209],[181,13],[323,18],[184,210],[322,211],[321,212],[312,13],[313,13],[320,13],[315,13],[318,213],[314,13],[316,214],[319,215],[317,214],[198,13],[189,13],[190,183],[244,216],[245,217],[242,218],[240,219],[241,220],[237,13],[329,189],[351,189],[423,221],[432,222],[436,223],[410,224],[409,13],[257,13],[469,225],[419,226],[305,227],[306,228],[297,229],[287,13],[328,230],[288,231],[330,232],[325,233],[324,13],[326,13],[342,234],[411,235],[412,236],[290,237],[294,238],[285,239],[389,240],[418,241],[264,242],[367,243],[187,244],[417,245],[183,167],[238,13],[246,246],[378,247],[236,13],[377,248],[71,13],[372,249],[214,13],[283,250],[368,13],[188,13],[247,13],[376,251],[196,13],[252,252],[293,253],[408,254],[292,13],[375,13],[239,13],[380,255],[381,256],[194,13],[383,257],[385,258],[384,259],[217,13],[374,244],[387,260],[373,261],[379,262],[205,13],[208,13],[206,13],[210,13],[207,13],[209,13],[211,263],[204,13],[359,264],[358,13],[364,265],[360,266],[363,267],[362,267],[365,265],[361,266],[251,268],[352,269],[415,270],[471,13],[440,271],[442,272],[289,13],[441,273],[413,235],[470,274],[309,235],[195,13],[291,275],[248,276],[249,277],[250,278],[280,279],[388,279],[266,279],[353,280],[267,280],[233,281],[232,13],[357,282],[356,283],[355,284],[354,285],[414,286],[301,287],[339,288],[300,289],[334,290],[338,291],[396,292],[395,293],[391,294],[348,295],[350,296],[347,297],[386,298],[341,13],[428,13],[340,299],[390,13],[253,300],[286,206],[284,301],[255,302],[258,303],[465,13],[256,304],[259,304],[426,13],[425,13],[427,13],[463,13],[261,305],[299,18],[69,13],[346,306],[230,13],[219,307],[295,13],[434,18],[444,308],[279,18],[438,189],[278,309],[421,310],[277,308],[185,13],[446,311],[275,18],[276,18],[268,13],[218,13],[274,312],[273,313],[216,314],[296,107],[263,107],[382,13],[370,315],[369,13],[430,13],[327,316],[298,18],[422,317],[64,18],[67,318],[68,319],[65,18],[66,13],[228,60],[223,320],[222,13],[221,321],[220,13],[420,322],[433,323],[435,324],[437,325],[439,326],[443,327],[477,328],[447,328],[476,329],[449,330],[459,331],[460,332],[462,333],[472,334],[475,209],[474,13],[473,335],[600,336],[597,13],[599,337],[598,13],[596,13],[529,338],[527,339],[528,340],[516,341],[517,339],[524,342],[515,343],[520,344],[530,13],[521,345],[526,346],[532,347],[531,348],[514,349],[522,350],[523,351],[518,352],[525,338],[519,353],[538,354],[501,355],[502,356],[505,357],[497,358],[504,359],[500,360],[495,13],[506,361],[507,362],[371,363],[513,13],[558,13],[482,13],[58,13],[59,13],[10,13],[11,13],[13,13],[12,13],[2,13],[14,13],[15,13],[16,13],[17,13],[18,13],[19,13],[20,13],[21,13],[3,13],[22,13],[23,13],[4,13],[24,13],[28,13],[25,13],[26,13],[27,13],[29,13],[30,13],[31,13],[5,13],[32,13],[33,13],[34,13],[35,13],[6,13],[39,13],[36,13],[37,13],[38,13],[40,13],[7,13],[41,13],[46,13],[47,13],[42,13],[43,13],[44,13],[45,13],[8,13],[51,13],[48,13],[49,13],[50,13],[52,13],[9,13],[53,13],[54,13],[55,13],[57,13],[56,13],[1,13],[97,364],[107,365],[96,364],[117,366],[88,367],[87,368],[116,335],[110,369],[115,370],[90,371],[104,372],[89,373],[113,374],[85,375],[84,335],[114,376],[86,377],[91,378],[92,13],[95,378],[82,13],[118,379],[108,380],[99,381],[100,382],[102,383],[98,384],[101,385],[111,335],[93,386],[94,387],[103,388],[83,389],[106,380],[105,378],[109,13],[112,390],[493,391],[540,392],[509,393],[494,391],[492,13],[508,394],[539,13],[537,13],[510,13],[536,395],[503,396],[512,13],[511,397],[568,398],[573,399],[567,400],[559,401],[555,402],[551,403],[564,13],[552,144],[674,404],[671,405],[571,406],[570,407],[553,408],[673,409],[547,13],[554,410],[572,411],[681,412],[675,413],[672,13],[556,13],[716,414],[682,415],[683,416],[684,417],[685,418],[686,418],[687,419],[688,418],[689,420],[690,418],[691,421],[692,422],[693,423],[694,424],[695,425],[696,426],[697,427],[698,418],[699,418],[700,428],[701,429],[702,430],[703,418],[704,431],[705,432],[706,420],[707,418],[708,433],[709,434],[710,435],[711,418],[712,436],[713,418],[714,437],[715,438],[717,439],[718,418],[719,418],[720,440],[721,418],[722,441],[723,442],[724,443],[725,13],[726,418],[727,444],[728,445],[729,418],[730,418],[731,446],[732,447],[733,448],[734,449],[735,450],[736,451],[737,13],[574,452]],"affectedFilesPendingEmit":[769,770,771,772,773,774,775,776,768,777,778,767,747,748,749,751,752,754,757,758,743,760,744,762,764,746,745,740,742,765,750,753,741,756,759,755,761,763,579,581,580,587,576,588,589,583,590,591,585,592,584,593,606,608,611,632,633,635,636,594,631,630,634,613,615,612,605,604,618,595,619,607,616,620,622,621,624,625,586,614,617,627,628,629,623,626,575,670,577,578,609,610,479,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,574],"version":"5.9.3"} \ No newline at end of file