├── .changeset ├── README.md └── config.json ├── .devcontainer └── devcontainer.json ├── .env ├── .eslintrc.json ├── .github ├── dependabot.yml └── workflows │ └── create-release-pull-request.yml ├── .gitignore ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── docs ├── charles.md ├── media │ ├── app-icon.png │ └── logo.svg └── pcapdroid.md ├── next-env.d.ts ├── next.config.js ├── package.json ├── pages ├── _app.tsx ├── api │ ├── mob │ │ └── [...all].ts │ └── update │ │ └── [...slug].ts └── index.tsx ├── pnpm-lock.yaml ├── public └── favicon.ico ├── src-tauri ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── build.rs ├── icons │ ├── 128x128.png │ ├── 128x128@2x.png │ ├── 32x32.png │ ├── Square107x107Logo.png │ ├── Square142x142Logo.png │ ├── Square150x150Logo.png │ ├── Square284x284Logo.png │ ├── Square30x30Logo.png │ ├── Square310x310Logo.png │ ├── Square44x44Logo.png │ ├── Square71x71Logo.png │ ├── Square89x89Logo.png │ ├── StoreLogo.png │ ├── icon.icns │ ├── icon.ico │ └── icon.png ├── src │ └── main.rs └── tauri.conf.json ├── src ├── @types │ └── index.d.ts ├── api.ts ├── components │ ├── HTML.tsx │ ├── Link.tsx │ └── Logo.tsx ├── constants.ts ├── features │ ├── chapter-tree-view │ │ ├── ChapterTreeView.tsx │ │ ├── CustomContent.tsx │ │ ├── CustomTreeItem.tsx │ │ └── index.ts │ ├── course │ │ ├── CourseCard.tsx │ │ ├── CourseDrawer.tsx │ │ └── index.ts │ ├── homework │ │ ├── Homework.tsx │ │ └── index.ts │ ├── layout │ │ ├── AppHeader.tsx │ │ ├── Banner.tsx │ │ └── index.ts │ ├── message.tsx │ ├── paper │ │ ├── Paper.tsx │ │ ├── index.ts │ │ └── questions │ │ │ ├── Completion.tsx │ │ │ ├── MultipleChoice.tsx │ │ │ └── SingleChoice.tsx │ ├── settings │ │ ├── MobToken.tsx │ │ ├── ModeToggleButton.tsx │ │ ├── Setting.tsx │ │ └── index.ts │ └── theme │ │ ├── BrandingThemeProvider.tsx │ │ ├── brandingTheme.ts │ │ ├── index.tsx │ │ ├── modeState.ts │ │ └── useTheme.ts ├── lib │ ├── request.ts │ └── store.ts └── utils.ts └── tsconfig.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@3.0.3/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "restricted", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node 3 | { 4 | "name": "Node.js & TypeScript", 5 | // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile 6 | "image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bookworm", 7 | // Features to add to the dev container. More info: https://containers.dev/features. 8 | "features": { 9 | "ghcr.io/devcontainers/features/rust:1": {} 10 | }, 11 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 12 | // "forwardPorts": [], 13 | // Use 'postCreateCommand' to run commands after the container is created. 14 | "postCreateCommand": "npm install -g pnpm@9.10.0" 15 | // Configure tool-specific properties. 16 | // "customizations": {}, 17 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 18 | // "remoteUser": "root" 19 | } 20 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | BANNER=国内用户建议使用 2 | BANNER_LINK=https://github.com/xiaolu-lujunji/mooc-helper/releases 3 | BANNER_LINK_DESCRIPTION=桌面端应用程序 -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for more information: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | # https://containers.dev/guide/dependabot 6 | 7 | version: 2 8 | updates: 9 | - package-ecosystem: "devcontainers" 10 | directory: "/" 11 | schedule: 12 | interval: weekly 13 | -------------------------------------------------------------------------------- /.github/workflows/create-release-pull-request.yml: -------------------------------------------------------------------------------- 1 | name: Create Release Pull Request 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | permissions: 9 | contents: write 10 | pull-requests: write 11 | 12 | concurrency: ${{ github.workflow }}-${{ github.ref }} 13 | 14 | jobs: 15 | release: 16 | name: Create Release Pull Request 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout Repo 20 | uses: actions/checkout@v4 21 | 22 | - name: Setup Node.js 20 23 | uses: actions/setup-node@v4 24 | with: 25 | node-version: 20 26 | 27 | - name: Install Dependencies 28 | run: pnpm install 29 | 30 | - name: Create Release Pull Request 31 | uses: changesets/action@v1 32 | env: 33 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env.local 30 | .env.development.local 31 | .env.test.local 32 | .env.production.local 33 | 34 | # vercel 35 | .vercel 36 | 37 | # typescript 38 | *.tsbuildinfo 39 | 40 | ~ -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.autoSave": "onFocusChange", 3 | "editor.formatOnSave": true, 4 | "editor.tabSize": 2 5 | } 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 lujunji 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | mooc helper logo 3 |

4 | 5 |

MOOC Helper

6 | 7 | 查询**中国大学 MOOC(慕课)课程**的**单元测验**、**单元作业**、**期中/期末测试**的答案 8 | 9 | ## 网站地址 10 | 11 | [mooc helper (mooc-helper.vercel.app)](https://mooc-helper.vercel.app/) 12 | 13 | 建议国内用户尝试如下方式使用: 14 | 15 | - 使用[桌面端应用程序](https://github.com/xiaolu-lujunji/mooc-helper/releases)(目前仅支持 Windows) 16 | - 手机端访问 17 | - 本地启动该项目 18 | 19 | ## 使用步骤 20 | 21 | 1. 获取 `mob-token`,可以使用 [PCAPdroid](./docs/pcapdroid.md) 或 [Charles](./docs/charles.md) 。 22 | 23 | 2. 点击应用右上角**设置按钮**,将获取的 `mob-token` 粘贴到**MOB_TOKEN 输入框**中。然后关闭设置,等待片刻。 24 | 25 | ## 注意事项 26 | 27 | - ❗❗❗ 请明确查询对象是否有时间限制。如果是,请查询后 **在时间截至前** 提交一次,保证一次有效成绩,因为查询操作会开启一次测验。[详情请看 issue13](https://github.com/xiaolu-lujunji/mooc-helper/issues/13) 28 | - 题目排列顺序、答案排列顺序可能存在差异 29 | 30 | ## 免责声明 31 | 32 | 本项目(以下简称“项目”)仅供参考和学习使用。作者尽力确保项目的准确性和可靠性,但不提供任何明示或暗示的保证,包括但不限于对项目的适销性、特定用途的适用性或无侵权的保证。 33 | 34 | 作者不对因使用本项目而产生的任何直接、间接、偶然、特殊、惩罚性或结果性损害承担任何责任,包括但不限于因使用、误用、或依赖项目中的信息而导致的利润损失、业务中断或数据丢失。 35 | 36 | 本项目中的所有内容均基于作者的个人见解和经验,不代表任何组织或公司的观点。 37 | 38 | 使用者应自行承担使用本项目所产生的一切风险。在任何情况下,作者均不对使用本项目而导致的任何损失或损害承担责任。 39 | -------------------------------------------------------------------------------- /docs/charles.md: -------------------------------------------------------------------------------- 1 | # 使用 Charles 获取 mob-token 2 | 3 | Charles 是一款 HTTP 代理/HTTP 监控器/反向代理,可让开发人员查看其机器与互联网之间的所有 HTTP 和 SSL / HTTPS 流量。其中包括请求、响应和 HTTP 标头(包含 cookie 和缓存信息)。 4 | 5 | ## 前提条件 6 | 7 | - 一台电脑 8 | - 一部手机 9 | - 电脑和手机处于同一局域网 10 | 11 | ## 使用 Charles 12 | 13 | 参考 [Charles 代理](https://juejin.cn/post/7345905452793167907#heading-2) 14 | -------------------------------------------------------------------------------- /docs/media/app-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/docs/media/app-icon.png -------------------------------------------------------------------------------- /docs/media/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /docs/pcapdroid.md: -------------------------------------------------------------------------------- 1 | # 使用 PCAPdroid 获取 mob-token 2 | 3 | [PCAPdroid](https://github.com/emanuele-f/PCAPdroid) 是一款隐私友好型开源应用程序,可让您跟踪、分析和阻止设备中其他应用程序的连接。它还可以导出 PCAP 流量转储、检查 HTTP、解密 TLS 流量等! 4 | 5 | ## 前提条件 6 | 7 | - 一部 Android 手机 8 | 9 | ## 下载 PCAPdroid 10 | 11 | 你可以从 [Releases](https://github.com/emanuele-f/PCAPdroid/releases) 页面下载最新版本。 12 | 13 | ## 使用 PCAPdroid 14 | 15 | 参考 [PCAPdroid Tutorials](https://youtu.be/WrZi3_1TSA4) 16 | -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | }; 5 | 6 | module.exports = nextConfig; 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mooc-helper", 3 | "version": "0.1.1", 4 | "private": false, 5 | "license": "MIT", 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "next build", 9 | "export": "next build && next export", 10 | "start": "next start", 11 | "lint": "next lint", 12 | "tauri": "cross-env NEXT_PUBLIC_TAURI=1 tauri" 13 | }, 14 | "dependencies": { 15 | "@babel/core": "^7.18.5", 16 | "@emotion/react": "^11.8.2", 17 | "@emotion/styled": "^11.8.1", 18 | "@mui/icons-material": "^5.5.1", 19 | "@mui/lab": "^5.0.0-alpha.73", 20 | "@mui/material": "^5.5.0", 21 | "@mui/utils": "^5.4.4", 22 | "@tauri-apps/api": "^1.1.0", 23 | "clsx": "^1.1.1", 24 | "got": "^12.5.1", 25 | "html-react-parser": "^1.4.12", 26 | "http-proxy-middleware": "^2.0.6", 27 | "ky": "^0.31.3", 28 | "lodash": "^4.17.21", 29 | "next": "12.1.6", 30 | "react": "18.1.0", 31 | "react-dom": "18.1.0", 32 | "recoil": "^0.6.1" 33 | }, 34 | "devDependencies": { 35 | "@changesets/cli": "^2.27.8", 36 | "@tauri-apps/cli": "^1.1.1", 37 | "@types/lodash": "^4.14.186", 38 | "@types/node": "17.0.21", 39 | "@types/react": "17.0.40", 40 | "cross-env": "^7.0.3", 41 | "eslint": "8.11.0", 42 | "eslint-config-next": "12.1.0", 43 | "typescript": "4.6.2" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import type { AppProps } from "next/app"; 2 | 3 | import Head from "next/head"; 4 | import { RecoilRoot } from "recoil"; 5 | import { BrandingProvider } from "@/features/theme"; 6 | 7 | function MyApp({ Component, pageProps }: AppProps) { 8 | return ( 9 | 10 | 11 | 12 | mooc helper 13 | 14 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | ); 28 | } 29 | 30 | export default MyApp; 31 | -------------------------------------------------------------------------------- /pages/api/mob/[...all].ts: -------------------------------------------------------------------------------- 1 | import type { NextApiRequest, NextApiResponse } from "next"; 2 | import { createProxyMiddleware } from "http-proxy-middleware"; 3 | 4 | const proxyMiddleware = createProxyMiddleware({ 5 | target: "https://www.icourse163.org", 6 | changeOrigin: true, 7 | pathRewrite: { 8 | "^/api": "", 9 | }, 10 | }); 11 | 12 | export default function handler(req: NextApiRequest, res: NextApiResponse) { 13 | // @ts-ignore 14 | proxyMiddleware(req, res, (result: unknown) => { 15 | if (result instanceof Error) { 16 | throw result; 17 | } 18 | }); 19 | } 20 | 21 | export const config = { 22 | api: { 23 | bodyParser: false, 24 | externalResolver: true, 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /pages/api/update/[...slug].ts: -------------------------------------------------------------------------------- 1 | import got from "got"; 2 | import type { NextApiRequest, NextApiResponse } from "next"; 3 | 4 | // https://docs.rs/tauri/1.2.0/tauri/updater/struct.UpdateBuilder.html#method.target 5 | const platformSuffixMap: Record = { 6 | windows: ".msi.zip", 7 | }; 8 | 9 | export default async function handler( 10 | req: NextApiRequest, 11 | res: NextApiResponse 12 | ) { 13 | const { slug } = req.query; 14 | const [target, currentVersion] = slug; 15 | 16 | if (target) { 17 | const suffix = platformSuffixMap[target ?? ""]; 18 | if (suffix) { 19 | const releases = await got( 20 | "https://api.github.com/repos/xiaolu-lujunji/mooc-helper/releases" 21 | ).json< 22 | [ 23 | { 24 | tag_name: string; 25 | body: string; 26 | draft: boolean; 27 | prerelease: boolean; 28 | published_at: string; 29 | assets: [ 30 | { 31 | name: string; 32 | browser_download_url: string; 33 | } 34 | ]; 35 | } 36 | ] 37 | >(); 38 | 39 | const latestRelease = releases.find( 40 | (item: any) => !item.draft && !item.prerelease 41 | ); 42 | 43 | if (latestRelease) { 44 | const version = latestRelease.tag_name.slice(1); 45 | if (version !== currentVersion) { 46 | const binaryAsset = latestRelease.assets.find((e: any) => 47 | e.name.endsWith(suffix) 48 | ); 49 | const sigAsset = latestRelease.assets.find((e: any) => 50 | e.name.endsWith(`${suffix}.sig`) 51 | ); 52 | if (binaryAsset && sigAsset) { 53 | const sigContent = await got(sigAsset.browser_download_url).text(); 54 | 55 | res.status(200).json({ 56 | url: binaryAsset.browser_download_url, 57 | version, 58 | notes: latestRelease.body, 59 | pub_date: latestRelease.published_at, 60 | signature: sigContent, 61 | }); 62 | 63 | return; 64 | } 65 | } 66 | } 67 | } 68 | } 69 | 70 | res.status(204).end(); 71 | } 72 | -------------------------------------------------------------------------------- /pages/index.tsx: -------------------------------------------------------------------------------- 1 | import type { NextPage } from "next"; 2 | import * as React from "react"; 3 | import Container from "@mui/material/Container"; 4 | import Box from "@mui/material/Box"; 5 | import Stack from "@mui/material/Stack"; 6 | import Typography from "@mui/material/Typography"; 7 | import Tooltip from "@mui/material/Tooltip"; 8 | import IconButton from "@mui/material/IconButton"; 9 | import GitHubIcon from "@mui/icons-material/GitHub"; 10 | import Logo from "@/components/Logo"; 11 | import { Banner, AppHeader } from "@/features/layout"; 12 | import Settings from "@/features/settings"; 13 | import { 14 | countState, 15 | courseListState, 16 | recentCourseListState, 17 | selectedCourseState, 18 | CourseCard, 19 | selectedContentState, 20 | } from "@/features/course"; 21 | import { Message, messageState } from "@/features/message"; 22 | import { useSetRecoilState, useRecoilState, useRecoilValue } from "recoil"; 23 | import { CourseDrawer } from "@/features/course"; 24 | import { styled } from "@mui/material/styles"; 25 | import { ChapterTreeView } from "@/features/chapter-tree-view"; 26 | import Homework from "@/features/homework"; 27 | import Paper from "@/features/paper"; 28 | import { courseList as getCourseList, homework, test } from "@/api"; 29 | import { PAGE_SIZE } from "@/constants"; 30 | import { openExternal } from "@/utils"; 31 | import store from "@/lib/store"; 32 | 33 | const GradientText = styled("span")<{ 34 | color?: "primary" | "error" | "success" | "warning"; 35 | }>(({ theme, color = "primary" }) => ({ 36 | background: 37 | theme.palette.mode === "dark" 38 | ? theme.palette.primary.main 39 | : `linear-gradient(to right, ${theme.palette[color].main}, ${theme.palette[color][700]})`, 40 | WebkitBackgroundClip: "text", 41 | WebkitTextFillColor: "transparent", 42 | })); 43 | 44 | const Home: NextPage<{ 45 | banner: string | null; 46 | bannerLink: string | null; 47 | bannerLinkDescription: string | null; 48 | }> = (props) => { 49 | const [courseList, setCourseList] = useRecoilState(courseListState); 50 | const [recentCourseList, setRecentCourseList] = useRecoilState( 51 | recentCourseListState 52 | ); 53 | const [selectedCourse, setSelectedCourse] = 54 | useRecoilState(selectedCourseState); 55 | const [mocPaperDto, setMocPaperDto] = React.useState({ 56 | objectiveQList: [], 57 | subjectiveQList: [], 58 | }); 59 | const setCount = useSetRecoilState(countState); 60 | const setMessage = useSetRecoilState(messageState); 61 | const selectedContent = useRecoilValue(selectedContentState); 62 | 63 | const paperRef = React.useRef(null); 64 | 65 | const selectCourse = (course: Course) => { 66 | setSelectedCourse(course); 67 | }; 68 | 69 | React.useEffect(() => { 70 | const updateMocPaperDto = async ( 71 | fetcher: ( 72 | contentId: number 73 | ) => Promise>, 74 | contentId: number 75 | ) => { 76 | try { 77 | const { status, results } = await fetcher(contentId); 78 | if (paperRef.current) { 79 | paperRef.current.scrollTop = 0; 80 | } 81 | if (status.code === 0) { 82 | setMocPaperDto(results.mocPaperDto); 83 | } else { 84 | setMessage({ 85 | show: true, 86 | msg: status.message, 87 | }); 88 | } 89 | } catch (error) { 90 | setMessage({ 91 | show: true, 92 | msg: String(error), 93 | }); 94 | } 95 | }; 96 | 97 | if (selectedContent?.type === "homework") { 98 | updateMocPaperDto(homework, selectedContent.contentId); 99 | } 100 | if (selectedContent?.type === "quiz") { 101 | updateMocPaperDto(test, selectedContent.contentId); 102 | } 103 | }, [selectedContent]); 104 | 105 | React.useEffect(() => { 106 | setMocPaperDto({ 107 | subjectiveQList: [], 108 | objectiveQList: [], 109 | }); 110 | }, [selectedCourse]); 111 | 112 | React.useEffect(() => { 113 | const whenReady = async () => { 114 | try { 115 | if (courseList.length !== 0) return; 116 | const { status, results } = await getCourseList(1, PAGE_SIZE); 117 | if (status.code === 0) { 118 | setCount(results.pagination.totlePageCount); 119 | setCourseList(results.result); 120 | setRecentCourseList(results.result); 121 | } else { 122 | setMessage({ 123 | show: true, 124 | msg: status.message, 125 | }); 126 | } 127 | } catch (error) { 128 | setMessage({ 129 | show: true, 130 | msg: String(error), 131 | }); 132 | } 133 | }; 134 | 135 | store.get("mob-token").then((storedMobToken) => { 136 | if (storedMobToken !== null) { 137 | whenReady(); 138 | } else { 139 | setMessage({ 140 | show: true, 141 | msg: "MOB-TOKEN未设置!", 142 | }); 143 | } 144 | }); 145 | }, []); 146 | 147 | return ( 148 | <> 149 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 166 | openExternal("https://github.com/xiaolu-lujunji/mooc-helper") 167 | } 168 | > 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | {recentCourseList.length === 0 && ( 177 | 184 | 185 | 186 | The MOOC  Helper you always 187 | wanted 188 | 189 | 190 | 查询中国大学MOOC(慕课)单元测验、单元作业、期中/期末测试答案 191 | 192 | 193 | 194 | )} 195 | {recentCourseList.length > 0 && selectedCourse === null && ( 196 | <> 197 | 最近查看 198 | 199 | {recentCourseList.map((course) => ( 200 | 206 | ))} 207 | 208 | 209 | )} 210 | {selectedCourse !== null && ( 211 | 218 | ({ 220 | width: { xs: "100%", lg: 300, xl: 300 }, 221 | overflow: "auto", 222 | zIndex: 1, 223 | backgroundColor: 224 | theme.palette.mode === "dark" 225 | ? theme.palette.primaryDark[900] 226 | : "rgba(255,255,255)", 227 | // backdropFilter: "blur(20px)", 228 | })} 229 | > 230 | 231 | 232 | 236 | 237 | 238 | 239 | 240 | )} 241 | 242 | 243 | 244 | ); 245 | }; 246 | 247 | export const getStaticProps = () => { 248 | return { 249 | props: { 250 | ...(!process.env.NEXT_PUBLIC_TAURI && { 251 | banner: process.env.BANNER ?? null, 252 | bannerLink: process.env.BANNER_LINK ?? null, 253 | bannerLinkDescription: process.env.BANNER_LINK_DESCRIPTION ?? null, 254 | }), 255 | }, // will be passed to the page component as props 256 | }; 257 | }; 258 | 259 | export default Home; 260 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/public/favicon.ico -------------------------------------------------------------------------------- /src-tauri/.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | -------------------------------------------------------------------------------- /src-tauri/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "adler" 7 | version = "1.0.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 10 | 11 | [[package]] 12 | name = "adler32" 13 | version = "1.2.0" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" 16 | 17 | [[package]] 18 | name = "aho-corasick" 19 | version = "0.7.19" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" 22 | dependencies = [ 23 | "memchr", 24 | ] 25 | 26 | [[package]] 27 | name = "alloc-no-stdlib" 28 | version = "2.0.4" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" 31 | 32 | [[package]] 33 | name = "alloc-stdlib" 34 | version = "0.2.2" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" 37 | dependencies = [ 38 | "alloc-no-stdlib", 39 | ] 40 | 41 | [[package]] 42 | name = "anyhow" 43 | version = "1.0.65" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" 46 | 47 | [[package]] 48 | name = "app" 49 | version = "0.1.0" 50 | dependencies = [ 51 | "serde", 52 | "serde_json", 53 | "tauri", 54 | "tauri-build", 55 | "tauri-plugin-store", 56 | ] 57 | 58 | [[package]] 59 | name = "atk" 60 | version = "0.15.1" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "2c3d816ce6f0e2909a96830d6911c2aff044370b1ef92d7f267b43bae5addedd" 63 | dependencies = [ 64 | "atk-sys", 65 | "bitflags", 66 | "glib", 67 | "libc", 68 | ] 69 | 70 | [[package]] 71 | name = "atk-sys" 72 | version = "0.15.1" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | checksum = "58aeb089fb698e06db8089971c7ee317ab9644bade33383f63631437b03aafb6" 75 | dependencies = [ 76 | "glib-sys", 77 | "gobject-sys", 78 | "libc", 79 | "system-deps 6.0.2", 80 | ] 81 | 82 | [[package]] 83 | name = "attohttpc" 84 | version = "0.22.0" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "1fcf00bc6d5abb29b5f97e3c61a90b6d3caa12f3faf897d4a3e3607c050a35a7" 87 | dependencies = [ 88 | "flate2", 89 | "http", 90 | "log", 91 | "native-tls", 92 | "serde", 93 | "serde_json", 94 | "serde_urlencoded", 95 | "url", 96 | ] 97 | 98 | [[package]] 99 | name = "autocfg" 100 | version = "1.1.0" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 103 | 104 | [[package]] 105 | name = "base64" 106 | version = "0.13.0" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 109 | 110 | [[package]] 111 | name = "bitflags" 112 | version = "1.3.2" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 115 | 116 | [[package]] 117 | name = "block" 118 | version = "0.1.6" 119 | source = "registry+https://github.com/rust-lang/crates.io-index" 120 | checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" 121 | 122 | [[package]] 123 | name = "block-buffer" 124 | version = "0.10.3" 125 | source = "registry+https://github.com/rust-lang/crates.io-index" 126 | checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" 127 | dependencies = [ 128 | "generic-array", 129 | ] 130 | 131 | [[package]] 132 | name = "brotli" 133 | version = "3.3.4" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" 136 | dependencies = [ 137 | "alloc-no-stdlib", 138 | "alloc-stdlib", 139 | "brotli-decompressor", 140 | ] 141 | 142 | [[package]] 143 | name = "brotli-decompressor" 144 | version = "2.3.2" 145 | source = "registry+https://github.com/rust-lang/crates.io-index" 146 | checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80" 147 | dependencies = [ 148 | "alloc-no-stdlib", 149 | "alloc-stdlib", 150 | ] 151 | 152 | [[package]] 153 | name = "bstr" 154 | version = "0.2.17" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" 157 | dependencies = [ 158 | "memchr", 159 | ] 160 | 161 | [[package]] 162 | name = "bumpalo" 163 | version = "3.11.0" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" 166 | 167 | [[package]] 168 | name = "bytemuck" 169 | version = "1.12.1" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" 172 | 173 | [[package]] 174 | name = "byteorder" 175 | version = "1.4.3" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 178 | 179 | [[package]] 180 | name = "bytes" 181 | version = "1.2.1" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" 184 | 185 | [[package]] 186 | name = "cairo-rs" 187 | version = "0.15.12" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "c76ee391b03d35510d9fa917357c7f1855bd9a6659c95a1b392e33f49b3369bc" 190 | dependencies = [ 191 | "bitflags", 192 | "cairo-sys-rs", 193 | "glib", 194 | "libc", 195 | "thiserror", 196 | ] 197 | 198 | [[package]] 199 | name = "cairo-sys-rs" 200 | version = "0.15.1" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8" 203 | dependencies = [ 204 | "glib-sys", 205 | "libc", 206 | "system-deps 6.0.2", 207 | ] 208 | 209 | [[package]] 210 | name = "cargo_toml" 211 | version = "0.11.8" 212 | source = "registry+https://github.com/rust-lang/crates.io-index" 213 | checksum = "e72c3ff59e3b7d24630206bb63a73af65da4ed5df1f76ee84dfafb9fee2ba60e" 214 | dependencies = [ 215 | "serde", 216 | "serde_derive", 217 | "toml", 218 | ] 219 | 220 | [[package]] 221 | name = "cc" 222 | version = "1.0.73" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 225 | 226 | [[package]] 227 | name = "cesu8" 228 | version = "1.1.0" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" 231 | 232 | [[package]] 233 | name = "cfb" 234 | version = "0.6.1" 235 | source = "registry+https://github.com/rust-lang/crates.io-index" 236 | checksum = "74f89d248799e3f15f91b70917f65381062a01bb8e222700ea0e5a7ff9785f9c" 237 | dependencies = [ 238 | "byteorder", 239 | "uuid 0.8.2", 240 | ] 241 | 242 | [[package]] 243 | name = "cfg-expr" 244 | version = "0.9.1" 245 | source = "registry+https://github.com/rust-lang/crates.io-index" 246 | checksum = "3431df59f28accaf4cb4eed4a9acc66bea3f3c3753aa6cdc2f024174ef232af7" 247 | dependencies = [ 248 | "smallvec", 249 | ] 250 | 251 | [[package]] 252 | name = "cfg-expr" 253 | version = "0.10.3" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "0aacacf4d96c24b2ad6eb8ee6df040e4f27b0d0b39a5710c30091baa830485db" 256 | dependencies = [ 257 | "smallvec", 258 | ] 259 | 260 | [[package]] 261 | name = "cfg-if" 262 | version = "1.0.0" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 265 | 266 | [[package]] 267 | name = "cocoa" 268 | version = "0.24.0" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" 271 | dependencies = [ 272 | "bitflags", 273 | "block", 274 | "cocoa-foundation", 275 | "core-foundation", 276 | "core-graphics", 277 | "foreign-types", 278 | "libc", 279 | "objc", 280 | ] 281 | 282 | [[package]] 283 | name = "cocoa-foundation" 284 | version = "0.1.0" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" 287 | dependencies = [ 288 | "bitflags", 289 | "block", 290 | "core-foundation", 291 | "core-graphics-types", 292 | "foreign-types", 293 | "libc", 294 | "objc", 295 | ] 296 | 297 | [[package]] 298 | name = "color_quant" 299 | version = "1.1.0" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" 302 | 303 | [[package]] 304 | name = "combine" 305 | version = "4.6.6" 306 | source = "registry+https://github.com/rust-lang/crates.io-index" 307 | checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" 308 | dependencies = [ 309 | "bytes", 310 | "memchr", 311 | ] 312 | 313 | [[package]] 314 | name = "convert_case" 315 | version = "0.4.0" 316 | source = "registry+https://github.com/rust-lang/crates.io-index" 317 | checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" 318 | 319 | [[package]] 320 | name = "core-foundation" 321 | version = "0.9.3" 322 | source = "registry+https://github.com/rust-lang/crates.io-index" 323 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 324 | dependencies = [ 325 | "core-foundation-sys", 326 | "libc", 327 | ] 328 | 329 | [[package]] 330 | name = "core-foundation-sys" 331 | version = "0.8.3" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" 334 | 335 | [[package]] 336 | name = "core-graphics" 337 | version = "0.22.3" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" 340 | dependencies = [ 341 | "bitflags", 342 | "core-foundation", 343 | "core-graphics-types", 344 | "foreign-types", 345 | "libc", 346 | ] 347 | 348 | [[package]] 349 | name = "core-graphics-types" 350 | version = "0.1.1" 351 | source = "registry+https://github.com/rust-lang/crates.io-index" 352 | checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" 353 | dependencies = [ 354 | "bitflags", 355 | "core-foundation", 356 | "foreign-types", 357 | "libc", 358 | ] 359 | 360 | [[package]] 361 | name = "cpufeatures" 362 | version = "0.2.5" 363 | source = "registry+https://github.com/rust-lang/crates.io-index" 364 | checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" 365 | dependencies = [ 366 | "libc", 367 | ] 368 | 369 | [[package]] 370 | name = "crc32fast" 371 | version = "1.3.2" 372 | source = "registry+https://github.com/rust-lang/crates.io-index" 373 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 374 | dependencies = [ 375 | "cfg-if", 376 | ] 377 | 378 | [[package]] 379 | name = "crossbeam-channel" 380 | version = "0.5.6" 381 | source = "registry+https://github.com/rust-lang/crates.io-index" 382 | checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" 383 | dependencies = [ 384 | "cfg-if", 385 | "crossbeam-utils", 386 | ] 387 | 388 | [[package]] 389 | name = "crossbeam-utils" 390 | version = "0.8.12" 391 | source = "registry+https://github.com/rust-lang/crates.io-index" 392 | checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" 393 | dependencies = [ 394 | "cfg-if", 395 | ] 396 | 397 | [[package]] 398 | name = "crypto-common" 399 | version = "0.1.6" 400 | source = "registry+https://github.com/rust-lang/crates.io-index" 401 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 402 | dependencies = [ 403 | "generic-array", 404 | "typenum", 405 | ] 406 | 407 | [[package]] 408 | name = "cssparser" 409 | version = "0.27.2" 410 | source = "registry+https://github.com/rust-lang/crates.io-index" 411 | checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" 412 | dependencies = [ 413 | "cssparser-macros", 414 | "dtoa-short", 415 | "itoa 0.4.8", 416 | "matches", 417 | "phf 0.8.0", 418 | "proc-macro2", 419 | "quote", 420 | "smallvec", 421 | "syn", 422 | ] 423 | 424 | [[package]] 425 | name = "cssparser-macros" 426 | version = "0.6.0" 427 | source = "registry+https://github.com/rust-lang/crates.io-index" 428 | checksum = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e" 429 | dependencies = [ 430 | "quote", 431 | "syn", 432 | ] 433 | 434 | [[package]] 435 | name = "ctor" 436 | version = "0.1.23" 437 | source = "registry+https://github.com/rust-lang/crates.io-index" 438 | checksum = "cdffe87e1d521a10f9696f833fe502293ea446d7f256c06128293a4119bdf4cb" 439 | dependencies = [ 440 | "quote", 441 | "syn", 442 | ] 443 | 444 | [[package]] 445 | name = "cty" 446 | version = "0.2.2" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" 449 | 450 | [[package]] 451 | name = "darling" 452 | version = "0.13.4" 453 | source = "registry+https://github.com/rust-lang/crates.io-index" 454 | checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" 455 | dependencies = [ 456 | "darling_core", 457 | "darling_macro", 458 | ] 459 | 460 | [[package]] 461 | name = "darling_core" 462 | version = "0.13.4" 463 | source = "registry+https://github.com/rust-lang/crates.io-index" 464 | checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" 465 | dependencies = [ 466 | "fnv", 467 | "ident_case", 468 | "proc-macro2", 469 | "quote", 470 | "strsim", 471 | "syn", 472 | ] 473 | 474 | [[package]] 475 | name = "darling_macro" 476 | version = "0.13.4" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" 479 | dependencies = [ 480 | "darling_core", 481 | "quote", 482 | "syn", 483 | ] 484 | 485 | [[package]] 486 | name = "deflate" 487 | version = "0.7.20" 488 | source = "registry+https://github.com/rust-lang/crates.io-index" 489 | checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" 490 | dependencies = [ 491 | "adler32", 492 | "byteorder", 493 | ] 494 | 495 | [[package]] 496 | name = "derive_more" 497 | version = "0.99.17" 498 | source = "registry+https://github.com/rust-lang/crates.io-index" 499 | checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" 500 | dependencies = [ 501 | "convert_case", 502 | "proc-macro2", 503 | "quote", 504 | "rustc_version 0.4.0", 505 | "syn", 506 | ] 507 | 508 | [[package]] 509 | name = "digest" 510 | version = "0.10.5" 511 | source = "registry+https://github.com/rust-lang/crates.io-index" 512 | checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" 513 | dependencies = [ 514 | "block-buffer", 515 | "crypto-common", 516 | ] 517 | 518 | [[package]] 519 | name = "dirs-next" 520 | version = "2.0.0" 521 | source = "registry+https://github.com/rust-lang/crates.io-index" 522 | checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" 523 | dependencies = [ 524 | "cfg-if", 525 | "dirs-sys-next", 526 | ] 527 | 528 | [[package]] 529 | name = "dirs-sys-next" 530 | version = "0.1.2" 531 | source = "registry+https://github.com/rust-lang/crates.io-index" 532 | checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" 533 | dependencies = [ 534 | "libc", 535 | "redox_users", 536 | "winapi", 537 | ] 538 | 539 | [[package]] 540 | name = "dispatch" 541 | version = "0.2.0" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" 544 | 545 | [[package]] 546 | name = "dtoa" 547 | version = "0.4.8" 548 | source = "registry+https://github.com/rust-lang/crates.io-index" 549 | checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" 550 | 551 | [[package]] 552 | name = "dtoa-short" 553 | version = "0.3.3" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | checksum = "bde03329ae10e79ede66c9ce4dc930aa8599043b0743008548680f25b91502d6" 556 | dependencies = [ 557 | "dtoa", 558 | ] 559 | 560 | [[package]] 561 | name = "embed_plist" 562 | version = "1.2.2" 563 | source = "registry+https://github.com/rust-lang/crates.io-index" 564 | checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" 565 | 566 | [[package]] 567 | name = "encoding_rs" 568 | version = "0.8.31" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" 571 | dependencies = [ 572 | "cfg-if", 573 | ] 574 | 575 | [[package]] 576 | name = "fastrand" 577 | version = "1.8.0" 578 | source = "registry+https://github.com/rust-lang/crates.io-index" 579 | checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" 580 | dependencies = [ 581 | "instant", 582 | ] 583 | 584 | [[package]] 585 | name = "field-offset" 586 | version = "0.3.4" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" 589 | dependencies = [ 590 | "memoffset", 591 | "rustc_version 0.3.3", 592 | ] 593 | 594 | [[package]] 595 | name = "filetime" 596 | version = "0.2.17" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c" 599 | dependencies = [ 600 | "cfg-if", 601 | "libc", 602 | "redox_syscall", 603 | "windows-sys", 604 | ] 605 | 606 | [[package]] 607 | name = "flate2" 608 | version = "1.0.24" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" 611 | dependencies = [ 612 | "crc32fast", 613 | "miniz_oxide", 614 | ] 615 | 616 | [[package]] 617 | name = "fnv" 618 | version = "1.0.7" 619 | source = "registry+https://github.com/rust-lang/crates.io-index" 620 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 621 | 622 | [[package]] 623 | name = "foreign-types" 624 | version = "0.3.2" 625 | source = "registry+https://github.com/rust-lang/crates.io-index" 626 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 627 | dependencies = [ 628 | "foreign-types-shared", 629 | ] 630 | 631 | [[package]] 632 | name = "foreign-types-shared" 633 | version = "0.1.1" 634 | source = "registry+https://github.com/rust-lang/crates.io-index" 635 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 636 | 637 | [[package]] 638 | name = "form_urlencoded" 639 | version = "1.1.0" 640 | source = "registry+https://github.com/rust-lang/crates.io-index" 641 | checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" 642 | dependencies = [ 643 | "percent-encoding", 644 | ] 645 | 646 | [[package]] 647 | name = "futf" 648 | version = "0.1.5" 649 | source = "registry+https://github.com/rust-lang/crates.io-index" 650 | checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" 651 | dependencies = [ 652 | "mac", 653 | "new_debug_unreachable", 654 | ] 655 | 656 | [[package]] 657 | name = "futures-channel" 658 | version = "0.3.24" 659 | source = "registry+https://github.com/rust-lang/crates.io-index" 660 | checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" 661 | dependencies = [ 662 | "futures-core", 663 | ] 664 | 665 | [[package]] 666 | name = "futures-core" 667 | version = "0.3.24" 668 | source = "registry+https://github.com/rust-lang/crates.io-index" 669 | checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" 670 | 671 | [[package]] 672 | name = "futures-executor" 673 | version = "0.3.24" 674 | source = "registry+https://github.com/rust-lang/crates.io-index" 675 | checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab" 676 | dependencies = [ 677 | "futures-core", 678 | "futures-task", 679 | "futures-util", 680 | ] 681 | 682 | [[package]] 683 | name = "futures-io" 684 | version = "0.3.24" 685 | source = "registry+https://github.com/rust-lang/crates.io-index" 686 | checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" 687 | 688 | [[package]] 689 | name = "futures-macro" 690 | version = "0.3.24" 691 | source = "registry+https://github.com/rust-lang/crates.io-index" 692 | checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17" 693 | dependencies = [ 694 | "proc-macro2", 695 | "quote", 696 | "syn", 697 | ] 698 | 699 | [[package]] 700 | name = "futures-task" 701 | version = "0.3.24" 702 | source = "registry+https://github.com/rust-lang/crates.io-index" 703 | checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" 704 | 705 | [[package]] 706 | name = "futures-util" 707 | version = "0.3.24" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" 710 | dependencies = [ 711 | "futures-core", 712 | "futures-macro", 713 | "futures-task", 714 | "pin-project-lite", 715 | "pin-utils", 716 | "slab", 717 | ] 718 | 719 | [[package]] 720 | name = "fxhash" 721 | version = "0.2.1" 722 | source = "registry+https://github.com/rust-lang/crates.io-index" 723 | checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" 724 | dependencies = [ 725 | "byteorder", 726 | ] 727 | 728 | [[package]] 729 | name = "gdk" 730 | version = "0.15.4" 731 | source = "registry+https://github.com/rust-lang/crates.io-index" 732 | checksum = "a6e05c1f572ab0e1f15be94217f0dc29088c248b14f792a5ff0af0d84bcda9e8" 733 | dependencies = [ 734 | "bitflags", 735 | "cairo-rs", 736 | "gdk-pixbuf", 737 | "gdk-sys", 738 | "gio", 739 | "glib", 740 | "libc", 741 | "pango", 742 | ] 743 | 744 | [[package]] 745 | name = "gdk-pixbuf" 746 | version = "0.15.11" 747 | source = "registry+https://github.com/rust-lang/crates.io-index" 748 | checksum = "ad38dd9cc8b099cceecdf41375bb6d481b1b5a7cd5cd603e10a69a9383f8619a" 749 | dependencies = [ 750 | "bitflags", 751 | "gdk-pixbuf-sys", 752 | "gio", 753 | "glib", 754 | "libc", 755 | ] 756 | 757 | [[package]] 758 | name = "gdk-pixbuf-sys" 759 | version = "0.15.10" 760 | source = "registry+https://github.com/rust-lang/crates.io-index" 761 | checksum = "140b2f5378256527150350a8346dbdb08fadc13453a7a2d73aecd5fab3c402a7" 762 | dependencies = [ 763 | "gio-sys", 764 | "glib-sys", 765 | "gobject-sys", 766 | "libc", 767 | "system-deps 6.0.2", 768 | ] 769 | 770 | [[package]] 771 | name = "gdk-sys" 772 | version = "0.15.1" 773 | source = "registry+https://github.com/rust-lang/crates.io-index" 774 | checksum = "32e7a08c1e8f06f4177fb7e51a777b8c1689f743a7bc11ea91d44d2226073a88" 775 | dependencies = [ 776 | "cairo-sys-rs", 777 | "gdk-pixbuf-sys", 778 | "gio-sys", 779 | "glib-sys", 780 | "gobject-sys", 781 | "libc", 782 | "pango-sys", 783 | "pkg-config", 784 | "system-deps 6.0.2", 785 | ] 786 | 787 | [[package]] 788 | name = "gdkx11-sys" 789 | version = "0.15.1" 790 | source = "registry+https://github.com/rust-lang/crates.io-index" 791 | checksum = "b4b7f8c7a84b407aa9b143877e267e848ff34106578b64d1e0a24bf550716178" 792 | dependencies = [ 793 | "gdk-sys", 794 | "glib-sys", 795 | "libc", 796 | "system-deps 6.0.2", 797 | "x11", 798 | ] 799 | 800 | [[package]] 801 | name = "generator" 802 | version = "0.7.1" 803 | source = "registry+https://github.com/rust-lang/crates.io-index" 804 | checksum = "cc184cace1cea8335047a471cc1da80f18acf8a76f3bab2028d499e328948ec7" 805 | dependencies = [ 806 | "cc", 807 | "libc", 808 | "log", 809 | "rustversion", 810 | "windows 0.32.0", 811 | ] 812 | 813 | [[package]] 814 | name = "generic-array" 815 | version = "0.14.6" 816 | source = "registry+https://github.com/rust-lang/crates.io-index" 817 | checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" 818 | dependencies = [ 819 | "typenum", 820 | "version_check", 821 | ] 822 | 823 | [[package]] 824 | name = "getrandom" 825 | version = "0.1.16" 826 | source = "registry+https://github.com/rust-lang/crates.io-index" 827 | checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" 828 | dependencies = [ 829 | "cfg-if", 830 | "libc", 831 | "wasi 0.9.0+wasi-snapshot-preview1", 832 | ] 833 | 834 | [[package]] 835 | name = "getrandom" 836 | version = "0.2.7" 837 | source = "registry+https://github.com/rust-lang/crates.io-index" 838 | checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" 839 | dependencies = [ 840 | "cfg-if", 841 | "libc", 842 | "wasi 0.11.0+wasi-snapshot-preview1", 843 | ] 844 | 845 | [[package]] 846 | name = "gio" 847 | version = "0.15.12" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "68fdbc90312d462781a395f7a16d96a2b379bb6ef8cd6310a2df272771c4283b" 850 | dependencies = [ 851 | "bitflags", 852 | "futures-channel", 853 | "futures-core", 854 | "futures-io", 855 | "gio-sys", 856 | "glib", 857 | "libc", 858 | "once_cell", 859 | "thiserror", 860 | ] 861 | 862 | [[package]] 863 | name = "gio-sys" 864 | version = "0.15.10" 865 | source = "registry+https://github.com/rust-lang/crates.io-index" 866 | checksum = "32157a475271e2c4a023382e9cab31c4584ee30a97da41d3c4e9fdd605abcf8d" 867 | dependencies = [ 868 | "glib-sys", 869 | "gobject-sys", 870 | "libc", 871 | "system-deps 6.0.2", 872 | "winapi", 873 | ] 874 | 875 | [[package]] 876 | name = "glib" 877 | version = "0.15.12" 878 | source = "registry+https://github.com/rust-lang/crates.io-index" 879 | checksum = "edb0306fbad0ab5428b0ca674a23893db909a98582969c9b537be4ced78c505d" 880 | dependencies = [ 881 | "bitflags", 882 | "futures-channel", 883 | "futures-core", 884 | "futures-executor", 885 | "futures-task", 886 | "glib-macros", 887 | "glib-sys", 888 | "gobject-sys", 889 | "libc", 890 | "once_cell", 891 | "smallvec", 892 | "thiserror", 893 | ] 894 | 895 | [[package]] 896 | name = "glib-macros" 897 | version = "0.15.11" 898 | source = "registry+https://github.com/rust-lang/crates.io-index" 899 | checksum = "25a68131a662b04931e71891fb14aaf65ee4b44d08e8abc10f49e77418c86c64" 900 | dependencies = [ 901 | "anyhow", 902 | "heck 0.4.0", 903 | "proc-macro-crate", 904 | "proc-macro-error", 905 | "proc-macro2", 906 | "quote", 907 | "syn", 908 | ] 909 | 910 | [[package]] 911 | name = "glib-sys" 912 | version = "0.15.10" 913 | source = "registry+https://github.com/rust-lang/crates.io-index" 914 | checksum = "ef4b192f8e65e9cf76cbf4ea71fa8e3be4a0e18ffe3d68b8da6836974cc5bad4" 915 | dependencies = [ 916 | "libc", 917 | "system-deps 6.0.2", 918 | ] 919 | 920 | [[package]] 921 | name = "glob" 922 | version = "0.3.0" 923 | source = "registry+https://github.com/rust-lang/crates.io-index" 924 | checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" 925 | 926 | [[package]] 927 | name = "globset" 928 | version = "0.4.9" 929 | source = "registry+https://github.com/rust-lang/crates.io-index" 930 | checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a" 931 | dependencies = [ 932 | "aho-corasick", 933 | "bstr", 934 | "fnv", 935 | "log", 936 | "regex", 937 | ] 938 | 939 | [[package]] 940 | name = "gobject-sys" 941 | version = "0.15.10" 942 | source = "registry+https://github.com/rust-lang/crates.io-index" 943 | checksum = "0d57ce44246becd17153bd035ab4d32cfee096a657fc01f2231c9278378d1e0a" 944 | dependencies = [ 945 | "glib-sys", 946 | "libc", 947 | "system-deps 6.0.2", 948 | ] 949 | 950 | [[package]] 951 | name = "gtk" 952 | version = "0.15.5" 953 | source = "registry+https://github.com/rust-lang/crates.io-index" 954 | checksum = "92e3004a2d5d6d8b5057d2b57b3712c9529b62e82c77f25c1fecde1fd5c23bd0" 955 | dependencies = [ 956 | "atk", 957 | "bitflags", 958 | "cairo-rs", 959 | "field-offset", 960 | "futures-channel", 961 | "gdk", 962 | "gdk-pixbuf", 963 | "gio", 964 | "glib", 965 | "gtk-sys", 966 | "gtk3-macros", 967 | "libc", 968 | "once_cell", 969 | "pango", 970 | "pkg-config", 971 | ] 972 | 973 | [[package]] 974 | name = "gtk-sys" 975 | version = "0.15.3" 976 | source = "registry+https://github.com/rust-lang/crates.io-index" 977 | checksum = "d5bc2f0587cba247f60246a0ca11fe25fb733eabc3de12d1965fc07efab87c84" 978 | dependencies = [ 979 | "atk-sys", 980 | "cairo-sys-rs", 981 | "gdk-pixbuf-sys", 982 | "gdk-sys", 983 | "gio-sys", 984 | "glib-sys", 985 | "gobject-sys", 986 | "libc", 987 | "pango-sys", 988 | "system-deps 6.0.2", 989 | ] 990 | 991 | [[package]] 992 | name = "gtk3-macros" 993 | version = "0.15.4" 994 | source = "registry+https://github.com/rust-lang/crates.io-index" 995 | checksum = "24f518afe90c23fba585b2d7697856f9e6a7bbc62f65588035e66f6afb01a2e9" 996 | dependencies = [ 997 | "anyhow", 998 | "proc-macro-crate", 999 | "proc-macro-error", 1000 | "proc-macro2", 1001 | "quote", 1002 | "syn", 1003 | ] 1004 | 1005 | [[package]] 1006 | name = "hashbrown" 1007 | version = "0.12.3" 1008 | source = "registry+https://github.com/rust-lang/crates.io-index" 1009 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 1010 | 1011 | [[package]] 1012 | name = "heck" 1013 | version = "0.3.3" 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" 1015 | checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" 1016 | dependencies = [ 1017 | "unicode-segmentation", 1018 | ] 1019 | 1020 | [[package]] 1021 | name = "heck" 1022 | version = "0.4.0" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" 1025 | 1026 | [[package]] 1027 | name = "hermit-abi" 1028 | version = "0.1.19" 1029 | source = "registry+https://github.com/rust-lang/crates.io-index" 1030 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 1031 | dependencies = [ 1032 | "libc", 1033 | ] 1034 | 1035 | [[package]] 1036 | name = "html5ever" 1037 | version = "0.25.2" 1038 | source = "registry+https://github.com/rust-lang/crates.io-index" 1039 | checksum = "e5c13fb08e5d4dfc151ee5e88bae63f7773d61852f3bdc73c9f4b9e1bde03148" 1040 | dependencies = [ 1041 | "log", 1042 | "mac", 1043 | "markup5ever", 1044 | "proc-macro2", 1045 | "quote", 1046 | "syn", 1047 | ] 1048 | 1049 | [[package]] 1050 | name = "http" 1051 | version = "0.2.8" 1052 | source = "registry+https://github.com/rust-lang/crates.io-index" 1053 | checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" 1054 | dependencies = [ 1055 | "bytes", 1056 | "fnv", 1057 | "itoa 1.0.4", 1058 | ] 1059 | 1060 | [[package]] 1061 | name = "http-range" 1062 | version = "0.1.5" 1063 | source = "registry+https://github.com/rust-lang/crates.io-index" 1064 | checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" 1065 | 1066 | [[package]] 1067 | name = "ico" 1068 | version = "0.1.0" 1069 | source = "registry+https://github.com/rust-lang/crates.io-index" 1070 | checksum = "6a4b3331534254a9b64095ae60d3dc2a8225a7a70229cd5888be127cdc1f6804" 1071 | dependencies = [ 1072 | "byteorder", 1073 | "png 0.11.0", 1074 | ] 1075 | 1076 | [[package]] 1077 | name = "ident_case" 1078 | version = "1.0.1" 1079 | source = "registry+https://github.com/rust-lang/crates.io-index" 1080 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 1081 | 1082 | [[package]] 1083 | name = "idna" 1084 | version = "0.3.0" 1085 | source = "registry+https://github.com/rust-lang/crates.io-index" 1086 | checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" 1087 | dependencies = [ 1088 | "unicode-bidi", 1089 | "unicode-normalization", 1090 | ] 1091 | 1092 | [[package]] 1093 | name = "ignore" 1094 | version = "0.4.18" 1095 | source = "registry+https://github.com/rust-lang/crates.io-index" 1096 | checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" 1097 | dependencies = [ 1098 | "crossbeam-utils", 1099 | "globset", 1100 | "lazy_static", 1101 | "log", 1102 | "memchr", 1103 | "regex", 1104 | "same-file", 1105 | "thread_local", 1106 | "walkdir", 1107 | "winapi-util", 1108 | ] 1109 | 1110 | [[package]] 1111 | name = "image" 1112 | version = "0.24.4" 1113 | source = "registry+https://github.com/rust-lang/crates.io-index" 1114 | checksum = "bd8e4fb07cf672b1642304e731ef8a6a4c7891d67bb4fd4f5ce58cd6ed86803c" 1115 | dependencies = [ 1116 | "bytemuck", 1117 | "byteorder", 1118 | "color_quant", 1119 | "num-rational", 1120 | "num-traits", 1121 | ] 1122 | 1123 | [[package]] 1124 | name = "indexmap" 1125 | version = "1.9.1" 1126 | source = "registry+https://github.com/rust-lang/crates.io-index" 1127 | checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" 1128 | dependencies = [ 1129 | "autocfg", 1130 | "hashbrown", 1131 | ] 1132 | 1133 | [[package]] 1134 | name = "infer" 1135 | version = "0.7.0" 1136 | source = "registry+https://github.com/rust-lang/crates.io-index" 1137 | checksum = "20b2b533137b9cad970793453d4f921c2e91312a6d88b1085c07bc15fc51bb3b" 1138 | dependencies = [ 1139 | "cfb", 1140 | ] 1141 | 1142 | [[package]] 1143 | name = "inflate" 1144 | version = "0.3.4" 1145 | source = "registry+https://github.com/rust-lang/crates.io-index" 1146 | checksum = "f5f9f47468e9a76a6452271efadc88fe865a82be91fe75e6c0c57b87ccea59d4" 1147 | dependencies = [ 1148 | "adler32", 1149 | ] 1150 | 1151 | [[package]] 1152 | name = "instant" 1153 | version = "0.1.12" 1154 | source = "registry+https://github.com/rust-lang/crates.io-index" 1155 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 1156 | dependencies = [ 1157 | "cfg-if", 1158 | ] 1159 | 1160 | [[package]] 1161 | name = "itoa" 1162 | version = "0.4.8" 1163 | source = "registry+https://github.com/rust-lang/crates.io-index" 1164 | checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" 1165 | 1166 | [[package]] 1167 | name = "itoa" 1168 | version = "1.0.4" 1169 | source = "registry+https://github.com/rust-lang/crates.io-index" 1170 | checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" 1171 | 1172 | [[package]] 1173 | name = "javascriptcore-rs" 1174 | version = "0.16.0" 1175 | source = "registry+https://github.com/rust-lang/crates.io-index" 1176 | checksum = "bf053e7843f2812ff03ef5afe34bb9c06ffee120385caad4f6b9967fcd37d41c" 1177 | dependencies = [ 1178 | "bitflags", 1179 | "glib", 1180 | "javascriptcore-rs-sys", 1181 | ] 1182 | 1183 | [[package]] 1184 | name = "javascriptcore-rs-sys" 1185 | version = "0.4.0" 1186 | source = "registry+https://github.com/rust-lang/crates.io-index" 1187 | checksum = "905fbb87419c5cde6e3269537e4ea7d46431f3008c5d057e915ef3f115e7793c" 1188 | dependencies = [ 1189 | "glib-sys", 1190 | "gobject-sys", 1191 | "libc", 1192 | "system-deps 5.0.0", 1193 | ] 1194 | 1195 | [[package]] 1196 | name = "jni" 1197 | version = "0.19.0" 1198 | source = "registry+https://github.com/rust-lang/crates.io-index" 1199 | checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" 1200 | dependencies = [ 1201 | "cesu8", 1202 | "combine", 1203 | "jni-sys", 1204 | "log", 1205 | "thiserror", 1206 | "walkdir", 1207 | ] 1208 | 1209 | [[package]] 1210 | name = "jni-sys" 1211 | version = "0.3.0" 1212 | source = "registry+https://github.com/rust-lang/crates.io-index" 1213 | checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" 1214 | 1215 | [[package]] 1216 | name = "js-sys" 1217 | version = "0.3.60" 1218 | source = "registry+https://github.com/rust-lang/crates.io-index" 1219 | checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" 1220 | dependencies = [ 1221 | "wasm-bindgen", 1222 | ] 1223 | 1224 | [[package]] 1225 | name = "json-patch" 1226 | version = "0.2.6" 1227 | source = "registry+https://github.com/rust-lang/crates.io-index" 1228 | checksum = "f995a3c8f2bc3dd52a18a583e90f9ec109c047fa1603a853e46bcda14d2e279d" 1229 | dependencies = [ 1230 | "serde", 1231 | "serde_json", 1232 | "treediff", 1233 | ] 1234 | 1235 | [[package]] 1236 | name = "kuchiki" 1237 | version = "0.8.1" 1238 | source = "registry+https://github.com/rust-lang/crates.io-index" 1239 | checksum = "1ea8e9c6e031377cff82ee3001dc8026cdf431ed4e2e6b51f98ab8c73484a358" 1240 | dependencies = [ 1241 | "cssparser", 1242 | "html5ever", 1243 | "matches", 1244 | "selectors", 1245 | ] 1246 | 1247 | [[package]] 1248 | name = "lazy_static" 1249 | version = "1.4.0" 1250 | source = "registry+https://github.com/rust-lang/crates.io-index" 1251 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 1252 | 1253 | [[package]] 1254 | name = "libc" 1255 | version = "0.2.134" 1256 | source = "registry+https://github.com/rust-lang/crates.io-index" 1257 | checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb" 1258 | 1259 | [[package]] 1260 | name = "line-wrap" 1261 | version = "0.1.1" 1262 | source = "registry+https://github.com/rust-lang/crates.io-index" 1263 | checksum = "f30344350a2a51da54c1d53be93fade8a237e545dbcc4bdbe635413f2117cab9" 1264 | dependencies = [ 1265 | "safemem", 1266 | ] 1267 | 1268 | [[package]] 1269 | name = "lock_api" 1270 | version = "0.4.9" 1271 | source = "registry+https://github.com/rust-lang/crates.io-index" 1272 | checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" 1273 | dependencies = [ 1274 | "autocfg", 1275 | "scopeguard", 1276 | ] 1277 | 1278 | [[package]] 1279 | name = "log" 1280 | version = "0.4.17" 1281 | source = "registry+https://github.com/rust-lang/crates.io-index" 1282 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 1283 | dependencies = [ 1284 | "cfg-if", 1285 | ] 1286 | 1287 | [[package]] 1288 | name = "loom" 1289 | version = "0.5.6" 1290 | source = "registry+https://github.com/rust-lang/crates.io-index" 1291 | checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" 1292 | dependencies = [ 1293 | "cfg-if", 1294 | "generator", 1295 | "scoped-tls", 1296 | "serde", 1297 | "serde_json", 1298 | "tracing", 1299 | "tracing-subscriber", 1300 | ] 1301 | 1302 | [[package]] 1303 | name = "mac" 1304 | version = "0.1.1" 1305 | source = "registry+https://github.com/rust-lang/crates.io-index" 1306 | checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" 1307 | 1308 | [[package]] 1309 | name = "malloc_buf" 1310 | version = "0.0.6" 1311 | source = "registry+https://github.com/rust-lang/crates.io-index" 1312 | checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" 1313 | dependencies = [ 1314 | "libc", 1315 | ] 1316 | 1317 | [[package]] 1318 | name = "markup5ever" 1319 | version = "0.10.1" 1320 | source = "registry+https://github.com/rust-lang/crates.io-index" 1321 | checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd" 1322 | dependencies = [ 1323 | "log", 1324 | "phf 0.8.0", 1325 | "phf_codegen", 1326 | "string_cache", 1327 | "string_cache_codegen", 1328 | "tendril", 1329 | ] 1330 | 1331 | [[package]] 1332 | name = "matchers" 1333 | version = "0.1.0" 1334 | source = "registry+https://github.com/rust-lang/crates.io-index" 1335 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" 1336 | dependencies = [ 1337 | "regex-automata", 1338 | ] 1339 | 1340 | [[package]] 1341 | name = "matches" 1342 | version = "0.1.9" 1343 | source = "registry+https://github.com/rust-lang/crates.io-index" 1344 | checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" 1345 | 1346 | [[package]] 1347 | name = "memchr" 1348 | version = "2.5.0" 1349 | source = "registry+https://github.com/rust-lang/crates.io-index" 1350 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 1351 | 1352 | [[package]] 1353 | name = "memoffset" 1354 | version = "0.6.5" 1355 | source = "registry+https://github.com/rust-lang/crates.io-index" 1356 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" 1357 | dependencies = [ 1358 | "autocfg", 1359 | ] 1360 | 1361 | [[package]] 1362 | name = "minisign-verify" 1363 | version = "0.2.1" 1364 | source = "registry+https://github.com/rust-lang/crates.io-index" 1365 | checksum = "933dca44d65cdd53b355d0b73d380a2ff5da71f87f036053188bf1eab6a19881" 1366 | 1367 | [[package]] 1368 | name = "miniz_oxide" 1369 | version = "0.5.4" 1370 | source = "registry+https://github.com/rust-lang/crates.io-index" 1371 | checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" 1372 | dependencies = [ 1373 | "adler", 1374 | ] 1375 | 1376 | [[package]] 1377 | name = "native-tls" 1378 | version = "0.2.10" 1379 | source = "registry+https://github.com/rust-lang/crates.io-index" 1380 | checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" 1381 | dependencies = [ 1382 | "lazy_static", 1383 | "libc", 1384 | "log", 1385 | "openssl", 1386 | "openssl-probe", 1387 | "openssl-sys", 1388 | "schannel", 1389 | "security-framework", 1390 | "security-framework-sys", 1391 | "tempfile", 1392 | ] 1393 | 1394 | [[package]] 1395 | name = "ndk" 1396 | version = "0.6.0" 1397 | source = "registry+https://github.com/rust-lang/crates.io-index" 1398 | checksum = "2032c77e030ddee34a6787a64166008da93f6a352b629261d0fee232b8742dd4" 1399 | dependencies = [ 1400 | "bitflags", 1401 | "jni-sys", 1402 | "ndk-sys", 1403 | "num_enum", 1404 | "thiserror", 1405 | ] 1406 | 1407 | [[package]] 1408 | name = "ndk-context" 1409 | version = "0.1.1" 1410 | source = "registry+https://github.com/rust-lang/crates.io-index" 1411 | checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" 1412 | 1413 | [[package]] 1414 | name = "ndk-sys" 1415 | version = "0.3.0" 1416 | source = "registry+https://github.com/rust-lang/crates.io-index" 1417 | checksum = "6e5a6ae77c8ee183dcbbba6150e2e6b9f3f4196a7666c02a715a95692ec1fa97" 1418 | dependencies = [ 1419 | "jni-sys", 1420 | ] 1421 | 1422 | [[package]] 1423 | name = "new_debug_unreachable" 1424 | version = "1.0.4" 1425 | source = "registry+https://github.com/rust-lang/crates.io-index" 1426 | checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" 1427 | 1428 | [[package]] 1429 | name = "nodrop" 1430 | version = "0.1.14" 1431 | source = "registry+https://github.com/rust-lang/crates.io-index" 1432 | checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" 1433 | 1434 | [[package]] 1435 | name = "nu-ansi-term" 1436 | version = "0.46.0" 1437 | source = "registry+https://github.com/rust-lang/crates.io-index" 1438 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" 1439 | dependencies = [ 1440 | "overload", 1441 | "winapi", 1442 | ] 1443 | 1444 | [[package]] 1445 | name = "num-integer" 1446 | version = "0.1.45" 1447 | source = "registry+https://github.com/rust-lang/crates.io-index" 1448 | checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" 1449 | dependencies = [ 1450 | "autocfg", 1451 | "num-traits", 1452 | ] 1453 | 1454 | [[package]] 1455 | name = "num-iter" 1456 | version = "0.1.43" 1457 | source = "registry+https://github.com/rust-lang/crates.io-index" 1458 | checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" 1459 | dependencies = [ 1460 | "autocfg", 1461 | "num-integer", 1462 | "num-traits", 1463 | ] 1464 | 1465 | [[package]] 1466 | name = "num-rational" 1467 | version = "0.4.1" 1468 | source = "registry+https://github.com/rust-lang/crates.io-index" 1469 | checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" 1470 | dependencies = [ 1471 | "autocfg", 1472 | "num-integer", 1473 | "num-traits", 1474 | ] 1475 | 1476 | [[package]] 1477 | name = "num-traits" 1478 | version = "0.2.15" 1479 | source = "registry+https://github.com/rust-lang/crates.io-index" 1480 | checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" 1481 | dependencies = [ 1482 | "autocfg", 1483 | ] 1484 | 1485 | [[package]] 1486 | name = "num_cpus" 1487 | version = "1.13.1" 1488 | source = "registry+https://github.com/rust-lang/crates.io-index" 1489 | checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" 1490 | dependencies = [ 1491 | "hermit-abi", 1492 | "libc", 1493 | ] 1494 | 1495 | [[package]] 1496 | name = "num_enum" 1497 | version = "0.5.7" 1498 | source = "registry+https://github.com/rust-lang/crates.io-index" 1499 | checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" 1500 | dependencies = [ 1501 | "num_enum_derive", 1502 | ] 1503 | 1504 | [[package]] 1505 | name = "num_enum_derive" 1506 | version = "0.5.7" 1507 | source = "registry+https://github.com/rust-lang/crates.io-index" 1508 | checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" 1509 | dependencies = [ 1510 | "proc-macro-crate", 1511 | "proc-macro2", 1512 | "quote", 1513 | "syn", 1514 | ] 1515 | 1516 | [[package]] 1517 | name = "num_threads" 1518 | version = "0.1.6" 1519 | source = "registry+https://github.com/rust-lang/crates.io-index" 1520 | checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" 1521 | dependencies = [ 1522 | "libc", 1523 | ] 1524 | 1525 | [[package]] 1526 | name = "objc" 1527 | version = "0.2.7" 1528 | source = "registry+https://github.com/rust-lang/crates.io-index" 1529 | checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" 1530 | dependencies = [ 1531 | "malloc_buf", 1532 | "objc_exception", 1533 | ] 1534 | 1535 | [[package]] 1536 | name = "objc-foundation" 1537 | version = "0.1.1" 1538 | source = "registry+https://github.com/rust-lang/crates.io-index" 1539 | checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" 1540 | dependencies = [ 1541 | "block", 1542 | "objc", 1543 | "objc_id", 1544 | ] 1545 | 1546 | [[package]] 1547 | name = "objc_exception" 1548 | version = "0.1.2" 1549 | source = "registry+https://github.com/rust-lang/crates.io-index" 1550 | checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" 1551 | dependencies = [ 1552 | "cc", 1553 | ] 1554 | 1555 | [[package]] 1556 | name = "objc_id" 1557 | version = "0.1.1" 1558 | source = "registry+https://github.com/rust-lang/crates.io-index" 1559 | checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" 1560 | dependencies = [ 1561 | "objc", 1562 | ] 1563 | 1564 | [[package]] 1565 | name = "once_cell" 1566 | version = "1.15.0" 1567 | source = "registry+https://github.com/rust-lang/crates.io-index" 1568 | checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" 1569 | 1570 | [[package]] 1571 | name = "open" 1572 | version = "3.0.3" 1573 | source = "registry+https://github.com/rust-lang/crates.io-index" 1574 | checksum = "b4a3100141f1733ea40b53381b0ae3117330735ef22309a190ac57b9576ea716" 1575 | dependencies = [ 1576 | "pathdiff", 1577 | "windows-sys", 1578 | ] 1579 | 1580 | [[package]] 1581 | name = "openssl" 1582 | version = "0.10.42" 1583 | source = "registry+https://github.com/rust-lang/crates.io-index" 1584 | checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" 1585 | dependencies = [ 1586 | "bitflags", 1587 | "cfg-if", 1588 | "foreign-types", 1589 | "libc", 1590 | "once_cell", 1591 | "openssl-macros", 1592 | "openssl-sys", 1593 | ] 1594 | 1595 | [[package]] 1596 | name = "openssl-macros" 1597 | version = "0.1.0" 1598 | source = "registry+https://github.com/rust-lang/crates.io-index" 1599 | checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" 1600 | dependencies = [ 1601 | "proc-macro2", 1602 | "quote", 1603 | "syn", 1604 | ] 1605 | 1606 | [[package]] 1607 | name = "openssl-probe" 1608 | version = "0.1.5" 1609 | source = "registry+https://github.com/rust-lang/crates.io-index" 1610 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 1611 | 1612 | [[package]] 1613 | name = "openssl-sys" 1614 | version = "0.9.76" 1615 | source = "registry+https://github.com/rust-lang/crates.io-index" 1616 | checksum = "5230151e44c0f05157effb743e8d517472843121cf9243e8b81393edb5acd9ce" 1617 | dependencies = [ 1618 | "autocfg", 1619 | "cc", 1620 | "libc", 1621 | "pkg-config", 1622 | "vcpkg", 1623 | ] 1624 | 1625 | [[package]] 1626 | name = "overload" 1627 | version = "0.1.1" 1628 | source = "registry+https://github.com/rust-lang/crates.io-index" 1629 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" 1630 | 1631 | [[package]] 1632 | name = "pango" 1633 | version = "0.15.10" 1634 | source = "registry+https://github.com/rust-lang/crates.io-index" 1635 | checksum = "22e4045548659aee5313bde6c582b0d83a627b7904dd20dc2d9ef0895d414e4f" 1636 | dependencies = [ 1637 | "bitflags", 1638 | "glib", 1639 | "libc", 1640 | "once_cell", 1641 | "pango-sys", 1642 | ] 1643 | 1644 | [[package]] 1645 | name = "pango-sys" 1646 | version = "0.15.10" 1647 | source = "registry+https://github.com/rust-lang/crates.io-index" 1648 | checksum = "d2a00081cde4661982ed91d80ef437c20eacaf6aa1a5962c0279ae194662c3aa" 1649 | dependencies = [ 1650 | "glib-sys", 1651 | "gobject-sys", 1652 | "libc", 1653 | "system-deps 6.0.2", 1654 | ] 1655 | 1656 | [[package]] 1657 | name = "parking_lot" 1658 | version = "0.12.1" 1659 | source = "registry+https://github.com/rust-lang/crates.io-index" 1660 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 1661 | dependencies = [ 1662 | "lock_api", 1663 | "parking_lot_core", 1664 | ] 1665 | 1666 | [[package]] 1667 | name = "parking_lot_core" 1668 | version = "0.9.3" 1669 | source = "registry+https://github.com/rust-lang/crates.io-index" 1670 | checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" 1671 | dependencies = [ 1672 | "cfg-if", 1673 | "libc", 1674 | "redox_syscall", 1675 | "smallvec", 1676 | "windows-sys", 1677 | ] 1678 | 1679 | [[package]] 1680 | name = "paste" 1681 | version = "1.0.9" 1682 | source = "registry+https://github.com/rust-lang/crates.io-index" 1683 | checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" 1684 | 1685 | [[package]] 1686 | name = "pathdiff" 1687 | version = "0.2.1" 1688 | source = "registry+https://github.com/rust-lang/crates.io-index" 1689 | checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" 1690 | 1691 | [[package]] 1692 | name = "percent-encoding" 1693 | version = "2.2.0" 1694 | source = "registry+https://github.com/rust-lang/crates.io-index" 1695 | checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" 1696 | 1697 | [[package]] 1698 | name = "pest" 1699 | version = "2.4.0" 1700 | source = "registry+https://github.com/rust-lang/crates.io-index" 1701 | checksum = "dbc7bc69c062e492337d74d59b120c274fd3d261b6bf6d3207d499b4b379c41a" 1702 | dependencies = [ 1703 | "thiserror", 1704 | "ucd-trie", 1705 | ] 1706 | 1707 | [[package]] 1708 | name = "phf" 1709 | version = "0.8.0" 1710 | source = "registry+https://github.com/rust-lang/crates.io-index" 1711 | checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" 1712 | dependencies = [ 1713 | "phf_macros 0.8.0", 1714 | "phf_shared 0.8.0", 1715 | "proc-macro-hack", 1716 | ] 1717 | 1718 | [[package]] 1719 | name = "phf" 1720 | version = "0.10.1" 1721 | source = "registry+https://github.com/rust-lang/crates.io-index" 1722 | checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" 1723 | dependencies = [ 1724 | "phf_macros 0.10.0", 1725 | "phf_shared 0.10.0", 1726 | "proc-macro-hack", 1727 | ] 1728 | 1729 | [[package]] 1730 | name = "phf_codegen" 1731 | version = "0.8.0" 1732 | source = "registry+https://github.com/rust-lang/crates.io-index" 1733 | checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" 1734 | dependencies = [ 1735 | "phf_generator 0.8.0", 1736 | "phf_shared 0.8.0", 1737 | ] 1738 | 1739 | [[package]] 1740 | name = "phf_generator" 1741 | version = "0.8.0" 1742 | source = "registry+https://github.com/rust-lang/crates.io-index" 1743 | checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" 1744 | dependencies = [ 1745 | "phf_shared 0.8.0", 1746 | "rand 0.7.3", 1747 | ] 1748 | 1749 | [[package]] 1750 | name = "phf_generator" 1751 | version = "0.10.0" 1752 | source = "registry+https://github.com/rust-lang/crates.io-index" 1753 | checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" 1754 | dependencies = [ 1755 | "phf_shared 0.10.0", 1756 | "rand 0.8.5", 1757 | ] 1758 | 1759 | [[package]] 1760 | name = "phf_macros" 1761 | version = "0.8.0" 1762 | source = "registry+https://github.com/rust-lang/crates.io-index" 1763 | checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" 1764 | dependencies = [ 1765 | "phf_generator 0.8.0", 1766 | "phf_shared 0.8.0", 1767 | "proc-macro-hack", 1768 | "proc-macro2", 1769 | "quote", 1770 | "syn", 1771 | ] 1772 | 1773 | [[package]] 1774 | name = "phf_macros" 1775 | version = "0.10.0" 1776 | source = "registry+https://github.com/rust-lang/crates.io-index" 1777 | checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" 1778 | dependencies = [ 1779 | "phf_generator 0.10.0", 1780 | "phf_shared 0.10.0", 1781 | "proc-macro-hack", 1782 | "proc-macro2", 1783 | "quote", 1784 | "syn", 1785 | ] 1786 | 1787 | [[package]] 1788 | name = "phf_shared" 1789 | version = "0.8.0" 1790 | source = "registry+https://github.com/rust-lang/crates.io-index" 1791 | checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" 1792 | dependencies = [ 1793 | "siphasher", 1794 | ] 1795 | 1796 | [[package]] 1797 | name = "phf_shared" 1798 | version = "0.10.0" 1799 | source = "registry+https://github.com/rust-lang/crates.io-index" 1800 | checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" 1801 | dependencies = [ 1802 | "siphasher", 1803 | ] 1804 | 1805 | [[package]] 1806 | name = "pin-project-lite" 1807 | version = "0.2.9" 1808 | source = "registry+https://github.com/rust-lang/crates.io-index" 1809 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 1810 | 1811 | [[package]] 1812 | name = "pin-utils" 1813 | version = "0.1.0" 1814 | source = "registry+https://github.com/rust-lang/crates.io-index" 1815 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1816 | 1817 | [[package]] 1818 | name = "pkg-config" 1819 | version = "0.3.25" 1820 | source = "registry+https://github.com/rust-lang/crates.io-index" 1821 | checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" 1822 | 1823 | [[package]] 1824 | name = "plist" 1825 | version = "1.3.1" 1826 | source = "registry+https://github.com/rust-lang/crates.io-index" 1827 | checksum = "bd39bc6cdc9355ad1dc5eeedefee696bb35c34caf21768741e81826c0bbd7225" 1828 | dependencies = [ 1829 | "base64", 1830 | "indexmap", 1831 | "line-wrap", 1832 | "serde", 1833 | "time", 1834 | "xml-rs", 1835 | ] 1836 | 1837 | [[package]] 1838 | name = "png" 1839 | version = "0.11.0" 1840 | source = "registry+https://github.com/rust-lang/crates.io-index" 1841 | checksum = "f0b0cabbbd20c2d7f06dbf015e06aad59b6ca3d9ed14848783e98af9aaf19925" 1842 | dependencies = [ 1843 | "bitflags", 1844 | "deflate", 1845 | "inflate", 1846 | "num-iter", 1847 | ] 1848 | 1849 | [[package]] 1850 | name = "png" 1851 | version = "0.17.6" 1852 | source = "registry+https://github.com/rust-lang/crates.io-index" 1853 | checksum = "8f0e7f4c94ec26ff209cee506314212639d6c91b80afb82984819fafce9df01c" 1854 | dependencies = [ 1855 | "bitflags", 1856 | "crc32fast", 1857 | "flate2", 1858 | "miniz_oxide", 1859 | ] 1860 | 1861 | [[package]] 1862 | name = "ppv-lite86" 1863 | version = "0.2.16" 1864 | source = "registry+https://github.com/rust-lang/crates.io-index" 1865 | checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" 1866 | 1867 | [[package]] 1868 | name = "precomputed-hash" 1869 | version = "0.1.1" 1870 | source = "registry+https://github.com/rust-lang/crates.io-index" 1871 | checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" 1872 | 1873 | [[package]] 1874 | name = "proc-macro-crate" 1875 | version = "1.2.1" 1876 | source = "registry+https://github.com/rust-lang/crates.io-index" 1877 | checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" 1878 | dependencies = [ 1879 | "once_cell", 1880 | "thiserror", 1881 | "toml", 1882 | ] 1883 | 1884 | [[package]] 1885 | name = "proc-macro-error" 1886 | version = "1.0.4" 1887 | source = "registry+https://github.com/rust-lang/crates.io-index" 1888 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 1889 | dependencies = [ 1890 | "proc-macro-error-attr", 1891 | "proc-macro2", 1892 | "quote", 1893 | "syn", 1894 | "version_check", 1895 | ] 1896 | 1897 | [[package]] 1898 | name = "proc-macro-error-attr" 1899 | version = "1.0.4" 1900 | source = "registry+https://github.com/rust-lang/crates.io-index" 1901 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 1902 | dependencies = [ 1903 | "proc-macro2", 1904 | "quote", 1905 | "version_check", 1906 | ] 1907 | 1908 | [[package]] 1909 | name = "proc-macro-hack" 1910 | version = "0.5.19" 1911 | source = "registry+https://github.com/rust-lang/crates.io-index" 1912 | checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" 1913 | 1914 | [[package]] 1915 | name = "proc-macro2" 1916 | version = "1.0.46" 1917 | source = "registry+https://github.com/rust-lang/crates.io-index" 1918 | checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" 1919 | dependencies = [ 1920 | "unicode-ident", 1921 | ] 1922 | 1923 | [[package]] 1924 | name = "quote" 1925 | version = "1.0.21" 1926 | source = "registry+https://github.com/rust-lang/crates.io-index" 1927 | checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" 1928 | dependencies = [ 1929 | "proc-macro2", 1930 | ] 1931 | 1932 | [[package]] 1933 | name = "rand" 1934 | version = "0.7.3" 1935 | source = "registry+https://github.com/rust-lang/crates.io-index" 1936 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 1937 | dependencies = [ 1938 | "getrandom 0.1.16", 1939 | "libc", 1940 | "rand_chacha 0.2.2", 1941 | "rand_core 0.5.1", 1942 | "rand_hc", 1943 | "rand_pcg", 1944 | ] 1945 | 1946 | [[package]] 1947 | name = "rand" 1948 | version = "0.8.5" 1949 | source = "registry+https://github.com/rust-lang/crates.io-index" 1950 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1951 | dependencies = [ 1952 | "libc", 1953 | "rand_chacha 0.3.1", 1954 | "rand_core 0.6.4", 1955 | ] 1956 | 1957 | [[package]] 1958 | name = "rand_chacha" 1959 | version = "0.2.2" 1960 | source = "registry+https://github.com/rust-lang/crates.io-index" 1961 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 1962 | dependencies = [ 1963 | "ppv-lite86", 1964 | "rand_core 0.5.1", 1965 | ] 1966 | 1967 | [[package]] 1968 | name = "rand_chacha" 1969 | version = "0.3.1" 1970 | source = "registry+https://github.com/rust-lang/crates.io-index" 1971 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1972 | dependencies = [ 1973 | "ppv-lite86", 1974 | "rand_core 0.6.4", 1975 | ] 1976 | 1977 | [[package]] 1978 | name = "rand_core" 1979 | version = "0.5.1" 1980 | source = "registry+https://github.com/rust-lang/crates.io-index" 1981 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 1982 | dependencies = [ 1983 | "getrandom 0.1.16", 1984 | ] 1985 | 1986 | [[package]] 1987 | name = "rand_core" 1988 | version = "0.6.4" 1989 | source = "registry+https://github.com/rust-lang/crates.io-index" 1990 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1991 | dependencies = [ 1992 | "getrandom 0.2.7", 1993 | ] 1994 | 1995 | [[package]] 1996 | name = "rand_hc" 1997 | version = "0.2.0" 1998 | source = "registry+https://github.com/rust-lang/crates.io-index" 1999 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 2000 | dependencies = [ 2001 | "rand_core 0.5.1", 2002 | ] 2003 | 2004 | [[package]] 2005 | name = "rand_pcg" 2006 | version = "0.2.1" 2007 | source = "registry+https://github.com/rust-lang/crates.io-index" 2008 | checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" 2009 | dependencies = [ 2010 | "rand_core 0.5.1", 2011 | ] 2012 | 2013 | [[package]] 2014 | name = "raw-window-handle" 2015 | version = "0.5.0" 2016 | source = "registry+https://github.com/rust-lang/crates.io-index" 2017 | checksum = "ed7e3d950b66e19e0c372f3fa3fbbcf85b1746b571f74e0c2af6042a5c93420a" 2018 | dependencies = [ 2019 | "cty", 2020 | ] 2021 | 2022 | [[package]] 2023 | name = "redox_syscall" 2024 | version = "0.2.16" 2025 | source = "registry+https://github.com/rust-lang/crates.io-index" 2026 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 2027 | dependencies = [ 2028 | "bitflags", 2029 | ] 2030 | 2031 | [[package]] 2032 | name = "redox_users" 2033 | version = "0.4.3" 2034 | source = "registry+https://github.com/rust-lang/crates.io-index" 2035 | checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" 2036 | dependencies = [ 2037 | "getrandom 0.2.7", 2038 | "redox_syscall", 2039 | "thiserror", 2040 | ] 2041 | 2042 | [[package]] 2043 | name = "regex" 2044 | version = "1.6.0" 2045 | source = "registry+https://github.com/rust-lang/crates.io-index" 2046 | checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" 2047 | dependencies = [ 2048 | "aho-corasick", 2049 | "memchr", 2050 | "regex-syntax", 2051 | ] 2052 | 2053 | [[package]] 2054 | name = "regex-automata" 2055 | version = "0.1.10" 2056 | source = "registry+https://github.com/rust-lang/crates.io-index" 2057 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 2058 | dependencies = [ 2059 | "regex-syntax", 2060 | ] 2061 | 2062 | [[package]] 2063 | name = "regex-syntax" 2064 | version = "0.6.27" 2065 | source = "registry+https://github.com/rust-lang/crates.io-index" 2066 | checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" 2067 | 2068 | [[package]] 2069 | name = "remove_dir_all" 2070 | version = "0.5.3" 2071 | source = "registry+https://github.com/rust-lang/crates.io-index" 2072 | checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" 2073 | dependencies = [ 2074 | "winapi", 2075 | ] 2076 | 2077 | [[package]] 2078 | name = "rfd" 2079 | version = "0.10.0" 2080 | source = "registry+https://github.com/rust-lang/crates.io-index" 2081 | checksum = "0149778bd99b6959285b0933288206090c50e2327f47a9c463bfdbf45c8823ea" 2082 | dependencies = [ 2083 | "block", 2084 | "dispatch", 2085 | "glib-sys", 2086 | "gobject-sys", 2087 | "gtk-sys", 2088 | "js-sys", 2089 | "lazy_static", 2090 | "log", 2091 | "objc", 2092 | "objc-foundation", 2093 | "objc_id", 2094 | "raw-window-handle", 2095 | "wasm-bindgen", 2096 | "wasm-bindgen-futures", 2097 | "web-sys", 2098 | "windows 0.37.0", 2099 | ] 2100 | 2101 | [[package]] 2102 | name = "rustc_version" 2103 | version = "0.3.3" 2104 | source = "registry+https://github.com/rust-lang/crates.io-index" 2105 | checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" 2106 | dependencies = [ 2107 | "semver 0.11.0", 2108 | ] 2109 | 2110 | [[package]] 2111 | name = "rustc_version" 2112 | version = "0.4.0" 2113 | source = "registry+https://github.com/rust-lang/crates.io-index" 2114 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 2115 | dependencies = [ 2116 | "semver 1.0.14", 2117 | ] 2118 | 2119 | [[package]] 2120 | name = "rustversion" 2121 | version = "1.0.9" 2122 | source = "registry+https://github.com/rust-lang/crates.io-index" 2123 | checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" 2124 | 2125 | [[package]] 2126 | name = "ryu" 2127 | version = "1.0.11" 2128 | source = "registry+https://github.com/rust-lang/crates.io-index" 2129 | checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" 2130 | 2131 | [[package]] 2132 | name = "safemem" 2133 | version = "0.3.3" 2134 | source = "registry+https://github.com/rust-lang/crates.io-index" 2135 | checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" 2136 | 2137 | [[package]] 2138 | name = "same-file" 2139 | version = "1.0.6" 2140 | source = "registry+https://github.com/rust-lang/crates.io-index" 2141 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 2142 | dependencies = [ 2143 | "winapi-util", 2144 | ] 2145 | 2146 | [[package]] 2147 | name = "schannel" 2148 | version = "0.1.20" 2149 | source = "registry+https://github.com/rust-lang/crates.io-index" 2150 | checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" 2151 | dependencies = [ 2152 | "lazy_static", 2153 | "windows-sys", 2154 | ] 2155 | 2156 | [[package]] 2157 | name = "scoped-tls" 2158 | version = "1.0.0" 2159 | source = "registry+https://github.com/rust-lang/crates.io-index" 2160 | checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" 2161 | 2162 | [[package]] 2163 | name = "scopeguard" 2164 | version = "1.1.0" 2165 | source = "registry+https://github.com/rust-lang/crates.io-index" 2166 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 2167 | 2168 | [[package]] 2169 | name = "security-framework" 2170 | version = "2.7.0" 2171 | source = "registry+https://github.com/rust-lang/crates.io-index" 2172 | checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" 2173 | dependencies = [ 2174 | "bitflags", 2175 | "core-foundation", 2176 | "core-foundation-sys", 2177 | "libc", 2178 | "security-framework-sys", 2179 | ] 2180 | 2181 | [[package]] 2182 | name = "security-framework-sys" 2183 | version = "2.6.1" 2184 | source = "registry+https://github.com/rust-lang/crates.io-index" 2185 | checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" 2186 | dependencies = [ 2187 | "core-foundation-sys", 2188 | "libc", 2189 | ] 2190 | 2191 | [[package]] 2192 | name = "selectors" 2193 | version = "0.22.0" 2194 | source = "registry+https://github.com/rust-lang/crates.io-index" 2195 | checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" 2196 | dependencies = [ 2197 | "bitflags", 2198 | "cssparser", 2199 | "derive_more", 2200 | "fxhash", 2201 | "log", 2202 | "matches", 2203 | "phf 0.8.0", 2204 | "phf_codegen", 2205 | "precomputed-hash", 2206 | "servo_arc", 2207 | "smallvec", 2208 | "thin-slice", 2209 | ] 2210 | 2211 | [[package]] 2212 | name = "semver" 2213 | version = "0.11.0" 2214 | source = "registry+https://github.com/rust-lang/crates.io-index" 2215 | checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" 2216 | dependencies = [ 2217 | "semver-parser", 2218 | ] 2219 | 2220 | [[package]] 2221 | name = "semver" 2222 | version = "1.0.14" 2223 | source = "registry+https://github.com/rust-lang/crates.io-index" 2224 | checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" 2225 | dependencies = [ 2226 | "serde", 2227 | ] 2228 | 2229 | [[package]] 2230 | name = "semver-parser" 2231 | version = "0.10.2" 2232 | source = "registry+https://github.com/rust-lang/crates.io-index" 2233 | checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" 2234 | dependencies = [ 2235 | "pest", 2236 | ] 2237 | 2238 | [[package]] 2239 | name = "serde" 2240 | version = "1.0.145" 2241 | source = "registry+https://github.com/rust-lang/crates.io-index" 2242 | checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" 2243 | dependencies = [ 2244 | "serde_derive", 2245 | ] 2246 | 2247 | [[package]] 2248 | name = "serde_derive" 2249 | version = "1.0.145" 2250 | source = "registry+https://github.com/rust-lang/crates.io-index" 2251 | checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" 2252 | dependencies = [ 2253 | "proc-macro2", 2254 | "quote", 2255 | "syn", 2256 | ] 2257 | 2258 | [[package]] 2259 | name = "serde_json" 2260 | version = "1.0.85" 2261 | source = "registry+https://github.com/rust-lang/crates.io-index" 2262 | checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" 2263 | dependencies = [ 2264 | "itoa 1.0.4", 2265 | "ryu", 2266 | "serde", 2267 | ] 2268 | 2269 | [[package]] 2270 | name = "serde_repr" 2271 | version = "0.1.9" 2272 | source = "registry+https://github.com/rust-lang/crates.io-index" 2273 | checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca" 2274 | dependencies = [ 2275 | "proc-macro2", 2276 | "quote", 2277 | "syn", 2278 | ] 2279 | 2280 | [[package]] 2281 | name = "serde_urlencoded" 2282 | version = "0.7.1" 2283 | source = "registry+https://github.com/rust-lang/crates.io-index" 2284 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 2285 | dependencies = [ 2286 | "form_urlencoded", 2287 | "itoa 1.0.4", 2288 | "ryu", 2289 | "serde", 2290 | ] 2291 | 2292 | [[package]] 2293 | name = "serde_with" 2294 | version = "1.14.0" 2295 | source = "registry+https://github.com/rust-lang/crates.io-index" 2296 | checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" 2297 | dependencies = [ 2298 | "serde", 2299 | "serde_with_macros", 2300 | ] 2301 | 2302 | [[package]] 2303 | name = "serde_with_macros" 2304 | version = "1.5.2" 2305 | source = "registry+https://github.com/rust-lang/crates.io-index" 2306 | checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" 2307 | dependencies = [ 2308 | "darling", 2309 | "proc-macro2", 2310 | "quote", 2311 | "syn", 2312 | ] 2313 | 2314 | [[package]] 2315 | name = "serialize-to-javascript" 2316 | version = "0.1.1" 2317 | source = "registry+https://github.com/rust-lang/crates.io-index" 2318 | checksum = "c9823f2d3b6a81d98228151fdeaf848206a7855a7a042bbf9bf870449a66cafb" 2319 | dependencies = [ 2320 | "serde", 2321 | "serde_json", 2322 | "serialize-to-javascript-impl", 2323 | ] 2324 | 2325 | [[package]] 2326 | name = "serialize-to-javascript-impl" 2327 | version = "0.1.1" 2328 | source = "registry+https://github.com/rust-lang/crates.io-index" 2329 | checksum = "74064874e9f6a15f04c1f3cb627902d0e6b410abbf36668afa873c61889f1763" 2330 | dependencies = [ 2331 | "proc-macro2", 2332 | "quote", 2333 | "syn", 2334 | ] 2335 | 2336 | [[package]] 2337 | name = "servo_arc" 2338 | version = "0.1.1" 2339 | source = "registry+https://github.com/rust-lang/crates.io-index" 2340 | checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" 2341 | dependencies = [ 2342 | "nodrop", 2343 | "stable_deref_trait", 2344 | ] 2345 | 2346 | [[package]] 2347 | name = "sha2" 2348 | version = "0.10.6" 2349 | source = "registry+https://github.com/rust-lang/crates.io-index" 2350 | checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" 2351 | dependencies = [ 2352 | "cfg-if", 2353 | "cpufeatures", 2354 | "digest", 2355 | ] 2356 | 2357 | [[package]] 2358 | name = "sharded-slab" 2359 | version = "0.1.4" 2360 | source = "registry+https://github.com/rust-lang/crates.io-index" 2361 | checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" 2362 | dependencies = [ 2363 | "lazy_static", 2364 | ] 2365 | 2366 | [[package]] 2367 | name = "siphasher" 2368 | version = "0.3.10" 2369 | source = "registry+https://github.com/rust-lang/crates.io-index" 2370 | checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" 2371 | 2372 | [[package]] 2373 | name = "slab" 2374 | version = "0.4.7" 2375 | source = "registry+https://github.com/rust-lang/crates.io-index" 2376 | checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" 2377 | dependencies = [ 2378 | "autocfg", 2379 | ] 2380 | 2381 | [[package]] 2382 | name = "smallvec" 2383 | version = "1.10.0" 2384 | source = "registry+https://github.com/rust-lang/crates.io-index" 2385 | checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" 2386 | 2387 | [[package]] 2388 | name = "soup2" 2389 | version = "0.2.1" 2390 | source = "registry+https://github.com/rust-lang/crates.io-index" 2391 | checksum = "b2b4d76501d8ba387cf0fefbe055c3e0a59891d09f0f995ae4e4b16f6b60f3c0" 2392 | dependencies = [ 2393 | "bitflags", 2394 | "gio", 2395 | "glib", 2396 | "libc", 2397 | "once_cell", 2398 | "soup2-sys", 2399 | ] 2400 | 2401 | [[package]] 2402 | name = "soup2-sys" 2403 | version = "0.2.0" 2404 | source = "registry+https://github.com/rust-lang/crates.io-index" 2405 | checksum = "009ef427103fcb17f802871647a7fa6c60cbb654b4c4e4c0ac60a31c5f6dc9cf" 2406 | dependencies = [ 2407 | "bitflags", 2408 | "gio-sys", 2409 | "glib-sys", 2410 | "gobject-sys", 2411 | "libc", 2412 | "system-deps 5.0.0", 2413 | ] 2414 | 2415 | [[package]] 2416 | name = "stable_deref_trait" 2417 | version = "1.2.0" 2418 | source = "registry+https://github.com/rust-lang/crates.io-index" 2419 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 2420 | 2421 | [[package]] 2422 | name = "state" 2423 | version = "0.5.3" 2424 | source = "registry+https://github.com/rust-lang/crates.io-index" 2425 | checksum = "dbe866e1e51e8260c9eed836a042a5e7f6726bb2b411dffeaa712e19c388f23b" 2426 | dependencies = [ 2427 | "loom", 2428 | ] 2429 | 2430 | [[package]] 2431 | name = "string_cache" 2432 | version = "0.8.4" 2433 | source = "registry+https://github.com/rust-lang/crates.io-index" 2434 | checksum = "213494b7a2b503146286049378ce02b482200519accc31872ee8be91fa820a08" 2435 | dependencies = [ 2436 | "new_debug_unreachable", 2437 | "once_cell", 2438 | "parking_lot", 2439 | "phf_shared 0.10.0", 2440 | "precomputed-hash", 2441 | "serde", 2442 | ] 2443 | 2444 | [[package]] 2445 | name = "string_cache_codegen" 2446 | version = "0.5.2" 2447 | source = "registry+https://github.com/rust-lang/crates.io-index" 2448 | checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" 2449 | dependencies = [ 2450 | "phf_generator 0.10.0", 2451 | "phf_shared 0.10.0", 2452 | "proc-macro2", 2453 | "quote", 2454 | ] 2455 | 2456 | [[package]] 2457 | name = "strsim" 2458 | version = "0.10.0" 2459 | source = "registry+https://github.com/rust-lang/crates.io-index" 2460 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 2461 | 2462 | [[package]] 2463 | name = "syn" 2464 | version = "1.0.102" 2465 | source = "registry+https://github.com/rust-lang/crates.io-index" 2466 | checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" 2467 | dependencies = [ 2468 | "proc-macro2", 2469 | "quote", 2470 | "unicode-ident", 2471 | ] 2472 | 2473 | [[package]] 2474 | name = "system-deps" 2475 | version = "5.0.0" 2476 | source = "registry+https://github.com/rust-lang/crates.io-index" 2477 | checksum = "18db855554db7bd0e73e06cf7ba3df39f97812cb11d3f75e71c39bf45171797e" 2478 | dependencies = [ 2479 | "cfg-expr 0.9.1", 2480 | "heck 0.3.3", 2481 | "pkg-config", 2482 | "toml", 2483 | "version-compare 0.0.11", 2484 | ] 2485 | 2486 | [[package]] 2487 | name = "system-deps" 2488 | version = "6.0.2" 2489 | source = "registry+https://github.com/rust-lang/crates.io-index" 2490 | checksum = "a1a45a1c4c9015217e12347f2a411b57ce2c4fc543913b14b6fe40483328e709" 2491 | dependencies = [ 2492 | "cfg-expr 0.10.3", 2493 | "heck 0.4.0", 2494 | "pkg-config", 2495 | "toml", 2496 | "version-compare 0.1.0", 2497 | ] 2498 | 2499 | [[package]] 2500 | name = "tao" 2501 | version = "0.14.0" 2502 | source = "registry+https://github.com/rust-lang/crates.io-index" 2503 | checksum = "43336f5d1793543ba96e2a1e75f3a5c7dcd592743be06a0ab3a190f4fcb4b934" 2504 | dependencies = [ 2505 | "bitflags", 2506 | "cairo-rs", 2507 | "cc", 2508 | "cocoa", 2509 | "core-foundation", 2510 | "core-graphics", 2511 | "crossbeam-channel", 2512 | "dispatch", 2513 | "gdk", 2514 | "gdk-pixbuf", 2515 | "gdk-sys", 2516 | "gdkx11-sys", 2517 | "gio", 2518 | "glib", 2519 | "glib-sys", 2520 | "gtk", 2521 | "image", 2522 | "instant", 2523 | "jni", 2524 | "lazy_static", 2525 | "libc", 2526 | "log", 2527 | "ndk", 2528 | "ndk-context", 2529 | "ndk-sys", 2530 | "objc", 2531 | "once_cell", 2532 | "parking_lot", 2533 | "paste", 2534 | "png 0.17.6", 2535 | "raw-window-handle", 2536 | "scopeguard", 2537 | "serde", 2538 | "unicode-segmentation", 2539 | "uuid 1.1.2", 2540 | "windows 0.39.0", 2541 | "windows-implement", 2542 | "x11-dl", 2543 | ] 2544 | 2545 | [[package]] 2546 | name = "tar" 2547 | version = "0.4.38" 2548 | source = "registry+https://github.com/rust-lang/crates.io-index" 2549 | checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" 2550 | dependencies = [ 2551 | "filetime", 2552 | "libc", 2553 | "xattr", 2554 | ] 2555 | 2556 | [[package]] 2557 | name = "tauri" 2558 | version = "1.1.1" 2559 | source = "registry+https://github.com/rust-lang/crates.io-index" 2560 | checksum = "efbf22abd61d95ca9b2becd77f9db4c093892f73e8a07d21d8b0b2bf71a7bcea" 2561 | dependencies = [ 2562 | "anyhow", 2563 | "attohttpc", 2564 | "base64", 2565 | "cocoa", 2566 | "dirs-next", 2567 | "embed_plist", 2568 | "encoding_rs", 2569 | "flate2", 2570 | "futures-util", 2571 | "glib", 2572 | "glob", 2573 | "gtk", 2574 | "heck 0.4.0", 2575 | "http", 2576 | "ignore", 2577 | "minisign-verify", 2578 | "objc", 2579 | "once_cell", 2580 | "open", 2581 | "percent-encoding", 2582 | "rand 0.8.5", 2583 | "raw-window-handle", 2584 | "regex", 2585 | "rfd", 2586 | "semver 1.0.14", 2587 | "serde", 2588 | "serde_json", 2589 | "serde_repr", 2590 | "serialize-to-javascript", 2591 | "state", 2592 | "tar", 2593 | "tauri-macros", 2594 | "tauri-runtime", 2595 | "tauri-runtime-wry", 2596 | "tauri-utils", 2597 | "tempfile", 2598 | "thiserror", 2599 | "time", 2600 | "tokio", 2601 | "url", 2602 | "uuid 1.1.2", 2603 | "webkit2gtk", 2604 | "webview2-com", 2605 | "windows 0.39.0", 2606 | "zip", 2607 | ] 2608 | 2609 | [[package]] 2610 | name = "tauri-build" 2611 | version = "1.1.1" 2612 | source = "registry+https://github.com/rust-lang/crates.io-index" 2613 | checksum = "0991fb306849897439dbd4a72e4cbed2413e2eb26cb4b3ba220b94edba8b4b88" 2614 | dependencies = [ 2615 | "anyhow", 2616 | "cargo_toml", 2617 | "heck 0.4.0", 2618 | "json-patch", 2619 | "semver 1.0.14", 2620 | "serde_json", 2621 | "tauri-utils", 2622 | "winres", 2623 | ] 2624 | 2625 | [[package]] 2626 | name = "tauri-codegen" 2627 | version = "1.1.1" 2628 | source = "registry+https://github.com/rust-lang/crates.io-index" 2629 | checksum = "356fa253e40ae4d6ff02075011f2f2bb4066f5c9d8c1e16ca6912d7b75903ba6" 2630 | dependencies = [ 2631 | "base64", 2632 | "brotli", 2633 | "ico", 2634 | "json-patch", 2635 | "plist", 2636 | "png 0.17.6", 2637 | "proc-macro2", 2638 | "quote", 2639 | "regex", 2640 | "semver 1.0.14", 2641 | "serde", 2642 | "serde_json", 2643 | "sha2", 2644 | "tauri-utils", 2645 | "thiserror", 2646 | "time", 2647 | "uuid 1.1.2", 2648 | "walkdir", 2649 | ] 2650 | 2651 | [[package]] 2652 | name = "tauri-macros" 2653 | version = "1.1.1" 2654 | source = "registry+https://github.com/rust-lang/crates.io-index" 2655 | checksum = "d6051fd6940ddb22af452340d03c66a3e2f5d72e0788d4081d91e31528ccdc4d" 2656 | dependencies = [ 2657 | "heck 0.4.0", 2658 | "proc-macro2", 2659 | "quote", 2660 | "syn", 2661 | "tauri-codegen", 2662 | "tauri-utils", 2663 | ] 2664 | 2665 | [[package]] 2666 | name = "tauri-plugin-store" 2667 | version = "0.0.0" 2668 | source = "git+https://github.com/tauri-apps/tauri-plugin-store#4326f75446b8b9e0cb9904c65f258b81e23e544e" 2669 | dependencies = [ 2670 | "log", 2671 | "serde", 2672 | "serde_json", 2673 | "tauri", 2674 | "thiserror", 2675 | ] 2676 | 2677 | [[package]] 2678 | name = "tauri-runtime" 2679 | version = "0.11.1" 2680 | source = "registry+https://github.com/rust-lang/crates.io-index" 2681 | checksum = "d49439a5ea47f474572b854972f42eda2e02a470be5ca9609cc83bb66945abe2" 2682 | dependencies = [ 2683 | "gtk", 2684 | "http", 2685 | "http-range", 2686 | "infer", 2687 | "rand 0.8.5", 2688 | "raw-window-handle", 2689 | "serde", 2690 | "serde_json", 2691 | "tauri-utils", 2692 | "thiserror", 2693 | "uuid 1.1.2", 2694 | "webview2-com", 2695 | "windows 0.39.0", 2696 | ] 2697 | 2698 | [[package]] 2699 | name = "tauri-runtime-wry" 2700 | version = "0.11.1" 2701 | source = "registry+https://github.com/rust-lang/crates.io-index" 2702 | checksum = "28dce920995fd49907aa9bea7249ed1771454f11f7611924c920a1f75fb614d4" 2703 | dependencies = [ 2704 | "cocoa", 2705 | "gtk", 2706 | "percent-encoding", 2707 | "rand 0.8.5", 2708 | "raw-window-handle", 2709 | "tauri-runtime", 2710 | "tauri-utils", 2711 | "uuid 1.1.2", 2712 | "webkit2gtk", 2713 | "webview2-com", 2714 | "windows 0.39.0", 2715 | "wry", 2716 | ] 2717 | 2718 | [[package]] 2719 | name = "tauri-utils" 2720 | version = "1.1.1" 2721 | source = "registry+https://github.com/rust-lang/crates.io-index" 2722 | checksum = "1e8fdae6f29cef959809a3c3afef510c5b715a446a597ab8b791497585363f39" 2723 | dependencies = [ 2724 | "brotli", 2725 | "ctor", 2726 | "glob", 2727 | "heck 0.4.0", 2728 | "html5ever", 2729 | "json-patch", 2730 | "kuchiki", 2731 | "memchr", 2732 | "phf 0.10.1", 2733 | "proc-macro2", 2734 | "quote", 2735 | "semver 1.0.14", 2736 | "serde", 2737 | "serde_json", 2738 | "serde_with", 2739 | "thiserror", 2740 | "url", 2741 | "walkdir", 2742 | "windows 0.39.0", 2743 | ] 2744 | 2745 | [[package]] 2746 | name = "tempfile" 2747 | version = "3.3.0" 2748 | source = "registry+https://github.com/rust-lang/crates.io-index" 2749 | checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" 2750 | dependencies = [ 2751 | "cfg-if", 2752 | "fastrand", 2753 | "libc", 2754 | "redox_syscall", 2755 | "remove_dir_all", 2756 | "winapi", 2757 | ] 2758 | 2759 | [[package]] 2760 | name = "tendril" 2761 | version = "0.4.3" 2762 | source = "registry+https://github.com/rust-lang/crates.io-index" 2763 | checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" 2764 | dependencies = [ 2765 | "futf", 2766 | "mac", 2767 | "utf-8", 2768 | ] 2769 | 2770 | [[package]] 2771 | name = "thin-slice" 2772 | version = "0.1.1" 2773 | source = "registry+https://github.com/rust-lang/crates.io-index" 2774 | checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" 2775 | 2776 | [[package]] 2777 | name = "thiserror" 2778 | version = "1.0.37" 2779 | source = "registry+https://github.com/rust-lang/crates.io-index" 2780 | checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" 2781 | dependencies = [ 2782 | "thiserror-impl", 2783 | ] 2784 | 2785 | [[package]] 2786 | name = "thiserror-impl" 2787 | version = "1.0.37" 2788 | source = "registry+https://github.com/rust-lang/crates.io-index" 2789 | checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" 2790 | dependencies = [ 2791 | "proc-macro2", 2792 | "quote", 2793 | "syn", 2794 | ] 2795 | 2796 | [[package]] 2797 | name = "thread_local" 2798 | version = "1.1.4" 2799 | source = "registry+https://github.com/rust-lang/crates.io-index" 2800 | checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" 2801 | dependencies = [ 2802 | "once_cell", 2803 | ] 2804 | 2805 | [[package]] 2806 | name = "time" 2807 | version = "0.3.15" 2808 | source = "registry+https://github.com/rust-lang/crates.io-index" 2809 | checksum = "d634a985c4d4238ec39cacaed2e7ae552fbd3c476b552c1deac3021b7d7eaf0c" 2810 | dependencies = [ 2811 | "itoa 1.0.4", 2812 | "libc", 2813 | "num_threads", 2814 | ] 2815 | 2816 | [[package]] 2817 | name = "tinyvec" 2818 | version = "1.6.0" 2819 | source = "registry+https://github.com/rust-lang/crates.io-index" 2820 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 2821 | dependencies = [ 2822 | "tinyvec_macros", 2823 | ] 2824 | 2825 | [[package]] 2826 | name = "tinyvec_macros" 2827 | version = "0.1.0" 2828 | source = "registry+https://github.com/rust-lang/crates.io-index" 2829 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" 2830 | 2831 | [[package]] 2832 | name = "tokio" 2833 | version = "1.21.2" 2834 | source = "registry+https://github.com/rust-lang/crates.io-index" 2835 | checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" 2836 | dependencies = [ 2837 | "autocfg", 2838 | "bytes", 2839 | "memchr", 2840 | "num_cpus", 2841 | "pin-project-lite", 2842 | ] 2843 | 2844 | [[package]] 2845 | name = "toml" 2846 | version = "0.5.9" 2847 | source = "registry+https://github.com/rust-lang/crates.io-index" 2848 | checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" 2849 | dependencies = [ 2850 | "serde", 2851 | ] 2852 | 2853 | [[package]] 2854 | name = "tracing" 2855 | version = "0.1.37" 2856 | source = "registry+https://github.com/rust-lang/crates.io-index" 2857 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 2858 | dependencies = [ 2859 | "cfg-if", 2860 | "pin-project-lite", 2861 | "tracing-attributes", 2862 | "tracing-core", 2863 | ] 2864 | 2865 | [[package]] 2866 | name = "tracing-attributes" 2867 | version = "0.1.23" 2868 | source = "registry+https://github.com/rust-lang/crates.io-index" 2869 | checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" 2870 | dependencies = [ 2871 | "proc-macro2", 2872 | "quote", 2873 | "syn", 2874 | ] 2875 | 2876 | [[package]] 2877 | name = "tracing-core" 2878 | version = "0.1.30" 2879 | source = "registry+https://github.com/rust-lang/crates.io-index" 2880 | checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" 2881 | dependencies = [ 2882 | "once_cell", 2883 | "valuable", 2884 | ] 2885 | 2886 | [[package]] 2887 | name = "tracing-log" 2888 | version = "0.1.3" 2889 | source = "registry+https://github.com/rust-lang/crates.io-index" 2890 | checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" 2891 | dependencies = [ 2892 | "lazy_static", 2893 | "log", 2894 | "tracing-core", 2895 | ] 2896 | 2897 | [[package]] 2898 | name = "tracing-subscriber" 2899 | version = "0.3.16" 2900 | source = "registry+https://github.com/rust-lang/crates.io-index" 2901 | checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" 2902 | dependencies = [ 2903 | "matchers", 2904 | "nu-ansi-term", 2905 | "once_cell", 2906 | "regex", 2907 | "sharded-slab", 2908 | "smallvec", 2909 | "thread_local", 2910 | "tracing", 2911 | "tracing-core", 2912 | "tracing-log", 2913 | ] 2914 | 2915 | [[package]] 2916 | name = "treediff" 2917 | version = "3.0.2" 2918 | source = "registry+https://github.com/rust-lang/crates.io-index" 2919 | checksum = "761e8d5ad7ce14bb82b7e61ccc0ca961005a275a060b9644a2431aa11553c2ff" 2920 | dependencies = [ 2921 | "serde_json", 2922 | ] 2923 | 2924 | [[package]] 2925 | name = "typenum" 2926 | version = "1.15.0" 2927 | source = "registry+https://github.com/rust-lang/crates.io-index" 2928 | checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" 2929 | 2930 | [[package]] 2931 | name = "ucd-trie" 2932 | version = "0.1.5" 2933 | source = "registry+https://github.com/rust-lang/crates.io-index" 2934 | checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" 2935 | 2936 | [[package]] 2937 | name = "unicode-bidi" 2938 | version = "0.3.8" 2939 | source = "registry+https://github.com/rust-lang/crates.io-index" 2940 | checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" 2941 | 2942 | [[package]] 2943 | name = "unicode-ident" 2944 | version = "1.0.4" 2945 | source = "registry+https://github.com/rust-lang/crates.io-index" 2946 | checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" 2947 | 2948 | [[package]] 2949 | name = "unicode-normalization" 2950 | version = "0.1.22" 2951 | source = "registry+https://github.com/rust-lang/crates.io-index" 2952 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 2953 | dependencies = [ 2954 | "tinyvec", 2955 | ] 2956 | 2957 | [[package]] 2958 | name = "unicode-segmentation" 2959 | version = "1.10.0" 2960 | source = "registry+https://github.com/rust-lang/crates.io-index" 2961 | checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" 2962 | 2963 | [[package]] 2964 | name = "url" 2965 | version = "2.3.1" 2966 | source = "registry+https://github.com/rust-lang/crates.io-index" 2967 | checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" 2968 | dependencies = [ 2969 | "form_urlencoded", 2970 | "idna", 2971 | "percent-encoding", 2972 | "serde", 2973 | ] 2974 | 2975 | [[package]] 2976 | name = "utf-8" 2977 | version = "0.7.6" 2978 | source = "registry+https://github.com/rust-lang/crates.io-index" 2979 | checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" 2980 | 2981 | [[package]] 2982 | name = "uuid" 2983 | version = "0.8.2" 2984 | source = "registry+https://github.com/rust-lang/crates.io-index" 2985 | checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" 2986 | 2987 | [[package]] 2988 | name = "uuid" 2989 | version = "1.1.2" 2990 | source = "registry+https://github.com/rust-lang/crates.io-index" 2991 | checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f" 2992 | dependencies = [ 2993 | "getrandom 0.2.7", 2994 | ] 2995 | 2996 | [[package]] 2997 | name = "valuable" 2998 | version = "0.1.0" 2999 | source = "registry+https://github.com/rust-lang/crates.io-index" 3000 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 3001 | 3002 | [[package]] 3003 | name = "vcpkg" 3004 | version = "0.2.15" 3005 | source = "registry+https://github.com/rust-lang/crates.io-index" 3006 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 3007 | 3008 | [[package]] 3009 | name = "version-compare" 3010 | version = "0.0.11" 3011 | source = "registry+https://github.com/rust-lang/crates.io-index" 3012 | checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" 3013 | 3014 | [[package]] 3015 | name = "version-compare" 3016 | version = "0.1.0" 3017 | source = "registry+https://github.com/rust-lang/crates.io-index" 3018 | checksum = "fe88247b92c1df6b6de80ddc290f3976dbdf2f5f5d3fd049a9fb598c6dd5ca73" 3019 | 3020 | [[package]] 3021 | name = "version_check" 3022 | version = "0.9.4" 3023 | source = "registry+https://github.com/rust-lang/crates.io-index" 3024 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 3025 | 3026 | [[package]] 3027 | name = "walkdir" 3028 | version = "2.3.2" 3029 | source = "registry+https://github.com/rust-lang/crates.io-index" 3030 | checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" 3031 | dependencies = [ 3032 | "same-file", 3033 | "winapi", 3034 | "winapi-util", 3035 | ] 3036 | 3037 | [[package]] 3038 | name = "wasi" 3039 | version = "0.9.0+wasi-snapshot-preview1" 3040 | source = "registry+https://github.com/rust-lang/crates.io-index" 3041 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 3042 | 3043 | [[package]] 3044 | name = "wasi" 3045 | version = "0.11.0+wasi-snapshot-preview1" 3046 | source = "registry+https://github.com/rust-lang/crates.io-index" 3047 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 3048 | 3049 | [[package]] 3050 | name = "wasm-bindgen" 3051 | version = "0.2.83" 3052 | source = "registry+https://github.com/rust-lang/crates.io-index" 3053 | checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" 3054 | dependencies = [ 3055 | "cfg-if", 3056 | "wasm-bindgen-macro", 3057 | ] 3058 | 3059 | [[package]] 3060 | name = "wasm-bindgen-backend" 3061 | version = "0.2.83" 3062 | source = "registry+https://github.com/rust-lang/crates.io-index" 3063 | checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" 3064 | dependencies = [ 3065 | "bumpalo", 3066 | "log", 3067 | "once_cell", 3068 | "proc-macro2", 3069 | "quote", 3070 | "syn", 3071 | "wasm-bindgen-shared", 3072 | ] 3073 | 3074 | [[package]] 3075 | name = "wasm-bindgen-futures" 3076 | version = "0.4.33" 3077 | source = "registry+https://github.com/rust-lang/crates.io-index" 3078 | checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" 3079 | dependencies = [ 3080 | "cfg-if", 3081 | "js-sys", 3082 | "wasm-bindgen", 3083 | "web-sys", 3084 | ] 3085 | 3086 | [[package]] 3087 | name = "wasm-bindgen-macro" 3088 | version = "0.2.83" 3089 | source = "registry+https://github.com/rust-lang/crates.io-index" 3090 | checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" 3091 | dependencies = [ 3092 | "quote", 3093 | "wasm-bindgen-macro-support", 3094 | ] 3095 | 3096 | [[package]] 3097 | name = "wasm-bindgen-macro-support" 3098 | version = "0.2.83" 3099 | source = "registry+https://github.com/rust-lang/crates.io-index" 3100 | checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" 3101 | dependencies = [ 3102 | "proc-macro2", 3103 | "quote", 3104 | "syn", 3105 | "wasm-bindgen-backend", 3106 | "wasm-bindgen-shared", 3107 | ] 3108 | 3109 | [[package]] 3110 | name = "wasm-bindgen-shared" 3111 | version = "0.2.83" 3112 | source = "registry+https://github.com/rust-lang/crates.io-index" 3113 | checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" 3114 | 3115 | [[package]] 3116 | name = "web-sys" 3117 | version = "0.3.60" 3118 | source = "registry+https://github.com/rust-lang/crates.io-index" 3119 | checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" 3120 | dependencies = [ 3121 | "js-sys", 3122 | "wasm-bindgen", 3123 | ] 3124 | 3125 | [[package]] 3126 | name = "webkit2gtk" 3127 | version = "0.18.0" 3128 | source = "registry+https://github.com/rust-lang/crates.io-index" 3129 | checksum = "29952969fb5e10fe834a52eb29ad0814ccdfd8387159b0933edf1344a1c9cdcc" 3130 | dependencies = [ 3131 | "bitflags", 3132 | "cairo-rs", 3133 | "gdk", 3134 | "gdk-sys", 3135 | "gio", 3136 | "gio-sys", 3137 | "glib", 3138 | "glib-sys", 3139 | "gobject-sys", 3140 | "gtk", 3141 | "gtk-sys", 3142 | "javascriptcore-rs", 3143 | "libc", 3144 | "once_cell", 3145 | "soup2", 3146 | "webkit2gtk-sys", 3147 | ] 3148 | 3149 | [[package]] 3150 | name = "webkit2gtk-sys" 3151 | version = "0.18.0" 3152 | source = "registry+https://github.com/rust-lang/crates.io-index" 3153 | checksum = "4d76ca6ecc47aeba01ec61e480139dda143796abcae6f83bcddf50d6b5b1dcf3" 3154 | dependencies = [ 3155 | "atk-sys", 3156 | "bitflags", 3157 | "cairo-sys-rs", 3158 | "gdk-pixbuf-sys", 3159 | "gdk-sys", 3160 | "gio-sys", 3161 | "glib-sys", 3162 | "gobject-sys", 3163 | "gtk-sys", 3164 | "javascriptcore-rs-sys", 3165 | "libc", 3166 | "pango-sys", 3167 | "pkg-config", 3168 | "soup2-sys", 3169 | "system-deps 6.0.2", 3170 | ] 3171 | 3172 | [[package]] 3173 | name = "webview2-com" 3174 | version = "0.19.1" 3175 | source = "registry+https://github.com/rust-lang/crates.io-index" 3176 | checksum = "b4a769c9f1a64a8734bde70caafac2b96cada12cd4aefa49196b3a386b8b4178" 3177 | dependencies = [ 3178 | "webview2-com-macros", 3179 | "webview2-com-sys", 3180 | "windows 0.39.0", 3181 | "windows-implement", 3182 | ] 3183 | 3184 | [[package]] 3185 | name = "webview2-com-macros" 3186 | version = "0.6.0" 3187 | source = "registry+https://github.com/rust-lang/crates.io-index" 3188 | checksum = "eaebe196c01691db62e9e4ca52c5ef1e4fd837dcae27dae3ada599b5a8fd05ac" 3189 | dependencies = [ 3190 | "proc-macro2", 3191 | "quote", 3192 | "syn", 3193 | ] 3194 | 3195 | [[package]] 3196 | name = "webview2-com-sys" 3197 | version = "0.19.0" 3198 | source = "registry+https://github.com/rust-lang/crates.io-index" 3199 | checksum = "aac48ef20ddf657755fdcda8dfed2a7b4fc7e4581acce6fe9b88c3d64f29dee7" 3200 | dependencies = [ 3201 | "regex", 3202 | "serde", 3203 | "serde_json", 3204 | "thiserror", 3205 | "windows 0.39.0", 3206 | "windows-bindgen", 3207 | "windows-metadata", 3208 | ] 3209 | 3210 | [[package]] 3211 | name = "winapi" 3212 | version = "0.3.9" 3213 | source = "registry+https://github.com/rust-lang/crates.io-index" 3214 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 3215 | dependencies = [ 3216 | "winapi-i686-pc-windows-gnu", 3217 | "winapi-x86_64-pc-windows-gnu", 3218 | ] 3219 | 3220 | [[package]] 3221 | name = "winapi-i686-pc-windows-gnu" 3222 | version = "0.4.0" 3223 | source = "registry+https://github.com/rust-lang/crates.io-index" 3224 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 3225 | 3226 | [[package]] 3227 | name = "winapi-util" 3228 | version = "0.1.5" 3229 | source = "registry+https://github.com/rust-lang/crates.io-index" 3230 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 3231 | dependencies = [ 3232 | "winapi", 3233 | ] 3234 | 3235 | [[package]] 3236 | name = "winapi-x86_64-pc-windows-gnu" 3237 | version = "0.4.0" 3238 | source = "registry+https://github.com/rust-lang/crates.io-index" 3239 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 3240 | 3241 | [[package]] 3242 | name = "windows" 3243 | version = "0.32.0" 3244 | source = "registry+https://github.com/rust-lang/crates.io-index" 3245 | checksum = "fbedf6db9096bc2364adce0ae0aa636dcd89f3c3f2cd67947062aaf0ca2a10ec" 3246 | dependencies = [ 3247 | "windows_aarch64_msvc 0.32.0", 3248 | "windows_i686_gnu 0.32.0", 3249 | "windows_i686_msvc 0.32.0", 3250 | "windows_x86_64_gnu 0.32.0", 3251 | "windows_x86_64_msvc 0.32.0", 3252 | ] 3253 | 3254 | [[package]] 3255 | name = "windows" 3256 | version = "0.37.0" 3257 | source = "registry+https://github.com/rust-lang/crates.io-index" 3258 | checksum = "57b543186b344cc61c85b5aab0d2e3adf4e0f99bc076eff9aa5927bcc0b8a647" 3259 | dependencies = [ 3260 | "windows_aarch64_msvc 0.37.0", 3261 | "windows_i686_gnu 0.37.0", 3262 | "windows_i686_msvc 0.37.0", 3263 | "windows_x86_64_gnu 0.37.0", 3264 | "windows_x86_64_msvc 0.37.0", 3265 | ] 3266 | 3267 | [[package]] 3268 | name = "windows" 3269 | version = "0.39.0" 3270 | source = "registry+https://github.com/rust-lang/crates.io-index" 3271 | checksum = "f1c4bd0a50ac6020f65184721f758dba47bb9fbc2133df715ec74a237b26794a" 3272 | dependencies = [ 3273 | "windows-implement", 3274 | "windows_aarch64_msvc 0.39.0", 3275 | "windows_i686_gnu 0.39.0", 3276 | "windows_i686_msvc 0.39.0", 3277 | "windows_x86_64_gnu 0.39.0", 3278 | "windows_x86_64_msvc 0.39.0", 3279 | ] 3280 | 3281 | [[package]] 3282 | name = "windows-bindgen" 3283 | version = "0.39.0" 3284 | source = "registry+https://github.com/rust-lang/crates.io-index" 3285 | checksum = "68003dbd0e38abc0fb85b939240f4bce37c43a5981d3df37ccbaaa981b47cb41" 3286 | dependencies = [ 3287 | "windows-metadata", 3288 | "windows-tokens", 3289 | ] 3290 | 3291 | [[package]] 3292 | name = "windows-implement" 3293 | version = "0.39.0" 3294 | source = "registry+https://github.com/rust-lang/crates.io-index" 3295 | checksum = "ba01f98f509cb5dc05f4e5fc95e535f78260f15fea8fe1a8abdd08f774f1cee7" 3296 | dependencies = [ 3297 | "syn", 3298 | "windows-tokens", 3299 | ] 3300 | 3301 | [[package]] 3302 | name = "windows-metadata" 3303 | version = "0.39.0" 3304 | source = "registry+https://github.com/rust-lang/crates.io-index" 3305 | checksum = "9ee5e275231f07c6e240d14f34e1b635bf1faa1c76c57cfd59a5cdb9848e4278" 3306 | 3307 | [[package]] 3308 | name = "windows-sys" 3309 | version = "0.36.1" 3310 | source = "registry+https://github.com/rust-lang/crates.io-index" 3311 | checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" 3312 | dependencies = [ 3313 | "windows_aarch64_msvc 0.36.1", 3314 | "windows_i686_gnu 0.36.1", 3315 | "windows_i686_msvc 0.36.1", 3316 | "windows_x86_64_gnu 0.36.1", 3317 | "windows_x86_64_msvc 0.36.1", 3318 | ] 3319 | 3320 | [[package]] 3321 | name = "windows-tokens" 3322 | version = "0.39.0" 3323 | source = "registry+https://github.com/rust-lang/crates.io-index" 3324 | checksum = "f838de2fe15fe6bac988e74b798f26499a8b21a9d97edec321e79b28d1d7f597" 3325 | 3326 | [[package]] 3327 | name = "windows_aarch64_msvc" 3328 | version = "0.32.0" 3329 | source = "registry+https://github.com/rust-lang/crates.io-index" 3330 | checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" 3331 | 3332 | [[package]] 3333 | name = "windows_aarch64_msvc" 3334 | version = "0.36.1" 3335 | source = "registry+https://github.com/rust-lang/crates.io-index" 3336 | checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" 3337 | 3338 | [[package]] 3339 | name = "windows_aarch64_msvc" 3340 | version = "0.37.0" 3341 | source = "registry+https://github.com/rust-lang/crates.io-index" 3342 | checksum = "2623277cb2d1c216ba3b578c0f3cf9cdebeddb6e66b1b218bb33596ea7769c3a" 3343 | 3344 | [[package]] 3345 | name = "windows_aarch64_msvc" 3346 | version = "0.39.0" 3347 | source = "registry+https://github.com/rust-lang/crates.io-index" 3348 | checksum = "ec7711666096bd4096ffa835238905bb33fb87267910e154b18b44eaabb340f2" 3349 | 3350 | [[package]] 3351 | name = "windows_i686_gnu" 3352 | version = "0.32.0" 3353 | source = "registry+https://github.com/rust-lang/crates.io-index" 3354 | checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" 3355 | 3356 | [[package]] 3357 | name = "windows_i686_gnu" 3358 | version = "0.36.1" 3359 | source = "registry+https://github.com/rust-lang/crates.io-index" 3360 | checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" 3361 | 3362 | [[package]] 3363 | name = "windows_i686_gnu" 3364 | version = "0.37.0" 3365 | source = "registry+https://github.com/rust-lang/crates.io-index" 3366 | checksum = "d3925fd0b0b804730d44d4b6278c50f9699703ec49bcd628020f46f4ba07d9e1" 3367 | 3368 | [[package]] 3369 | name = "windows_i686_gnu" 3370 | version = "0.39.0" 3371 | source = "registry+https://github.com/rust-lang/crates.io-index" 3372 | checksum = "763fc57100a5f7042e3057e7e8d9bdd7860d330070251a73d003563a3bb49e1b" 3373 | 3374 | [[package]] 3375 | name = "windows_i686_msvc" 3376 | version = "0.32.0" 3377 | source = "registry+https://github.com/rust-lang/crates.io-index" 3378 | checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" 3379 | 3380 | [[package]] 3381 | name = "windows_i686_msvc" 3382 | version = "0.36.1" 3383 | source = "registry+https://github.com/rust-lang/crates.io-index" 3384 | checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" 3385 | 3386 | [[package]] 3387 | name = "windows_i686_msvc" 3388 | version = "0.37.0" 3389 | source = "registry+https://github.com/rust-lang/crates.io-index" 3390 | checksum = "ce907ac74fe331b524c1298683efbf598bb031bc84d5e274db2083696d07c57c" 3391 | 3392 | [[package]] 3393 | name = "windows_i686_msvc" 3394 | version = "0.39.0" 3395 | source = "registry+https://github.com/rust-lang/crates.io-index" 3396 | checksum = "7bc7cbfe58828921e10a9f446fcaaf649204dcfe6c1ddd712c5eebae6bda1106" 3397 | 3398 | [[package]] 3399 | name = "windows_x86_64_gnu" 3400 | version = "0.32.0" 3401 | source = "registry+https://github.com/rust-lang/crates.io-index" 3402 | checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" 3403 | 3404 | [[package]] 3405 | name = "windows_x86_64_gnu" 3406 | version = "0.36.1" 3407 | source = "registry+https://github.com/rust-lang/crates.io-index" 3408 | checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" 3409 | 3410 | [[package]] 3411 | name = "windows_x86_64_gnu" 3412 | version = "0.37.0" 3413 | source = "registry+https://github.com/rust-lang/crates.io-index" 3414 | checksum = "2babfba0828f2e6b32457d5341427dcbb577ceef556273229959ac23a10af33d" 3415 | 3416 | [[package]] 3417 | name = "windows_x86_64_gnu" 3418 | version = "0.39.0" 3419 | source = "registry+https://github.com/rust-lang/crates.io-index" 3420 | checksum = "6868c165637d653ae1e8dc4d82c25d4f97dd6605eaa8d784b5c6e0ab2a252b65" 3421 | 3422 | [[package]] 3423 | name = "windows_x86_64_msvc" 3424 | version = "0.32.0" 3425 | source = "registry+https://github.com/rust-lang/crates.io-index" 3426 | checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" 3427 | 3428 | [[package]] 3429 | name = "windows_x86_64_msvc" 3430 | version = "0.36.1" 3431 | source = "registry+https://github.com/rust-lang/crates.io-index" 3432 | checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" 3433 | 3434 | [[package]] 3435 | name = "windows_x86_64_msvc" 3436 | version = "0.37.0" 3437 | source = "registry+https://github.com/rust-lang/crates.io-index" 3438 | checksum = "f4dd6dc7df2d84cf7b33822ed5b86318fb1781948e9663bacd047fc9dd52259d" 3439 | 3440 | [[package]] 3441 | name = "windows_x86_64_msvc" 3442 | version = "0.39.0" 3443 | source = "registry+https://github.com/rust-lang/crates.io-index" 3444 | checksum = "5e4d40883ae9cae962787ca76ba76390ffa29214667a111db9e0a1ad8377e809" 3445 | 3446 | [[package]] 3447 | name = "winres" 3448 | version = "0.1.12" 3449 | source = "registry+https://github.com/rust-lang/crates.io-index" 3450 | checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c" 3451 | dependencies = [ 3452 | "toml", 3453 | ] 3454 | 3455 | [[package]] 3456 | name = "wry" 3457 | version = "0.21.1" 3458 | source = "registry+https://github.com/rust-lang/crates.io-index" 3459 | checksum = "ff5c1352b4266fdf92c63479d2f58ab4cd29dc4e78fbc1b62011ed1227926945" 3460 | dependencies = [ 3461 | "base64", 3462 | "block", 3463 | "cocoa", 3464 | "core-graphics", 3465 | "crossbeam-channel", 3466 | "gdk", 3467 | "gio", 3468 | "glib", 3469 | "gtk", 3470 | "html5ever", 3471 | "http", 3472 | "kuchiki", 3473 | "libc", 3474 | "log", 3475 | "objc", 3476 | "objc_id", 3477 | "once_cell", 3478 | "serde", 3479 | "serde_json", 3480 | "sha2", 3481 | "tao", 3482 | "thiserror", 3483 | "url", 3484 | "webkit2gtk", 3485 | "webkit2gtk-sys", 3486 | "webview2-com", 3487 | "windows 0.39.0", 3488 | "windows-implement", 3489 | ] 3490 | 3491 | [[package]] 3492 | name = "x11" 3493 | version = "2.20.0" 3494 | source = "registry+https://github.com/rust-lang/crates.io-index" 3495 | checksum = "f7ae97874a928d821b061fce3d1fc52f08071dd53c89a6102bc06efcac3b2908" 3496 | dependencies = [ 3497 | "libc", 3498 | "pkg-config", 3499 | ] 3500 | 3501 | [[package]] 3502 | name = "x11-dl" 3503 | version = "2.20.0" 3504 | source = "registry+https://github.com/rust-lang/crates.io-index" 3505 | checksum = "0c83627bc137605acc00bb399c7b908ef460b621fc37c953db2b09f88c449ea6" 3506 | dependencies = [ 3507 | "lazy_static", 3508 | "libc", 3509 | "pkg-config", 3510 | ] 3511 | 3512 | [[package]] 3513 | name = "xattr" 3514 | version = "0.2.3" 3515 | source = "registry+https://github.com/rust-lang/crates.io-index" 3516 | checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" 3517 | dependencies = [ 3518 | "libc", 3519 | ] 3520 | 3521 | [[package]] 3522 | name = "xml-rs" 3523 | version = "0.8.4" 3524 | source = "registry+https://github.com/rust-lang/crates.io-index" 3525 | checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" 3526 | 3527 | [[package]] 3528 | name = "zip" 3529 | version = "0.6.2" 3530 | source = "registry+https://github.com/rust-lang/crates.io-index" 3531 | checksum = "bf225bcf73bb52cbb496e70475c7bd7a3f769df699c0020f6c7bd9a96dcf0b8d" 3532 | dependencies = [ 3533 | "byteorder", 3534 | "crc32fast", 3535 | "crossbeam-utils", 3536 | ] 3537 | -------------------------------------------------------------------------------- /src-tauri/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "app" 3 | version = "0.1.0" 4 | description = "A Tauri App" 5 | authors = ["you"] 6 | license = "" 7 | repository = "" 8 | default-run = "app" 9 | edition = "2021" 10 | rust-version = "1.57" 11 | 12 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 13 | 14 | [build-dependencies] 15 | tauri-build = { version = "1.1.1", features = [] } 16 | 17 | [dependencies] 18 | serde_json = "1.0" 19 | serde = { version = "1.0", features = ["derive"] } 20 | tauri = { version = "1.1.1", features = ["http-request", "shell-open", "updater"] } 21 | 22 | [dependencies.tauri-plugin-store] 23 | git = "https://github.com/tauri-apps/tauri-plugin-store" 24 | 25 | [features] 26 | # by default Tauri runs in production mode 27 | # when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL 28 | default = [ "custom-protocol" ] 29 | # this feature is used for production builds where `devPath` points to the filesystem 30 | # DO NOT remove this 31 | custom-protocol = [ "tauri/custom-protocol" ] 32 | -------------------------------------------------------------------------------- /src-tauri/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | tauri_build::build() 3 | } 4 | -------------------------------------------------------------------------------- /src-tauri/icons/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/src-tauri/icons/128x128.png -------------------------------------------------------------------------------- /src-tauri/icons/128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/src-tauri/icons/128x128@2x.png -------------------------------------------------------------------------------- /src-tauri/icons/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/src-tauri/icons/32x32.png -------------------------------------------------------------------------------- /src-tauri/icons/Square107x107Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/src-tauri/icons/Square107x107Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square142x142Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/src-tauri/icons/Square142x142Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square150x150Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/src-tauri/icons/Square150x150Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square284x284Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/src-tauri/icons/Square284x284Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square30x30Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/src-tauri/icons/Square30x30Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square310x310Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/src-tauri/icons/Square310x310Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square44x44Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/src-tauri/icons/Square44x44Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square71x71Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/src-tauri/icons/Square71x71Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square89x89Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/src-tauri/icons/Square89x89Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/src-tauri/icons/StoreLogo.png -------------------------------------------------------------------------------- /src-tauri/icons/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/src-tauri/icons/icon.icns -------------------------------------------------------------------------------- /src-tauri/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/src-tauri/icons/icon.ico -------------------------------------------------------------------------------- /src-tauri/icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whale4113/mooc-helper/d14e36ba06c5e747c6dbf4ac1ea2efde87702afb/src-tauri/icons/icon.png -------------------------------------------------------------------------------- /src-tauri/src/main.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr( 2 | all(not(debug_assertions), target_os = "windows"), 3 | windows_subsystem = "windows" 4 | )] 5 | 6 | use tauri_plugin_store::PluginBuilder; 7 | 8 | fn main() { 9 | let builder = tauri::Builder::default(); 10 | 11 | builder 12 | .plugin(PluginBuilder::default().build()) 13 | .setup(|app| { 14 | #[cfg(debug_assertions)] // only include this code on debug builds 15 | { 16 | use tauri::Manager; 17 | let window = app.get_window("main").unwrap(); 18 | window.open_devtools(); 19 | } 20 | Ok(()) 21 | }) 22 | .run(tauri::generate_context!()) 23 | .expect("error while running tauri application"); 24 | } 25 | -------------------------------------------------------------------------------- /src-tauri/tauri.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../node_modules/@tauri-apps/cli/schema.json", 3 | "build": { 4 | "beforeBuildCommand": "cross-env NEXT_PUBLIC_TAURI=1 npm run export", 5 | "beforeDevCommand": "npm run dev", 6 | "devPath": "http://localhost:3000", 7 | "distDir": "../out" 8 | }, 9 | "package": { 10 | "productName": "mooc-helper", 11 | "version": "0.1.1" 12 | }, 13 | "tauri": { 14 | "allowlist": { 15 | "http": { 16 | "request": true, 17 | "scope": ["https://www.icourse163.org/*"] 18 | }, 19 | "shell": { 20 | "open": true, 21 | "scope": [] 22 | } 23 | }, 24 | "bundle": { 25 | "active": true, 26 | "category": "DeveloperTool", 27 | "copyright": "", 28 | "deb": { 29 | "depends": [] 30 | }, 31 | "externalBin": [], 32 | "icon": [ 33 | "icons/32x32.png", 34 | "icons/128x128.png", 35 | "icons/128x128@2x.png", 36 | "icons/icon.icns", 37 | "icons/icon.ico" 38 | ], 39 | "identifier": "com.lujunji.mooc-helper", 40 | "longDescription": "", 41 | "macOS": { 42 | "entitlements": null, 43 | "exceptionDomain": "", 44 | "frameworks": [], 45 | "providerShortName": null, 46 | "signingIdentity": null 47 | }, 48 | "resources": [], 49 | "shortDescription": "", 50 | "targets": "all", 51 | "windows": { 52 | "certificateThumbprint": null, 53 | "digestAlgorithm": "sha256", 54 | "timestampUrl": "" 55 | } 56 | }, 57 | "security": { 58 | "csp": null 59 | }, 60 | "updater": { 61 | "active": true, 62 | "endpoints": [ 63 | "https://mooc-helper.vercel.app/api/update/{{target}}/{{current_version}}" 64 | ], 65 | "dialog": true, 66 | "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDhCRERDQTgzN0JDQ0M2OTAKUldTUXhzeDdnOHJkaXlqYXhQdWlyUHJUMFo4bDEvN3B0WVNDU05EaGJUN3FzM3NDdUQyeVZJWGoK" 67 | }, 68 | "windows": [ 69 | { 70 | "fullscreen": false, 71 | "center": true, 72 | "width": 1024, 73 | "height": 768, 74 | "resizable": true, 75 | "title": "mooc-helper" 76 | } 77 | ] 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/@types/index.d.ts: -------------------------------------------------------------------------------- 1 | interface Result { 2 | status: { code: number; message: string }; 3 | results: T; 4 | } 5 | 6 | interface Pagination { 7 | totlePageCount: number; 8 | } 9 | 10 | interface Course { 11 | id: number; 12 | currentTermId: number; 13 | name: string; 14 | imgUrl: string; 15 | fromCourseId: number; 16 | schoolPanel: SchoolPanel; 17 | termPanel: { 18 | id: number; 19 | }; 20 | } 21 | 22 | interface SchoolPanel { 23 | name: string; 24 | } 25 | 26 | interface Chapter { 27 | id: number; 28 | name: string; 29 | homeworks: { 30 | contentId: number; 31 | name: string; 32 | }[]; 33 | quizs: { 34 | contentId: number; 35 | name: string; 36 | }[]; 37 | exam: { 38 | objectTestVo: { 39 | id: number; 40 | name: string; 41 | }; 42 | subjectTestVo: { 43 | id: number; 44 | name: string; 45 | }; 46 | }; 47 | } 48 | 49 | interface Content { 50 | contentId: number; 51 | contentType: number; 52 | name: string; 53 | } 54 | 55 | interface Homework extends Content {} 56 | 57 | interface Quiz extends Content {} 58 | 59 | interface ObjectiveQ { 60 | id: number; 61 | type: number; 62 | title: string; 63 | optionDtos: { 64 | id: string; 65 | answer: boolean; 66 | content: string; 67 | }[]; 68 | stdAnswer: string; 69 | } 70 | 71 | interface SubjectiveQ { 72 | id: number; 73 | type: number; 74 | title: string; 75 | judgeDtos: { 76 | id: number; 77 | msg: string; 78 | }[]; 79 | } 80 | 81 | interface MocPaperDto { 82 | objectiveQList: ObjectiveQ[]; 83 | subjectiveQList: SubjectiveQ[]; 84 | } 85 | -------------------------------------------------------------------------------- /src/api.ts: -------------------------------------------------------------------------------- 1 | import request from "@/lib/request"; 2 | 3 | export const courseList = async (page: number, pageSize: number) => 4 | request>({ 5 | url: "mob/course/getAllMyCourseList/v2", 6 | method: "POST", 7 | query: { 8 | p: page, 9 | psize: pageSize, 10 | type: 30, 11 | }, 12 | }); 13 | 14 | export const courseInfo = async (courseId: number, currentTermId: number) => 15 | request>({ 16 | url: "mob/course/courseLearn/v1", 17 | method: "POST", 18 | query: { 19 | cid: courseId, 20 | tid: currentTermId, 21 | }, 22 | }); 23 | 24 | export const homework = async (currentTermId: number) => 25 | request>({ 26 | url: "mob/course/homeworkPaperDto/v1", 27 | method: "POST", 28 | query: { 29 | tid: currentTermId, 30 | }, 31 | }); 32 | 33 | export const test = async (testId: number) => 34 | request>({ 35 | url: "mob/course/paperDetail/v1", 36 | method: "POST", 37 | query: { 38 | testId, 39 | isExercise: true, 40 | withStdAnswerAndAnalyse: true, 41 | }, 42 | }); 43 | -------------------------------------------------------------------------------- /src/components/HTML.tsx: -------------------------------------------------------------------------------- 1 | import type { HTMLReactParserOptions, Element } from "html-react-parser"; 2 | import * as React from "react"; 3 | // import Image from "next/image"; 4 | import parse, { domToReact } from "html-react-parser"; 5 | 6 | // const regExp = /width: (?[1-9]+)px; height: (?[1-9]+)px;/; 7 | 8 | // https://github.com/lujunji-xiaolu/mooc-helper/issues/10 9 | const rewriteAddressMap = new Map([ 10 | [/img[0-2]\.ph\.126\.net/g, "img-ph-mirror.nosdn.127.net"], 11 | ]); 12 | 13 | const parseStyles = (styles: string = ""): { [key: string]: string } => { 14 | return styles 15 | .split(";") 16 | .filter((style) => style.split(":").length === 2) 17 | .map((style) => [ 18 | style 19 | .split(":")[0] 20 | .trim() 21 | .replace(/-./g, (c) => c.substring(1).toUpperCase()), 22 | style.split(":")[1].trim(), 23 | ]) 24 | .reduce( 25 | (styleObj, style) => ({ 26 | ...styleObj, 27 | [style[0]]: style[1], 28 | }), 29 | {} 30 | ); 31 | }; 32 | 33 | const options: HTMLReactParserOptions = { 34 | replace(domNode) { 35 | if (domNode.type === "tag" && (domNode as Element).tagName === "span") { 36 | const { attribs, children } = domNode as Element; 37 | return ( 38 | 39 | {domToReact(children, options)} 40 | 41 | ); 42 | } 43 | if (domNode.type === "tag" && (domNode as Element).tagName === "p") { 44 | const { attribs, children } = domNode as Element; 45 | return ( 46 | 47 | {domToReact(children, options)} 48 | 49 | ); 50 | } 51 | // if (domNode.type === "tag" && (domNode as Element).tagName === "img") { 52 | // const { attribs } = domNode as Element; 53 | // const execArray = regExp.exec(attribs.style); 54 | // if (execArray && execArray.groups) { 55 | // const width = window.parseInt(execArray.groups.width, 10); 56 | // const height = window.parseInt(execArray.groups.height, 10); 57 | // return ; 58 | // } 59 | // } 60 | }, 61 | }; 62 | 63 | export default function HTML({ html }: { html: string }) { 64 | for (const [searchValue, replaceValue] of rewriteAddressMap) { 65 | html = html.replaceAll(searchValue, replaceValue); 66 | } 67 | 68 | return <>{parse(html, options)}; 69 | } 70 | -------------------------------------------------------------------------------- /src/components/Link.tsx: -------------------------------------------------------------------------------- 1 | import { forwardRef } from "react"; 2 | import clsx from "clsx"; 3 | import { useRouter } from "next/router"; 4 | import NextLink, { LinkProps as NextLinkProps } from "next/link"; 5 | import MuiLink, { LinkProps as MuiLinkProps } from "@mui/material/Link"; 6 | import { styled } from "@mui/material/styles"; 7 | 8 | /** 9 | * File to keep in sync with: 10 | * 11 | * - /docs/src/modules/components/Link.tsx 12 | * - /examples/nextjs/src/Link.tsx 13 | * - /examples/nextjs-with-typescript/src/Link.tsx 14 | */ 15 | 16 | // Add support for the sx prop for consistency with the other branches. 17 | const Anchor = styled("a")({}); 18 | 19 | interface NextLinkComposedProps 20 | extends Omit< 21 | React.AnchorHTMLAttributes, 22 | "href" | "onMouseEnter" | "onClick" 23 | >, 24 | Omit { 25 | to: NextLinkProps["href"]; 26 | linkAs?: NextLinkProps["as"]; 27 | href?: NextLinkProps["href"]; 28 | } 29 | 30 | const NextLinkComposed = forwardRef( 31 | function NextLinkComposed(props, ref) { 32 | const { 33 | to, 34 | linkAs, 35 | href, 36 | replace, 37 | scroll, 38 | shallow, 39 | prefetch, 40 | locale, 41 | ...other 42 | } = props; 43 | 44 | return ( 45 | 55 | 56 | 57 | ); 58 | } 59 | ); 60 | 61 | export type LinkProps = { 62 | activeClassName?: string; 63 | as?: NextLinkProps["as"]; 64 | href: NextLinkProps["href"]; 65 | linkAs?: NextLinkProps["as"]; // Useful when the as prop is shallow by styled(). 66 | noLinkStyle?: boolean; 67 | } & Omit & 68 | Omit; 69 | 70 | // A styled version of the Next.js Link component: 71 | // https://nextjs.org/docs/api-reference/next/link 72 | const Link = forwardRef(function Link( 73 | props, 74 | ref 75 | ) { 76 | const { 77 | activeClassName = "active", 78 | as: asProp, 79 | className: classNameProps, 80 | href, 81 | linkAs: linkAsProp, 82 | noLinkStyle, 83 | role, // Link don't have roles. 84 | ...other 85 | } = props; 86 | 87 | const router = useRouter(); 88 | const pathname = typeof href === "string" ? href : href?.pathname; 89 | const className = clsx(classNameProps, { 90 | [activeClassName]: router.pathname === pathname && activeClassName, 91 | }); 92 | 93 | const isExternal = 94 | typeof href === "string" && 95 | (href.indexOf("http") === 0 || href.indexOf("mailto:") === 0); 96 | 97 | if (isExternal) { 98 | if (noLinkStyle) { 99 | return ; 100 | } 101 | 102 | return ; 103 | } 104 | 105 | let linkAs = linkAsProp || asProp || (href as string); 106 | 107 | if (noLinkStyle) { 108 | return ( 109 | 116 | ); 117 | } 118 | 119 | return ( 120 | 128 | ); 129 | }); 130 | 131 | export default Link; 132 | -------------------------------------------------------------------------------- /src/components/Logo.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | import Box from "@mui/material/Box"; 3 | import SvgIcon from "@mui/material/SvgIcon"; 4 | 5 | function LogoIcon() { 6 | return ( 7 | 8 | 12 | 13 | ); 14 | } 15 | 16 | export default function Logo() { 17 | return ( 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /src/constants.ts: -------------------------------------------------------------------------------- 1 | export const PAGE_SIZE = 5; 2 | export const TAURI_STORE_PATH = "settings.json"; 3 | -------------------------------------------------------------------------------- /src/features/chapter-tree-view/ChapterTreeView.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import TreeView from "@mui/lab/TreeView"; 3 | import KeyboardArrowDownRounded from "@mui/icons-material/KeyboardArrowDownRounded"; 4 | import KeyboardArrowUpRounded from "@mui/icons-material/KeyboardArrowUpRounded"; 5 | import CustomTreeItem from "./CustomTreeItem"; 6 | import { useRecoilValue, useSetRecoilState } from "recoil"; 7 | import { courseInfo } from "@/api"; 8 | import { selectedContentState, selectedCourseState } from "@/features/course"; 9 | import { messageState } from "@/features/message"; 10 | 11 | export default function ChapterTreeView() { 12 | const [expanded, setExpanded] = React.useState([]); 13 | const [selected, setSelected] = React.useState([]); 14 | const [chapters, setChapters] = React.useState([]); 15 | 16 | const selectedCourse = useRecoilValue(selectedCourseState); 17 | const setSelectedContent = useSetRecoilState(selectedContentState); 18 | const setMessage = useSetRecoilState(messageState); 19 | 20 | React.useEffect(() => { 21 | const handleSelectedCourseChange = async (course: Course | null) => { 22 | if (course) { 23 | try { 24 | const { status, results } = await courseInfo( 25 | course.id, 26 | course.termPanel.id 27 | ); 28 | if (status.code === 0) { 29 | setChapters(results.termDto.chapters); 30 | if (selectedCourse) { 31 | setExpanded([String(selectedCourse.id)]); 32 | } 33 | } else { 34 | setMessage({ 35 | show: true, 36 | msg: status.message, 37 | }); 38 | } 39 | } catch (error) { 40 | setMessage({ 41 | show: true, 42 | msg: String(error), 43 | }); 44 | } 45 | } 46 | }; 47 | 48 | handleSelectedCourseChange(selectedCourse); 49 | }, [selectedCourse, setMessage]); 50 | 51 | return ( 52 | 56 | } 57 | defaultExpandIcon={ 58 | 59 | } 60 | defaultEndIcon={
} 61 | sx={{ py: 1, overflowY: "auto" }} 62 | expanded={expanded} 63 | selected={selected} 64 | onNodeToggle={(_: React.SyntheticEvent, nodeIds) => 65 | setExpanded(nodeIds) 66 | } 67 | onNodeSelect={( 68 | _: React.SyntheticEvent, 69 | nodeIds: string[] 70 | ) => setSelected(nodeIds)} 71 | > 72 | {selectedCourse && ( 73 | 78 | {chapters.map((chapter) => ( 79 | 84 | {chapter.homeworks?.map((homework) => ( 85 | 92 | setSelectedContent({ 93 | type: "homework", 94 | contentId: homework.contentId, 95 | }), 96 | }} 97 | /> 98 | ))} 99 | {chapter.quizs?.map((quiz) => ( 100 | { 107 | setSelectedContent({ 108 | type: "quiz", 109 | contentId: quiz.contentId, 110 | }); 111 | }, 112 | }} 113 | /> 114 | ))} 115 | {chapter.exam?.objectTestVo && ( 116 | 123 | setSelectedContent({ 124 | type: "quiz", 125 | contentId: chapter.exam.objectTestVo.id, 126 | }), 127 | }} 128 | /> 129 | )} 130 | {chapter.exam?.subjectTestVo && ( 131 | 138 | setSelectedContent({ 139 | type: "homework", 140 | contentId: chapter.exam.subjectTestVo.id, 141 | }), 142 | }} 143 | /> 144 | )} 145 | 146 | ))} 147 | 148 | )} 149 | 150 | ); 151 | } 152 | -------------------------------------------------------------------------------- /src/features/chapter-tree-view/CustomContent.tsx: -------------------------------------------------------------------------------- 1 | import type { TreeItemContentProps } from "@mui/lab/TreeItem"; 2 | 3 | import * as React from "react"; 4 | import { useTreeItem } from "@mui/lab/TreeItem"; 5 | 6 | import Box from "@mui/material/Box"; 7 | import Typography from "@mui/material/Typography"; 8 | 9 | import clsx from "clsx"; 10 | 11 | const CustomContent = React.forwardRef(function CustomContent( 12 | props: TreeItemContentProps & { lastNestedChild?: boolean }, 13 | ref 14 | ) { 15 | const { 16 | lastNestedChild, 17 | classes, 18 | className, 19 | label, 20 | nodeId, 21 | icon: iconProp, 22 | expansionIcon, 23 | displayIcon, 24 | onClick, 25 | } = props; 26 | 27 | const { 28 | disabled, 29 | expanded, 30 | selected, 31 | focused, 32 | handleExpansion, 33 | handleSelection, 34 | preventSelection, 35 | } = useTreeItem(nodeId); 36 | 37 | const handleMouseDown = ( 38 | event: React.MouseEvent 39 | ) => { 40 | preventSelection(event); 41 | }; 42 | 43 | const handleExpansionClick = ( 44 | event: React.MouseEvent 45 | ) => { 46 | handleExpansion(event); 47 | }; 48 | 49 | const handleSelectionClick = ( 50 | event: React.MouseEvent 51 | ) => { 52 | handleSelection(event); 53 | if (onClick) { 54 | onClick(event); 55 | } 56 | }; 57 | 58 | return ( 59 | /* @ts-ignore -- Key event is handled by the TreeView */ 60 | } 71 | > 72 | {lastNestedChild ? ( 73 | 84 | ) : ( 85 | iconProp 86 | )} 87 | 102 | {label} 103 | 104 | {expansionIcon || displayIcon} 105 | 106 | ); 107 | }); 108 | 109 | export default CustomContent; 110 | -------------------------------------------------------------------------------- /src/features/chapter-tree-view/CustomTreeItem.tsx: -------------------------------------------------------------------------------- 1 | import type { TreeItemProps } from "@mui/lab/TreeItem"; 2 | 3 | import TreeItem from "@mui/lab/TreeItem"; 4 | import CustomContent from "./CustomContent"; 5 | 6 | import { styled } from "@mui/material/styles"; 7 | 8 | const StyledTreeItem = styled(TreeItem)(({ theme }) => ({ 9 | "& .MuiTreeItem-content": { 10 | border: "none", 11 | backgroundColor: "transparent", 12 | borderRadius: 5, 13 | padding: theme.spacing(0.5), 14 | textAlign: "left", 15 | position: "relative", 16 | zIndex: 1, 17 | }, 18 | "& .MuiTreeItem-content .MuiTreeItem-label": { 19 | paddingLeft: theme.spacing(1), 20 | }, 21 | "& .MuiTreeItem-root": { 22 | position: "relative", 23 | "&:last-of-type": { 24 | "&:before": { 25 | height: 34 / 2, 26 | }, 27 | }, 28 | "&:before": { 29 | content: '""', 30 | display: "block", 31 | position: "absolute", 32 | left: -18, 33 | height: "100%", 34 | width: 2, 35 | backgroundColor: 36 | theme.palette.mode === "dark" 37 | ? theme.palette.primaryDark[600] 38 | : theme.palette.grey[200], 39 | }, 40 | }, 41 | "& .MuiTreeItem-group": { 42 | marginLeft: 0, 43 | paddingLeft: theme.spacing(3), 44 | "& .MuiTreeItem-content": { 45 | "&:before": { 46 | content: '""', 47 | position: "absolute", 48 | display: "block", 49 | width: 24, 50 | height: 2, 51 | backgroundColor: 52 | theme.palette.mode === "dark" 53 | ? theme.palette.primaryDark[600] 54 | : theme.palette.grey[200], 55 | top: "50%", 56 | left: 6, 57 | transform: "translate(-100%, -50%)", 58 | }, 59 | }, 60 | }, 61 | })); 62 | 63 | const CustomTreeItem = ( 64 | props: TreeItemProps & { 65 | ContentProps?: { lastNestedChild?: boolean }; 66 | } 67 | ) => ; 68 | 69 | export default CustomTreeItem; 70 | -------------------------------------------------------------------------------- /src/features/chapter-tree-view/index.ts: -------------------------------------------------------------------------------- 1 | import ChapterTreeView from "./ChapterTreeView"; 2 | 3 | export { ChapterTreeView }; 4 | -------------------------------------------------------------------------------- /src/features/course/CourseCard.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import Box from "@mui/material/Box"; 3 | import Button from "@mui/material/Button"; 4 | import Typography from "@mui/material/Typography"; 5 | import Paper from "@mui/material/Paper"; 6 | import LaunchRounded from "@mui/icons-material/LaunchRounded"; 7 | import Avatar from "@mui/material/Avatar"; 8 | import Link from "@/components/Link"; 9 | import { styled } from "@mui/material/styles"; 10 | 11 | const Label = styled("span")(({ theme }) => { 12 | return { 13 | fontSize: theme.typography.pxToRem(12), 14 | fontWeight: 700, 15 | lineHeight: "20px", 16 | border: `1px solid ${ 17 | theme.palette.mode === "dark" 18 | ? theme.palette.primaryDark[500] 19 | : theme.palette.grey[200] 20 | }`, 21 | backgroundColor: 22 | theme.palette.mode === "dark" ? theme.palette.primaryDark[800] : "#FFF", 23 | padding: theme.spacing(0, 0.8), 24 | borderRadius: 5, 25 | whiteSpace: "nowrap", 26 | }; 27 | }); 28 | 29 | interface CourseCardProps { 30 | width: number; 31 | course: Course; 32 | onClick: (course: Course) => void; 33 | } 34 | 35 | export default function CourseCard({ 36 | width, 37 | course, 38 | onClick, 39 | }: CourseCardProps) { 40 | const { name, imgUrl, schoolPanel, fromCourseId } = course; 41 | 42 | return ( 43 | onClick(course)} 53 | > 54 | 59 | 60 | 61 | 71 | {name}{" "} 72 | 73 | 77 | 89 | 90 | 91 | 98 | 99 | 100 | 101 | 102 | ); 103 | } 104 | -------------------------------------------------------------------------------- /src/features/course/CourseDrawer.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import Box from "@mui/material/Box"; 3 | import SwipeableDrawer from "@mui/material/Drawer"; 4 | import Tooltip from "@mui/material/Tooltip"; 5 | import IconButton from "@mui/material/IconButton"; 6 | import BookIcon from "@mui/icons-material/Book"; 7 | import Pagination from "@mui/material/Pagination"; 8 | import CourseCard from "@/features/course/CourseCard"; 9 | import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil"; 10 | import { countState, courseListState, selectedCourseState } from "."; 11 | import { courseList as getCourseList } from "@/api"; 12 | import { PAGE_SIZE } from "@/constants"; 13 | import { messageState } from "@/features/message"; 14 | 15 | export default function SwipeableTemporaryDrawer() { 16 | const [open, setOpen] = React.useState(false); 17 | 18 | const [courseList, setCourseList] = useRecoilState(courseListState); 19 | const count = useRecoilValue(countState); 20 | const setMessage = useSetRecoilState(messageState); 21 | const setSelectedCourse = useSetRecoilState(selectedCourseState); 22 | 23 | const changeCourseList: ( 24 | event: React.ChangeEvent, 25 | page: number 26 | ) => void = React.useCallback( 27 | async (_, page: number) => { 28 | try { 29 | const { status, results } = await getCourseList(page, PAGE_SIZE); 30 | if (status.code === 0) { 31 | setCourseList(results.result); 32 | } else { 33 | setMessage({ 34 | show: true, 35 | msg: status.message, 36 | }); 37 | } 38 | } catch (error) { 39 | setMessage({ 40 | show: true, 41 | msg: String(error), 42 | }); 43 | } 44 | }, 45 | [setCourseList, setMessage] 46 | ); 47 | 48 | const selectCourse = (course: Course) => { 49 | setSelectedCourse(course); 50 | setOpen(false); 51 | }; 52 | 53 | return ( 54 | <> 55 | 56 | setOpen(true)}> 57 | 58 | 59 | 60 | setOpen(false)} 64 | > 65 | ({ 67 | overflow: "auto", 68 | "&::-webkit-scrollbar-thumb": { 69 | border: `3px solid ${theme.palette.primaryDark["900"]}`, 70 | borderRadius: 20, 71 | backgroundColor: theme.palette.primaryDark["700"], 72 | }, 73 | "&::-webkit-scrollbar": { 74 | width: 12, 75 | }, 76 | })} 77 | > 78 | {courseList.map((course) => ( 79 | 85 | ))} 86 | 87 | 88 | 89 | 90 | ); 91 | } 92 | -------------------------------------------------------------------------------- /src/features/course/index.ts: -------------------------------------------------------------------------------- 1 | import { atom } from "recoil"; 2 | import CourseDrawer from "./CourseDrawer"; 3 | import CourseCard from "./CourseCard"; 4 | 5 | export const courseListState = atom({ 6 | key: "courseListState", 7 | default: [], 8 | }); 9 | 10 | export const recentCourseListState = atom({ 11 | key: "recentListState", 12 | default: [], 13 | }); 14 | 15 | export const selectedCourseState = atom({ 16 | key: "selectedCourseState", 17 | default: null, 18 | }); 19 | 20 | export const selectedContentState = atom<{ 21 | type: "homework" | "quiz"; 22 | contentId: number; 23 | } | null>({ 24 | key: "selectedContentState", 25 | default: null, 26 | }); 27 | 28 | export const countState = atom({ 29 | key: "countState", 30 | default: 0, 31 | }); 32 | 33 | export { CourseDrawer, CourseCard }; 34 | -------------------------------------------------------------------------------- /src/features/homework/Homework.tsx: -------------------------------------------------------------------------------- 1 | import Box from "@mui/material/Box"; 2 | import Typography from "@mui/material/Typography"; 3 | import HTML from "@/components/HTML"; 4 | 5 | export default function Homework({ 6 | mocPaperDto, 7 | }: { 8 | mocPaperDto: MocPaperDto; 9 | }) { 10 | return ( 11 | 12 | {mocPaperDto.subjectiveQList.map((subjectiveQ) => { 13 | return ( 14 | 27 | theme.palette.mode === "dark" 28 | ? "primaryDark.700" 29 | : "grey.100", 30 | "@media (hover: none)": { 31 | bgcolor: "transparent", 32 | }, 33 | }, 34 | }} 35 | > 36 | 37 | 43 | {/* {htmr(subjectiveQ.title, { transform })} */} 44 | 45 | 46 | 47 | 52 | {subjectiveQ.judgeDtos.map((judgeDto) => ( 53 | 57 | 58 | 59 | ))} 60 | 61 | 62 | 63 | ); 64 | })} 65 | 66 | ); 67 | } 68 | -------------------------------------------------------------------------------- /src/features/homework/index.ts: -------------------------------------------------------------------------------- 1 | import Homework from "./Homework"; 2 | 3 | export default Homework; 4 | -------------------------------------------------------------------------------- /src/features/layout/AppHeader.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import Container from "@mui/material/Container"; 3 | import { styled, alpha } from "@mui/material/styles"; 4 | 5 | const Header = styled("header")(({ theme }) => ({ 6 | position: "sticky", 7 | top: 0, 8 | transition: theme.transitions.create("top"), 9 | zIndex: theme.zIndex.appBar, 10 | backdropFilter: "blur(20px)", 11 | boxShadow: `inset 0px -1px 1px ${ 12 | theme.palette.mode === "dark" 13 | ? theme.palette.primaryDark[700] 14 | : theme.palette.grey[100] 15 | }`, 16 | backgroundColor: 17 | theme.palette.mode === "dark" 18 | ? alpha(theme.palette.primaryDark[900], 0.72) 19 | : "rgba(255,255,255,0.72)", 20 | })); 21 | 22 | const AppHeader: React.FC = ({ children }) => { 23 | return ( 24 |
25 | 26 | {children} 27 | 28 |
29 | ); 30 | }; 31 | 32 | export default AppHeader; 33 | -------------------------------------------------------------------------------- /src/features/layout/Banner.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import Typography from "@mui/material/Typography"; 3 | import Link from "@/components/Link"; 4 | 5 | interface BannerProps { 6 | message: string | null; 7 | link: string | null; 8 | linkDescription: string | null; 9 | } 10 | 11 | const Banner: React.FC = ({ message, link, linkDescription }) => { 12 | if (!message) return null; 13 | 14 | return ( 15 | 25 | theme.palette.mode === "dark" 26 | ? `linear-gradient(90deg, ${theme.palette.primary[900]}, ${theme.palette.primary[600]} 120%)` 27 | : `linear-gradient(-90deg, ${theme.palette.primary[700]}, ${theme.palette.primary[500]} 120%)`, 28 | fontSize: (theme) => theme.typography.pxToRem(13), 29 | }} 30 | > 31 | {message} 32 | {link ? ( 33 | 43 | {linkDescription ?? "查看详情"} → 44 | 45 | ) : null} 46 | 47 | ); 48 | }; 49 | 50 | export default Banner; 51 | -------------------------------------------------------------------------------- /src/features/layout/index.ts: -------------------------------------------------------------------------------- 1 | import AppHeader from "./AppHeader"; 2 | import Banner from "./Banner"; 3 | 4 | export { AppHeader, Banner }; 5 | -------------------------------------------------------------------------------- /src/features/message.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import Snackbar from "@mui/material/Snackbar"; 3 | import { atom, useRecoilState } from "recoil"; 4 | 5 | export const messageState = atom({ 6 | key: "messageState", 7 | default: { show: false, msg: "" }, 8 | }); 9 | 10 | export const Message: React.FC = () => { 11 | const [message, setMessage] = useRecoilState(messageState); 12 | 13 | const closeMessage = React.useCallback( 14 | (_: React.SyntheticEvent | Event, reason?: string) => { 15 | if (reason === "clickaway") { 16 | return; 17 | } 18 | setMessage({ show: false, msg: "" }); 19 | }, 20 | [setMessage] 21 | ); 22 | 23 | return ( 24 | 30 | ); 31 | }; 32 | -------------------------------------------------------------------------------- /src/features/paper/Paper.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import Box from "@mui/material/Box"; 3 | import SingleChoice from "./questions/SingleChoice"; 4 | import MultipleChoice from "./questions/MultipleChoice"; 5 | import Completion from "./questions/Completion"; 6 | 7 | export default function Paper({ mocPaperDto }: { mocPaperDto: MocPaperDto }) { 8 | return ( 9 | 10 | {mocPaperDto.objectiveQList.map((objectiveQ) => { 11 | switch (objectiveQ.type) { 12 | case 1: 13 | case 4: 14 | return ; 15 | case 2: 16 | return ; 17 | case 3: 18 | return ; 19 | default: 20 | return null; 21 | } 22 | })} 23 | 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /src/features/paper/index.ts: -------------------------------------------------------------------------------- 1 | import Paper from "./Paper"; 2 | 3 | export default Paper; 4 | -------------------------------------------------------------------------------- /src/features/paper/questions/Completion.tsx: -------------------------------------------------------------------------------- 1 | import Box from "@mui/material/Box"; 2 | import Typography from "@mui/material/Typography"; 3 | import HTML from "@/components/HTML"; 4 | 5 | interface CompletionProps { 6 | question: ObjectiveQ; 7 | } 8 | 9 | const Completion: React.FC = ({ question }) => { 10 | return ( 11 | 23 | theme.palette.mode === "dark" ? "primaryDark.700" : "grey.100", 24 | "@media (hover: none)": { 25 | bgcolor: "transparent", 26 | }, 27 | }, 28 | }} 29 | > 30 | 36 | 37 | 38 | 43 | 44 | 45 | 46 | ); 47 | }; 48 | 49 | export default Completion; 50 | -------------------------------------------------------------------------------- /src/features/paper/questions/MultipleChoice.tsx: -------------------------------------------------------------------------------- 1 | import Box from "@mui/material/Box"; 2 | import Typography from "@mui/material/Typography"; 3 | import FormControl from "@mui/material/FormControl"; 4 | import FormGroup from "@mui/material/FormGroup"; 5 | import FormControlLabel from "@mui/material/FormControlLabel"; 6 | import Checkbox from "@mui/material/Checkbox"; 7 | import HTML from "@/components/HTML"; 8 | 9 | interface MultipleChoiceProps { 10 | question: ObjectiveQ; 11 | } 12 | 13 | const MultipleChoice: React.FC = ({ question }) => { 14 | return ( 15 | 27 | theme.palette.mode === "dark" ? "primaryDark.700" : "grey.100", 28 | "@media (hover: none)": { 29 | bgcolor: "transparent", 30 | }, 31 | }, 32 | }} 33 | > 34 | 40 | 41 | 42 | 43 | 44 | {question.optionDtos.map((optionDto) => ( 45 | } 48 | label={ 49 | 50 | 51 | 52 | } 53 | /> 54 | ))} 55 | 56 | 57 | 58 | ); 59 | }; 60 | 61 | export default MultipleChoice; 62 | -------------------------------------------------------------------------------- /src/features/paper/questions/SingleChoice.tsx: -------------------------------------------------------------------------------- 1 | import Box from "@mui/material/Box"; 2 | import Typography from "@mui/material/Typography"; 3 | import FormControl from "@mui/material/FormControl"; 4 | import RadioGroup from "@mui/material/RadioGroup"; 5 | import FormControlLabel from "@mui/material/FormControlLabel"; 6 | import Radio from "@mui/material/Radio"; 7 | import HTML from "@/components/HTML"; 8 | 9 | interface SingleChoiceProps { 10 | question: ObjectiveQ; 11 | } 12 | 13 | const SingleChoice: React.FC = ({ question }) => { 14 | return ( 15 | 27 | theme.palette.mode === "dark" ? "primaryDark.700" : "grey.100", 28 | "@media (hover: none)": { 29 | bgcolor: "transparent", 30 | }, 31 | }, 32 | }} 33 | > 34 | 40 | 41 | 42 | 43 | optionDtosItem.answer) 46 | ?.id 47 | } 48 | > 49 | {question.optionDtos.map((optionDto) => ( 50 | } 54 | label={ 55 | 56 | 57 | 58 | } 59 | /> 60 | ))} 61 | 62 | 63 | 64 | ); 65 | }; 66 | 67 | export default SingleChoice; 68 | -------------------------------------------------------------------------------- /src/features/settings/MobToken.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import Input from "@mui/material/Input"; 3 | import { courseList as getCourseList } from "@/api"; 4 | import { PAGE_SIZE } from "@/constants"; 5 | import { useSetRecoilState } from "recoil"; 6 | import { 7 | countState, 8 | courseListState, 9 | recentCourseListState, 10 | } from "@/features/course"; 11 | import { messageState } from "@/features/message"; 12 | import store from "@/lib/store"; 13 | 14 | export default function MobToken() { 15 | const [value, setValue] = React.useState(""); 16 | const setCount = useSetRecoilState(countState); 17 | const setCourseList = useSetRecoilState(courseListState); 18 | const setRecentCourseList = useSetRecoilState(recentCourseListState); 19 | const setMessage = useSetRecoilState(messageState); 20 | 21 | const changeValue: React.ChangeEventHandler< 22 | HTMLTextAreaElement | HTMLInputElement 23 | > = async (ev) => { 24 | setValue(ev.target.value); 25 | }; 26 | 27 | const handleTokenChange = async () => { 28 | try { 29 | await store.set("mob-token", value); 30 | const { status, results } = await getCourseList(1, PAGE_SIZE); 31 | if (status.code === 0) { 32 | setCount(results.pagination.totlePageCount); 33 | setCourseList(results.result); 34 | setRecentCourseList(results.result); 35 | } else { 36 | setMessage({ 37 | show: true, 38 | msg: status.message, 39 | }); 40 | } 41 | } catch (error) { 42 | setMessage({ 43 | show: true, 44 | msg: String(error), 45 | }); 46 | } 47 | }; 48 | 49 | React.useEffect(() => { 50 | store.get("mob-token").then((storedMobToken) => { 51 | setValue(storedMobToken ?? ""); 52 | }); 53 | }, []); 54 | 55 | return ( 56 | 62 | ); 63 | } 64 | -------------------------------------------------------------------------------- /src/features/settings/ModeToggleButton.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import ToggleButtonGroup from "@mui/material/ToggleButtonGroup"; 3 | import ToggleButton from "@mui/material/ToggleButton"; 4 | import LightModeIcon from "@mui/icons-material/LightMode"; 5 | import DarkModeOutlinedIcon from "@mui/icons-material/DarkModeOutlined"; 6 | import SettingsBrightnessIcon from "@mui/icons-material/SettingsBrightness"; 7 | import { styled } from "@mui/material/styles"; 8 | import { useRecoilState } from "recoil"; 9 | import { modeState } from "@/features/theme"; 10 | import store from "@/lib/store"; 11 | 12 | const IconToggleButton = styled(ToggleButton)({ 13 | display: "flex", 14 | justifyContent: "center", 15 | width: "100%", 16 | "& > *": { 17 | marginRight: "8px", 18 | }, 19 | }); 20 | 21 | export default function ModeToggleButton() { 22 | const [mode, setMode] = useRecoilState(modeState); 23 | 24 | const changeMode = (_: any, value: "light" | "dark" | "system") => { 25 | store.set("mode", value); 26 | setMode(value); 27 | }; 28 | 29 | return ( 30 | 38 | 44 | 45 | light 46 | 47 | 53 | 54 | system 55 | 56 | 62 | 63 | dark 64 | 65 | 66 | ); 67 | } 68 | -------------------------------------------------------------------------------- /src/features/settings/Setting.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import Drawer from "@mui/material/Drawer"; 3 | import Box from "@mui/material/Box"; 4 | import Tooltip from "@mui/material/Tooltip"; 5 | import Typography from "@mui/material/Typography"; 6 | import Divider from "@mui/material/Divider"; 7 | import IconButton from "@mui/material/IconButton"; 8 | import CloseIcon from "@mui/icons-material/Close"; 9 | import SettingsOutlinedIcon from "@mui/icons-material/SettingsOutlined"; 10 | import ModeToggleButton from "./ModeToggleButton"; 11 | import MobToken from "./MobToken"; 12 | import { styled } from "@mui/material/styles"; 13 | 14 | const Heading = styled(Typography)(({ theme }) => ({ 15 | margin: "20px 0 10px", 16 | color: theme.palette.grey[600], 17 | fontWeight: 700, 18 | fontSize: theme.typography.pxToRem(11), 19 | textTransform: "uppercase", 20 | letterSpacing: ".08rem", 21 | })); 22 | 23 | export default function Settings() { 24 | const [open, setOpen] = React.useState(false); 25 | 26 | const onClose = () => setOpen(false); 27 | 28 | const onOpen = () => setOpen(true); 29 | 30 | return ( 31 | <> 32 | 33 | 34 | 35 | 36 | 37 | 49 | 57 | 58 | 设置 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 主题 68 | 69 | 70 | 71 | mob-token 72 | 73 | 74 | 75 | 76 | 77 | ); 78 | } 79 | -------------------------------------------------------------------------------- /src/features/settings/index.ts: -------------------------------------------------------------------------------- 1 | import Settings from "./Setting"; 2 | 3 | export default Settings; 4 | -------------------------------------------------------------------------------- /src/features/theme/BrandingThemeProvider.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import CssBaseline from "@mui/material/CssBaseline"; 3 | import { ThemeProvider } from "@mui/material/styles"; 4 | import { useTheme } from "./useTheme"; 5 | 6 | export default function BrandingProvider({ 7 | children, 8 | }: { 9 | children: React.ReactNode; 10 | }) { 11 | const theme = useTheme(); 12 | 13 | return ( 14 | 15 | 16 | {children} 17 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /src/features/theme/brandingTheme.ts: -------------------------------------------------------------------------------- 1 | import { deepmerge } from '@mui/utils'; 2 | import ArrowDropDownRounded from '@mui/icons-material/ArrowDropDownRounded'; 3 | import { createTheme, ThemeOptions, Theme, alpha } from '@mui/material/styles'; 4 | 5 | declare module '@mui/material/styles/createPalette' { 6 | interface ColorRange { 7 | 50: string; 8 | 100: string; 9 | 200: string; 10 | 300: string; 11 | 400: string; 12 | 500: string; 13 | 600: string; 14 | 700: string; 15 | 800: string; 16 | 900: string; 17 | } 18 | 19 | interface PaletteColor extends ColorRange {} 20 | 21 | interface Palette { 22 | primaryDark: PaletteColor; 23 | } 24 | } 25 | 26 | declare module '@mui/material/styles/createTypography' { 27 | interface TypographyOptions { 28 | fontWeightSemiBold?: number; 29 | fontWeightExtraBold?: number; 30 | fontFamilyCode?: string; 31 | } 32 | 33 | interface Typography { 34 | fontWeightSemiBold: number; 35 | fontWeightExtraBold: number; 36 | fontFamilyCode: string; 37 | } 38 | } 39 | 40 | // TODO: enable this once types conflict is fixed 41 | // declare module '@mui/material/Button' { 42 | // interface ButtonPropsVariantOverrides { 43 | // code: true; 44 | // } 45 | // } 46 | 47 | const defaultTheme = createTheme(); 48 | 49 | const blue = { 50 | 50: '#F0F7FF', 51 | 100: '#C2E0FF', 52 | 200: '#99CCF3', 53 | 300: '#66B2FF', 54 | 400: '#3399FF', 55 | main: '#007FFF', 56 | 500: '#007FFF', 57 | 600: '#0072E5', // vs blueDark 900: WCAG 4.6 AAA (large), APCA 36 Not for reading text 58 | 700: '#0059B2', 59 | 800: '#004C99', 60 | 900: '#003A75', 61 | }; 62 | export const blueDark = { 63 | 50: '#E2EDF8', 64 | 100: '#CEE0F3', 65 | 200: '#91B9E3', 66 | 300: '#5090D3', 67 | main: '#5090D3', 68 | 400: '#265D97', 69 | 500: '#1E4976', 70 | 600: '#173A5E', 71 | 700: '#132F4C', // contrast 13.64:1 72 | 800: '#001E3C', 73 | 900: '#0A1929', 74 | }; 75 | const grey = { 76 | 50: '#F3F6F9', 77 | 100: '#E7EBF0', 78 | 200: '#E0E3E7', 79 | 300: '#CDD2D7', // vs blueDark 900: WCAG 11.6 AAA, APCA 78 Best for text 80 | 400: '#B2BAC2', // vs blueDark 900: WCAG 9 AAA, APCA 63.3 Ok for text 81 | 500: '#A0AAB4', // vs blueDark 900: WCAG 7.5 AAA, APCA 54.3 Only for large text 82 | 600: '#6F7E8C', // vs white bg: WCAG 4.1 AA, APCA 68.7 Ok for text 83 | 700: '#3E5060', // vs white bg: WCAG 8.3 AAA, APCA 88.7 Best for text 84 | 800: '#2D3843', // vs white bg: WCAG 11.9 AAA, APCA 97.3 Best for text 85 | 900: '#1A2027', 86 | }; 87 | // context on the Advanced Perceptual Contrast Algorithm (APCA) used above here: https://github.com/w3c/wcag/issues/695 88 | 89 | const systemFont = [ 90 | '-apple-system', 91 | 'BlinkMacSystemFont', 92 | '"Segoe UI"', 93 | 'Roboto', 94 | '"Helvetica Neue"', 95 | 'Arial', 96 | 'sans-serif', 97 | '"Apple Color Emoji"', 98 | '"Segoe UI Emoji"', 99 | '"Segoe UI Symbol"', 100 | ]; 101 | 102 | export const getMetaThemeColor = (mode: 'light' | 'dark') => { 103 | const themeColor = { 104 | light: grey[50], 105 | dark: blueDark[800], 106 | }; 107 | return themeColor[mode]; 108 | }; 109 | 110 | export const getDesignTokens = (mode: 'light' | 'dark') => 111 | ({ 112 | palette: { 113 | primary: { 114 | ...blue, 115 | ...(mode === 'dark' && { 116 | main: blue[400], 117 | }), 118 | }, 119 | divider: mode === 'dark' ? alpha(blue[100], 0.08) : grey[100], 120 | primaryDark: blueDark, 121 | mode, 122 | ...(mode === 'dark' && { 123 | background: { 124 | default: blueDark[800], 125 | paper: blueDark[900], 126 | }, 127 | }), 128 | common: { 129 | black: '#1D1D1D', 130 | }, 131 | ...(mode === 'light' && { 132 | text: { 133 | primary: grey[900], 134 | secondary: grey[700], 135 | }, 136 | }), 137 | ...(mode === 'dark' && { 138 | text: { 139 | primary: '#fff', 140 | secondary: grey[400], 141 | }, 142 | }), 143 | grey, 144 | error: { 145 | 50: '#FFF0F1', 146 | 100: '#FFDBDE', 147 | 200: '#FFBDC2', 148 | 300: '#FF99A2', 149 | 400: '#FF7A86', 150 | 500: '#FF505F', 151 | main: '#EB0014', // contrast 4.63:1 152 | 600: '#EB0014', 153 | 700: '#C70011', 154 | 800: '#94000D', 155 | 900: '#570007', 156 | }, 157 | success: { 158 | 50: '#E9FBF0', 159 | 100: '#C6F6D9', 160 | 200: '#9AEFBC', 161 | 300: '#6AE79C', 162 | 400: '#3EE07F', 163 | 500: '#21CC66', 164 | 600: '#1DB45A', 165 | ...(mode === 'dark' && { 166 | main: '#1DB45A', // contrast 6.17:1 (blueDark.800) 167 | }), 168 | ...(mode === 'light' && { 169 | main: '#1AA251', // contrast 3.31:1 170 | }), 171 | 700: '#1AA251', 172 | 800: '#178D46', 173 | 900: '#0F5C2E', 174 | }, 175 | warning: { 176 | 50: '#FFF9EB', 177 | 100: '#FFF3C1', 178 | 200: '#FFECA1', 179 | 300: '#FFDC48', // vs blueDark900: WCAG 10.4 AAA, APCA 72 Ok for text 180 | 400: '#F4C000', // vs blueDark900: WCAG 6.4 AA normal, APCA 48 Only large text 181 | 500: '#DEA500', // vs blueDark900: WCAG 8 AAA normal, APCA 58 Only large text 182 | main: '#DEA500', 183 | 600: '#D18E00', // vs blueDark900: WCAG 6.4 AA normal, APCA 48 Only large text 184 | 700: '#AB6800', // vs white bg: WCAG 4.4 AA large, APCA 71 Ok for text 185 | 800: '#8C5800', // vs white bg: WCAG 5.9 AAA large, APCA 80 Best for text 186 | 900: '#5A3600', // vs white bg: WCAG 10.7 AAA, APCA 95 Best for text 187 | }, 188 | }, 189 | shape: { 190 | borderRadius: 10, 191 | }, 192 | spacing: 10, 193 | typography: { 194 | fontFamily: ['"IBM Plex Sans"', ...systemFont].join(','), 195 | fontFamilyCode: [ 196 | 'Consolas', 197 | 'Menlo', 198 | 'Monaco', 199 | 'Andale Mono', 200 | 'Ubuntu Mono', 201 | 'monospace', 202 | ].join(','), 203 | fontFamilyTagline: ['"PlusJakartaSans-ExtraBold"', ...systemFont].join(','), 204 | fontFamilySystem: systemFont.join(','), 205 | fontWeightSemiBold: 600, 206 | fontWeightExtraBold: 800, 207 | h1: { 208 | fontFamily: ['"PlusJakartaSans-ExtraBold"', ...systemFont].join(','), 209 | fontSize: 'clamp(2.625rem, 1.2857rem + 3.5714vw, 4rem)', 210 | fontWeight: 800, 211 | lineHeight: 78 / 70, 212 | ...(mode === 'light' && { 213 | color: blueDark[900], 214 | }), 215 | }, 216 | h2: { 217 | fontFamily: ['"PlusJakartaSans-ExtraBold"', ...systemFont].join(','), 218 | fontSize: 'clamp(1.5rem, 0.9643rem + 1.4286vw, 2.25rem)', 219 | fontWeight: 800, 220 | lineHeight: 44 / 36, 221 | color: mode === 'dark' ? grey[100] : blueDark[700], 222 | }, 223 | h3: { 224 | fontFamily: ['"PlusJakartaSans-Bold"', ...systemFont].join(','), 225 | fontSize: defaultTheme.typography.pxToRem(36), 226 | lineHeight: 44 / 36, 227 | letterSpacing: 0.2, 228 | }, 229 | h4: { 230 | fontFamily: ['"PlusJakartaSans-Bold"', ...systemFont].join(','), 231 | fontSize: defaultTheme.typography.pxToRem(28), 232 | lineHeight: 42 / 28, 233 | letterSpacing: 0.2, 234 | }, 235 | h5: { 236 | fontFamily: ['"PlusJakartaSans-Bold"', ...systemFont].join(','), 237 | fontSize: defaultTheme.typography.pxToRem(24), 238 | lineHeight: 36 / 24, 239 | letterSpacing: 0.1, 240 | color: mode === 'dark' ? blue[300] : blue.main, 241 | }, 242 | h6: { 243 | fontSize: defaultTheme.typography.pxToRem(20), 244 | lineHeight: 30 / 20, 245 | }, 246 | button: { 247 | textTransform: 'initial', 248 | fontWeight: 700, 249 | letterSpacing: 0, 250 | }, 251 | subtitle1: { 252 | fontSize: defaultTheme.typography.pxToRem(18), 253 | lineHeight: 24 / 18, 254 | letterSpacing: 0, 255 | fontWeight: 500, 256 | }, 257 | body1: { 258 | fontSize: defaultTheme.typography.pxToRem(16), // 16px 259 | lineHeight: 24 / 16, 260 | letterSpacing: 0, 261 | }, 262 | body2: { 263 | fontSize: defaultTheme.typography.pxToRem(14), // 14px 264 | lineHeight: 21 / 14, 265 | letterSpacing: 0, 266 | }, 267 | caption: { 268 | display: 'inline-block', 269 | fontSize: defaultTheme.typography.pxToRem(12), // 12px 270 | lineHeight: 18 / 12, 271 | letterSpacing: 0, 272 | fontWeight: 700, 273 | }, 274 | }, 275 | } as ThemeOptions); 276 | 277 | export function getThemedComponents(theme: Theme) { 278 | return { 279 | components: { 280 | MuiButtonBase: { 281 | defaultProps: { 282 | disableTouchRipple: true, 283 | }, 284 | }, 285 | MuiButton: { 286 | defaultProps: { 287 | disableElevation: true, 288 | }, 289 | styleOverrides: { 290 | sizeLarge: { 291 | padding: '0.875rem 1rem', 292 | ...theme.typography.body1, 293 | lineHeight: 21 / 16, 294 | fontWeight: 700, 295 | }, 296 | sizeSmall: { 297 | padding: theme.spacing(0.5, 1), 298 | marginLeft: theme.spacing(-1), 299 | }, 300 | containedPrimary: { 301 | backgroundColor: theme.palette.primary[500], 302 | color: '#fff', 303 | }, 304 | }, 305 | variants: [ 306 | { 307 | props: { variant: 'code' }, 308 | style: { 309 | color: 310 | theme.palette.mode === 'dark' ? theme.palette.grey[400] : theme.palette.grey[800], 311 | border: '1px solid', 312 | borderColor: 313 | theme.palette.mode === 'dark' 314 | ? theme.palette.primaryDark[400] 315 | : theme.palette.grey[300], 316 | backgroundColor: 317 | theme.palette.mode === 'dark' 318 | ? theme.palette.primaryDark[700] 319 | : theme.palette.grey[50], 320 | fontFamily: theme.typography.fontFamilyCode, 321 | fontWeight: 400, 322 | fontSize: defaultTheme.typography.pxToRem(13), // 14px 323 | lineHeight: 21 / 14, 324 | letterSpacing: 0, 325 | WebkitFontSmoothing: 'subpixel-antialiased', 326 | '&:hover, &.Mui-focusVisible': { 327 | borderColor: theme.palette.primary.main, 328 | backgroundColor: 329 | theme.palette.mode === 'dark' 330 | ? theme.palette.primaryDark[600] 331 | : theme.palette.primary[50], 332 | '& .MuiButton-endIcon': { 333 | color: 334 | theme.palette.mode === 'dark' 335 | ? theme.palette.primary[300] 336 | : theme.palette.primary.main, 337 | }, 338 | }, 339 | '& .MuiButton-startIcon': { 340 | color: theme.palette.grey[400], 341 | }, 342 | '& .MuiButton-endIcon': { 343 | display: 'inline-block', 344 | position: 'absolute', 345 | right: 0, 346 | marginRight: 10, 347 | color: 348 | theme.palette.mode === 'dark' ? theme.palette.grey[400] : theme.palette.grey[700], 349 | }, 350 | }, 351 | }, 352 | { 353 | props: { variant: 'link' }, 354 | style: { 355 | fontSize: theme.typography.pxToRem(14), 356 | fontWeight: 700, 357 | color: 358 | theme.palette.mode === 'dark' 359 | ? theme.palette.primary[300] 360 | : theme.palette.primary[600], 361 | mb: 1, 362 | '& svg': { 363 | ml: -0.5, 364 | }, 365 | }, 366 | }, 367 | ], 368 | }, 369 | MuiIconButton: { 370 | variants: [ 371 | { 372 | props: { color: 'primary' }, 373 | style: { 374 | height: 34, 375 | width: 34, 376 | border: `1px solid ${ 377 | theme.palette.mode === 'dark' 378 | ? theme.palette.primaryDark[700] 379 | : theme.palette.grey[200] 380 | }`, 381 | borderRadius: theme.shape.borderRadius, 382 | color: 383 | theme.palette.mode === 'dark' 384 | ? theme.palette.primary[300] 385 | : theme.palette.primary[500], 386 | '&:hover': { 387 | borderColor: 388 | theme.palette.mode === 'dark' 389 | ? theme.palette.primaryDark[600] 390 | : theme.palette.grey[300], 391 | background: 392 | theme.palette.mode === 'dark' 393 | ? alpha(theme.palette.primaryDark[700], 0.4) 394 | : theme.palette.grey[50], 395 | }, 396 | }, 397 | }, 398 | ], 399 | }, 400 | MuiMenu: { 401 | styleOverrides: { 402 | paper: { 403 | mt: 0.5, 404 | minWidth: 160, 405 | elevation: 0, 406 | color: theme.palette.text.secondary, 407 | backgroundImage: 'none', 408 | bgColor: 409 | theme.palette.mode === 'dark' 410 | ? theme.palette.primaryDark[900] 411 | : theme.palette.background.paper, 412 | border: `1px solid ${ 413 | theme.palette.mode === 'dark' 414 | ? theme.palette.primaryDark[700] 415 | : theme.palette.grey[200] 416 | }`, 417 | '& .MuiMenuItem-root': { 418 | fontSize: theme.typography.pxToRem(14), 419 | fontWeight: 500, 420 | '&:hover': { 421 | backgroundColor: 422 | theme.palette.mode === 'dark' 423 | ? alpha(theme.palette.primaryDark[700], 0.4) 424 | : theme.palette.grey[50], 425 | }, 426 | '&:focus': { 427 | backgroundColor: 428 | theme.palette.mode === 'dark' 429 | ? alpha(theme.palette.primaryDark[700], 0.4) 430 | : theme.palette.grey[50], 431 | }, 432 | '&.Mui-selected': { 433 | fontWeight: 500, 434 | color: 435 | theme.palette.mode === 'dark' 436 | ? theme.palette.primary[300] 437 | : theme.palette.primary[600], 438 | backgroundColor: 439 | theme.palette.mode === 'dark' 440 | ? theme.palette.primaryDark[700] 441 | : alpha(theme.palette.primary[100], 0.6), 442 | }, 443 | }, 444 | }, 445 | }, 446 | }, 447 | MuiPopover: { 448 | styleOverrides: { 449 | paper: { 450 | boxShadow: `0px 4px 20px ${ 451 | theme.palette.mode === 'dark' ? 'rgba(0, 0, 0, 0.5)' : 'rgba(170, 180, 190, 0.3)' 452 | }`, 453 | }, 454 | }, 455 | }, 456 | MuiContainer: { 457 | styleOverrides: { 458 | root: { 459 | [theme.breakpoints.up('md')]: { 460 | paddingLeft: theme.spacing(2), 461 | paddingRight: theme.spacing(2), 462 | }, 463 | }, 464 | }, 465 | }, 466 | MuiDivider: { 467 | styleOverrides: { 468 | root: { 469 | borderColor: 470 | theme.palette.mode === 'dark' 471 | ? alpha(theme.palette.primary[100], 0.08) 472 | : theme.palette.grey[100], 473 | }, 474 | }, 475 | }, 476 | MuiLink: { 477 | defaultProps: { 478 | underline: 'none', 479 | }, 480 | styleOverrides: { 481 | root: { 482 | color: 483 | theme.palette.mode === 'dark' 484 | ? theme.palette.primary[300] 485 | : theme.palette.primary[600], 486 | fontWeight: 700, 487 | display: 'inline-flex', 488 | alignItems: 'center', 489 | '&:hover': { 490 | color: 491 | theme.palette.mode === 'dark' 492 | ? theme.palette.primary[200] 493 | : theme.palette.primary[700], 494 | }, 495 | '&.MuiTypography-body1 > svg': { 496 | marginTop: 2, 497 | }, 498 | '& svg:last-child': { 499 | marginLeft: 2, 500 | }, 501 | }, 502 | }, 503 | }, 504 | MuiChip: { 505 | styleOverrides: { 506 | root: { 507 | fontWeight: 500, 508 | }, 509 | outlined: { 510 | color: theme.palette.mode === 'dark' ? '#fff' : theme.palette.grey[900], 511 | backgroundColor: 'transparent', 512 | borderColor: 513 | theme.palette.mode === 'dark' 514 | ? theme.palette.primaryDark[600] 515 | : theme.palette.grey[300], 516 | }, 517 | filled: { 518 | border: '1px solid transparent', 519 | color: theme.palette.mode === 'dark' ? '#fff' : theme.palette.primary[800], 520 | backgroundColor: 521 | theme.palette.mode === 'dark' 522 | ? theme.palette.primaryDark[500] 523 | : theme.palette.primary[100], 524 | '&:hover': { 525 | backgroundColor: 526 | theme.palette.mode === 'dark' 527 | ? theme.palette.primaryDark[600] 528 | : theme.palette.primary[200], 529 | }, 530 | }, 531 | deleteIcon: { 532 | color: theme.palette.mode === 'dark' ? '#fff' : theme.palette.primary[700], 533 | '&:hover': { 534 | color: 535 | theme.palette.mode === 'dark' 536 | ? theme.palette.grey[100] 537 | : theme.palette.primary[900], 538 | }, 539 | }, 540 | }, 541 | }, 542 | MuiList: { 543 | styleOverrides: { 544 | root: { 545 | padding: 0, 546 | }, 547 | }, 548 | }, 549 | MuiListItemButton: { 550 | styleOverrides: { 551 | root: { 552 | padding: '8px', 553 | textTransform: 'none', 554 | fontWeight: 500, 555 | fontSize: theme.typography.pxToRem(14), 556 | color: 557 | theme.palette.mode === 'dark' ? theme.palette.grey[300] : theme.palette.grey[700], 558 | borderRadius: 0, 559 | '&:hover': { 560 | backgroundColor: 561 | theme.palette.mode === 'dark' 562 | ? alpha(theme.palette.primaryDark[700], 0.4) 563 | : theme.palette.grey[50], 564 | }, 565 | '&.Mui-selected': { 566 | color: theme.palette.mode === 'dark' ? '#fff' : theme.palette.primary[500], 567 | borderRadius: 10, 568 | border: '1px solid', 569 | borderColor: 570 | theme.palette.mode === 'dark' 571 | ? `${theme.palette.primary[700]} !important` 572 | : `${theme.palette.primary[500]} !important`, 573 | backgroundColor: 574 | theme.palette.mode === 'dark' 575 | ? theme.palette.primaryDark[700] 576 | : theme.palette.primary[50], 577 | '&:hover': { 578 | backgroundColor: 579 | theme.palette.mode === 'dark' 580 | ? theme.palette.primaryDark[600] 581 | : theme.palette.primary[100], 582 | }, 583 | }, 584 | }, 585 | }, 586 | }, 587 | MuiSelect: { 588 | defaultProps: { 589 | IconComponent: ArrowDropDownRounded, 590 | }, 591 | styleOverrides: { 592 | iconFilled: { 593 | top: 'calc(50% - .25em)', 594 | }, 595 | }, 596 | }, 597 | MuiTab: { 598 | defaultProps: { 599 | disableTouchRipple: true, 600 | }, 601 | }, 602 | MuiPaper: { 603 | styleOverrides: { 604 | root: { 605 | backgroundImage: 'none', 606 | backgroundColor: 607 | theme.palette.mode === 'dark' ? theme.palette.primaryDark[900] : '#fff', 608 | '&[href]': { 609 | textDecorationLine: 'none', 610 | }, 611 | }, 612 | outlined: { 613 | display: 'block', 614 | borderColor: 615 | theme.palette.mode === 'dark' 616 | ? theme.palette.primaryDark[500] 617 | : theme.palette.grey[200], 618 | ...(theme.palette.mode === 'dark' && { 619 | backgroundColor: theme.palette.primaryDark[700], 620 | }), 621 | 'a&, button&': { 622 | '&:hover': { 623 | boxShadow: `0px 4px 20px ${ 624 | theme.palette.mode === 'dark' ? 'rgba(0, 0, 0, 0.5)' : 'rgba(170, 180, 190, 0.3)' 625 | }`, 626 | }, 627 | }, 628 | }, 629 | }, 630 | }, 631 | MuiTableCell: { 632 | styleOverrides: { 633 | root: { 634 | padding: theme.spacing(1, 2), 635 | borderColor: theme.palette.divider, 636 | }, 637 | head: { 638 | color: theme.palette.text.primary, 639 | fontWeight: 700, 640 | }, 641 | body: { 642 | color: theme.palette.text.secondary, 643 | }, 644 | }, 645 | }, 646 | MuiToggleButtonGroup: { 647 | styleOverrides: { 648 | root: { 649 | backgroundColor: 650 | theme.palette.mode === 'dark' ? theme.palette.primaryDark[900] : '#fff', 651 | }, 652 | }, 653 | }, 654 | MuiToggleButton: { 655 | styleOverrides: { 656 | root: { 657 | textTransform: 'none', 658 | fontWeight: 500, 659 | color: 660 | theme.palette.mode === 'dark' ? theme.palette.grey[300] : theme.palette.grey[700], 661 | borderColor: 662 | theme.palette.mode === 'dark' 663 | ? theme.palette.primaryDark[500] 664 | : theme.palette.grey[200], 665 | '&.Mui-selected': { 666 | color: theme.palette.mode === 'dark' ? '#fff' : theme.palette.primary[500], 667 | borderColor: 668 | theme.palette.mode === 'dark' 669 | ? `${theme.palette.primary[700]} !important` 670 | : `${theme.palette.primary[500]} !important`, 671 | backgroundColor: 672 | theme.palette.mode === 'dark' 673 | ? theme.palette.primaryDark[700] 674 | : theme.palette.primary[50], 675 | '&:hover': { 676 | backgroundColor: 677 | theme.palette.mode === 'dark' 678 | ? theme.palette.primaryDark[600] 679 | : theme.palette.primary[100], 680 | }, 681 | }, 682 | }, 683 | }, 684 | }, 685 | MuiTooltip: { 686 | styleOverrides: { 687 | tooltip: { 688 | padding: '5px 9px', 689 | }, 690 | }, 691 | }, 692 | MuiSwitch: { 693 | styleOverrides: { 694 | root: { 695 | width: 32, 696 | height: 20, 697 | padding: 0, 698 | '& .MuiSwitch-switchBase': { 699 | '&.Mui-checked': { 700 | transform: 'translateX(11px)', 701 | color: '#fff', 702 | }, 703 | }, 704 | }, 705 | switchBase: { 706 | height: 20, 707 | width: 20, 708 | padding: 0, 709 | color: '#fff', 710 | '&.Mui-checked + .MuiSwitch-track': { 711 | opacity: 1, 712 | }, 713 | }, 714 | track: { 715 | opacity: 1, 716 | borderRadius: 32, 717 | backgroundColor: 718 | theme.palette.mode === 'dark' ? theme.palette.grey[800] : theme.palette.grey[400], 719 | }, 720 | thumb: { 721 | flexShrink: 0, 722 | width: '14px', 723 | height: '14px', 724 | }, 725 | }, 726 | }, 727 | MuiPaginationItem: { 728 | styleOverrides: { 729 | root: { 730 | textTransform: 'none', 731 | fontWeight: 700, 732 | color: 733 | theme.palette.mode === 'dark' ? theme.palette.grey[300] : theme.palette.grey[700], 734 | borderColor: 735 | theme.palette.mode === 'dark' 736 | ? theme.palette.primaryDark[500] 737 | : theme.palette.grey[200], 738 | '&.Mui-selected': { 739 | color: theme.palette.mode === 'dark' ? '#fff' : theme.palette.primary[500], 740 | borderColor: 741 | theme.palette.mode === 'dark' 742 | ? `${theme.palette.primary[700]} !important` 743 | : `${theme.palette.primary[500]} !important`, 744 | backgroundColor: 745 | theme.palette.mode === 'dark' 746 | ? theme.palette.primaryDark[700] 747 | : theme.palette.primary[50], 748 | '&:hover': { 749 | backgroundColor: 750 | theme.palette.mode === 'dark' 751 | ? theme.palette.primaryDark[600] 752 | : theme.palette.primary[100], 753 | }, 754 | }, 755 | }, 756 | }, 757 | }, 758 | MuiCssBaseline: { 759 | defaultProps: { 760 | enableColorScheme: true, 761 | }, 762 | }, 763 | }, 764 | }; 765 | } 766 | 767 | const darkTheme = createTheme(getDesignTokens('dark')); 768 | export const brandingDarkTheme = deepmerge(darkTheme, getThemedComponents(darkTheme)); 769 | -------------------------------------------------------------------------------- /src/features/theme/index.tsx: -------------------------------------------------------------------------------- 1 | import BrandingProvider from "./BrandingThemeProvider"; 2 | import modeState from "./modeState"; 3 | 4 | export { BrandingProvider, modeState }; 5 | -------------------------------------------------------------------------------- /src/features/theme/modeState.ts: -------------------------------------------------------------------------------- 1 | import { atom } from "recoil"; 2 | 3 | const modeState = atom<"light" | "dark" | "system">({ 4 | key: "modeState", 5 | default: "system", 6 | }); 7 | 8 | export default modeState; 9 | -------------------------------------------------------------------------------- /src/features/theme/useTheme.ts: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { useRecoilState } from "recoil"; 3 | import { createTheme } from "@mui/material/styles"; 4 | import { deepmerge } from "@mui/utils"; 5 | import modeState from "./modeState"; 6 | import { getDesignTokens, getThemedComponents } from "./brandingTheme"; 7 | import store from "@/lib/store"; 8 | 9 | export function useTheme() { 10 | const [themeMode, setThemeMode] = React.useState<"light" | "dark">("light"); 11 | const [mode, setMode] = useRecoilState(modeState); 12 | 13 | React.useEffect(() => { 14 | if (mode === "system") { 15 | const mediaQueryList = window.matchMedia("(prefers-color-scheme: dark)"); 16 | setThemeMode(mediaQueryList.matches ? "dark" : "light"); 17 | } else { 18 | setThemeMode(mode); 19 | } 20 | }, [mode]); 21 | 22 | React.useEffect(() => { 23 | const mediaQueryList = window.matchMedia("(prefers-color-scheme: dark)"); 24 | const listener = (ev: MediaQueryListEvent) => { 25 | if (mode === "system") { 26 | setThemeMode(ev.matches ? "dark" : "light"); 27 | } 28 | }; 29 | mediaQueryList.addEventListener("change", listener); 30 | return () => { 31 | mediaQueryList.removeEventListener("change", listener); 32 | }; 33 | }, [mode]); 34 | 35 | React.useEffect(() => { 36 | store.get("mode").then((storedMode) => { 37 | const preferMode = (storedMode ?? "system") as 38 | | "light" 39 | | "dark" 40 | | "system"; 41 | setMode(preferMode); 42 | }); 43 | }, [setMode]); 44 | 45 | const theme = React.useMemo(() => { 46 | const designTokens = getDesignTokens(themeMode); 47 | let newTheme = createTheme(designTokens); 48 | newTheme = deepmerge(newTheme, getThemedComponents(newTheme)); 49 | return newTheme; 50 | }, [themeMode]); 51 | 52 | return theme; 53 | } 54 | -------------------------------------------------------------------------------- /src/lib/request.ts: -------------------------------------------------------------------------------- 1 | import ky from "ky"; 2 | import { getClient } from "@tauri-apps/api/http"; 3 | import mapValues from "lodash/mapValues"; 4 | import store from "./store"; 5 | import type { HttpOptions } from "@tauri-apps/api/http"; 6 | 7 | interface RequestOptions extends HttpOptions { 8 | timeout?: number; 9 | } 10 | 11 | async function requestWeb(options: RequestOptions) { 12 | const mobToken = await store.get("mob-token"); 13 | 14 | const response = await ky(options.url, { 15 | prefixUrl: "/api", 16 | method: options.method, 17 | headers: { 18 | ...options.headers, 19 | "edu-app-type": "android", 20 | }, 21 | searchParams: { 22 | ...options.query, 23 | "mob-token": mobToken ?? "", 24 | }, 25 | json: options.body, 26 | timeout: options.timeout, 27 | }); 28 | 29 | const data = await response.json(); 30 | 31 | return data; 32 | } 33 | 34 | async function requestTauri(options: RequestOptions) { 35 | const { url, query, ...other } = options; 36 | 37 | const mobToken = await store.get("mob-token"); 38 | 39 | const handledQuery = mapValues( 40 | { 41 | ...query, 42 | "mob-token": mobToken ?? "", 43 | }, 44 | (value) => String(value) 45 | ); 46 | 47 | const client = await getClient(); 48 | const response = await client.request({ 49 | url: `https://www.icourse163.org/${url}`, 50 | headers: { 51 | "edu-app-type": "android", 52 | }, 53 | query: handledQuery, 54 | ...other, 55 | }); 56 | 57 | return response.data; 58 | } 59 | 60 | const request = process.env.NEXT_PUBLIC_TAURI ? requestTauri : requestWeb; 61 | 62 | export default request; 63 | -------------------------------------------------------------------------------- /src/lib/store.ts: -------------------------------------------------------------------------------- 1 | import { invoke } from "@tauri-apps/api/tauri"; 2 | import { TAURI_STORE_PATH } from "@/constants"; 3 | 4 | export interface Store { 5 | get: (key: string) => Promise; 6 | set: (key: string, value: string) => Promise; 7 | } 8 | 9 | const storeTauri: Store = { 10 | get: (key) => { 11 | return invoke("plugin:store|get", { 12 | path: TAURI_STORE_PATH, 13 | key, 14 | }); 15 | }, 16 | set: (key, value) => { 17 | return invoke("plugin:store|set", { 18 | path: TAURI_STORE_PATH, 19 | key, 20 | value, 21 | }); 22 | }, 23 | }; 24 | 25 | const storeWeb: Store = { 26 | get: (key) => { 27 | return Promise.resolve(localStorage.getItem(key)); 28 | }, 29 | set: (key, value) => { 30 | return Promise.resolve(localStorage.setItem(key, value)); 31 | }, 32 | }; 33 | 34 | const store = process.env.NEXT_PUBLIC_TAURI ? storeTauri : storeWeb; 35 | 36 | export default store; 37 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import { open } from "@tauri-apps/api/shell"; 2 | 3 | const openExternalWeb = (url: string) => window.open(url, "_blank"); 4 | 5 | const openExternalTauri = (url: string) => open(url); 6 | 7 | export const openExternal = process.env.NEXT_PUBLIC_TAURI 8 | ? openExternalTauri 9 | : openExternalWeb; 10 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "@/*": ["src/*"] 20 | } 21 | }, 22 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 23 | "exclude": ["node_modules"] 24 | } 25 | --------------------------------------------------------------------------------