diff --git a/slader-legacy-frontend/.gitignore b/slader-legacy-frontend/.gitignore
new file mode 100644
index 0000000..403adbc
--- /dev/null
+++ b/slader-legacy-frontend/.gitignore
@@ -0,0 +1,23 @@
+.DS_Store
+node_modules
+/dist
+
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/slader-legacy-frontend/.npmrc b/slader-legacy-frontend/.npmrc
new file mode 100644
index 0000000..bf2e764
--- /dev/null
+++ b/slader-legacy-frontend/.npmrc
@@ -0,0 +1 @@
+shamefully-hoist=true
diff --git a/slader-legacy-frontend/README.md b/slader-legacy-frontend/README.md
new file mode 100644
index 0000000..184422d
--- /dev/null
+++ b/slader-legacy-frontend/README.md
@@ -0,0 +1,24 @@
+# slader-legacy-frontend
+
+## Project setup
+```
+pnpm install
+```
+
+### Compiles and hot-reloads for development
+```
+pnpm run serve
+```
+
+### Compiles and minifies for production
+```
+pnpm run build
+```
+
+### Lints and fixes files
+```
+pnpm run lint
+```
+
+### Customize configuration
+See [Configuration Reference](https://cli.vuejs.org/config/).
diff --git a/slader-legacy-frontend/babel.config.js b/slader-legacy-frontend/babel.config.js
new file mode 100644
index 0000000..e955840
--- /dev/null
+++ b/slader-legacy-frontend/babel.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ presets: [
+ '@vue/cli-plugin-babel/preset'
+ ]
+}
diff --git a/slader-legacy-frontend/config.js b/slader-legacy-frontend/config.js
new file mode 100644
index 0000000..65c1472
--- /dev/null
+++ b/slader-legacy-frontend/config.js
@@ -0,0 +1,6 @@
+require('dotenv').config()
+let appConfig={
+ baseUrl:process.env.VUE_APP_BASE_URL
+}
+console.log(appConfig)
+export {appConfig}
diff --git a/slader-legacy-frontend/package.json b/slader-legacy-frontend/package.json
new file mode 100644
index 0000000..75274f0
--- /dev/null
+++ b/slader-legacy-frontend/package.json
@@ -0,0 +1,54 @@
+{
+ "name": "slader-legacy-frontend",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "serve": "vue-cli-service serve",
+ "build": "vue-cli-service build",
+ "lint": "vue-cli-service lint"
+ },
+ "dependencies": {
+ "axios": "^0.21.1",
+ "core-js": "^3.6.5",
+ "sweetalert2": "^11.1.0",
+ "vue": "^2.6.11",
+ "vue-router": "^3.2.0",
+ "vuetify": "^2.4.0"
+ },
+ "devDependencies": {
+ "@vue/cli-plugin-babel": "~4.5.0",
+ "@vue/cli-plugin-eslint": "~4.5.0",
+ "@vue/cli-plugin-router": "~4.5.0",
+ "@vue/cli-service": "~4.5.0",
+ "babel-eslint": "^10.1.0",
+ "eslint": "^6.7.2",
+ "eslint-plugin-vue": "^6.2.2",
+ "sass": "~1.32.0",
+ "sass-loader": "^10.0.0",
+ "vue-cli-plugin-vuetify": "^2.4.1",
+ "vue-template-compiler": "^2.6.11",
+ "vuetify-loader": "^1.7.0"
+ },
+ "eslintConfig": {
+ "root": true,
+ "env": {
+ "node": true
+ },
+ "extends": [
+ "plugin:vue/essential",
+ "eslint:recommended"
+ ],
+ "parserOptions": {
+ "parser": "babel-eslint"
+ },
+ "rules": {
+ "no-unused-vars": "off",
+ "vue/no-unused-components": "off"
+ }
+ },
+ "browserslist": [
+ "> 1%",
+ "last 2 versions",
+ "not dead"
+ ]
+}
diff --git a/slader-legacy-frontend/public/favicon.ico b/slader-legacy-frontend/public/favicon.ico
new file mode 100644
index 0000000..df36fcf
Binary files /dev/null and b/slader-legacy-frontend/public/favicon.ico differ
diff --git a/slader-legacy-frontend/public/index.html b/slader-legacy-frontend/public/index.html
new file mode 100644
index 0000000..642a583
--- /dev/null
+++ b/slader-legacy-frontend/public/index.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+ <%= htmlWebpackPlugin.options.title %>
+
+
+
+
+
+
+
+
+
diff --git a/slader-legacy-frontend/public/test.html b/slader-legacy-frontend/public/test.html
new file mode 100644
index 0000000..b72f286
--- /dev/null
+++ b/slader-legacy-frontend/public/test.html
@@ -0,0 +1,922 @@
+
+
+
+
+
+
+
+ 5.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
RESULT
+
+
+
+
+

+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
Your solution is not live yet. Click to edit.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1.4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ the expression of every letter is given in the prompt
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ the symbol shown in this step if for inclusive distinction as explained in pp 4 and 5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ the arrow denotes an implication as shown in pp 6
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
RESULT
+
+
+
+
+
+
+ the final result is shown in line 3
+
+
+
+
+
+
+
+
+
+
+
Your solution is not live yet. Click to edit.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/slader-legacy-frontend/src/App.vue b/slader-legacy-frontend/src/App.vue
new file mode 100644
index 0000000..b2a841f
--- /dev/null
+++ b/slader-legacy-frontend/src/App.vue
@@ -0,0 +1,61 @@
+
+
+
+
+
+ slader-legacy
+
+
+ mdi-brightness-6
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ slader-legacy {{new Date().getFullYear()}}
+
+
+
+
+
+
+
+
diff --git a/slader-legacy-frontend/src/assets/logo.png b/slader-legacy-frontend/src/assets/logo.png
new file mode 100644
index 0000000..f3d2503
Binary files /dev/null and b/slader-legacy-frontend/src/assets/logo.png differ
diff --git a/slader-legacy-frontend/src/assets/logo.svg b/slader-legacy-frontend/src/assets/logo.svg
new file mode 100644
index 0000000..145b6d1
--- /dev/null
+++ b/slader-legacy-frontend/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/slader-legacy-frontend/src/components/HelloWorld.vue b/slader-legacy-frontend/src/components/HelloWorld.vue
new file mode 100644
index 0000000..50a447d
--- /dev/null
+++ b/slader-legacy-frontend/src/components/HelloWorld.vue
@@ -0,0 +1,151 @@
+
+
+
+
+
+
+
+
+
+ Welcome to Vuetify
+
+
+
+ For help and collaboration with other Vuetify developers,
+
please join our online
+ Discord Community
+
+
+
+
+
+ What's next?
+
+
+
+
+ {{ next.text }}
+
+
+
+
+
+
+ Important Links
+
+
+
+
+ {{ link.text }}
+
+
+
+
+
+
+ Ecosystem
+
+
+
+
+ {{ eco.text }}
+
+
+
+
+
+
+
+
diff --git a/slader-legacy-frontend/src/components/StandardTable.vue b/slader-legacy-frontend/src/components/StandardTable.vue
new file mode 100644
index 0000000..8b26aa3
--- /dev/null
+++ b/slader-legacy-frontend/src/components/StandardTable.vue
@@ -0,0 +1,35 @@
+
+
+
+
+ mdi-arrow-left-circle
+
+
+ {{ tableTitle }}
+
+
+
+
+ mdi-magnify
+
+
+
+
+
+
+
+
+
diff --git a/slader-legacy-frontend/src/components/TextbookBlock.vue b/slader-legacy-frontend/src/components/TextbookBlock.vue
new file mode 100644
index 0000000..8607fbf
--- /dev/null
+++ b/slader-legacy-frontend/src/components/TextbookBlock.vue
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+ {{ textbookTitleRefined }}
+
+
+
+ 详情
+
+
+
+
+ mdi-close
+
+
+ 书名:{{ title }}
+ 题数:{{ quantity }}
+
+
+
+
+
+
+
+
+
+
diff --git a/slader-legacy-frontend/src/includes.js b/slader-legacy-frontend/src/includes.js
new file mode 100644
index 0000000..7a92e2a
--- /dev/null
+++ b/slader-legacy-frontend/src/includes.js
@@ -0,0 +1,22 @@
+import axios from 'axios'
+import {appConfig} from "../config"
+import Swal from "sweetalert2"
+
+let myAxios=axios.create({
+ baseURL:appConfig.baseUrl
+})
+export function textbookTitleRefine(str){
+ return firstUpperCase(str.split('-').slice(1).join(' '))
+}
+export function firstUpperCase(str) {
+ return str.toLowerCase().replace(/( |^)[a-z]/g, (L) => L.toUpperCase())
+}
+export function showServerErrorAlert(){
+ Swal.fire({
+ title: '错误',
+ icon: 'error',
+ text: '拉取伺服器资料时出错'
+ })
+}
+
+export {myAxios}
diff --git a/slader-legacy-frontend/src/main.js b/slader-legacy-frontend/src/main.js
new file mode 100644
index 0000000..917702d
--- /dev/null
+++ b/slader-legacy-frontend/src/main.js
@@ -0,0 +1,12 @@
+import Vue from 'vue'
+import App from './App.vue'
+import router from './router'
+import vuetify from './plugins/vuetify'
+
+Vue.config.productionTip = false
+
+new Vue({
+ router,
+ vuetify,
+ render: h => h(App)
+}).$mount('#app')
diff --git a/slader-legacy-frontend/src/plugins/vuetify.js b/slader-legacy-frontend/src/plugins/vuetify.js
new file mode 100644
index 0000000..c0d1611
--- /dev/null
+++ b/slader-legacy-frontend/src/plugins/vuetify.js
@@ -0,0 +1,8 @@
+import Vue from 'vue';
+import Vuetify from 'vuetify/lib/framework';
+
+Vue.use(Vuetify);
+
+export default new Vuetify({
+
+});
diff --git a/slader-legacy-frontend/src/router/index.js b/slader-legacy-frontend/src/router/index.js
new file mode 100644
index 0000000..ba0d76a
--- /dev/null
+++ b/slader-legacy-frontend/src/router/index.js
@@ -0,0 +1,41 @@
+import Vue from 'vue'
+import VueRouter from 'vue-router'
+import Home from '../views/Home.vue'
+import Textbook from "@/views/Textbook"
+import Section from "@/views/Section"
+import Exercise from "@/views/Exercise"
+
+Vue.use(VueRouter)
+
+const routes = [
+ {
+ path: '/',
+ name: 'home',
+ component: Home
+ },
+ {
+ path: '/textbook/:textbook?',
+ name: 'textbook',
+ component: Textbook,
+ props: true
+ },
+ {
+ path: '/textbook/:textbook/section/:section',
+ name: 'section',
+ component: Section,
+ props: true
+ },
+ {
+ path: '/textbook/:textbook/section/:section/exercise/:exercise',
+ name: 'exercise',
+ component: Exercise,
+ props: true
+ }
+]
+
+const router = new VueRouter({
+ mode: "history",
+ routes: [...routes],
+})
+
+export default router
diff --git a/slader-legacy-frontend/src/views/About.vue b/slader-legacy-frontend/src/views/About.vue
new file mode 100644
index 0000000..3fa2807
--- /dev/null
+++ b/slader-legacy-frontend/src/views/About.vue
@@ -0,0 +1,5 @@
+
+
+
This is an about page
+
+
diff --git a/slader-legacy-frontend/src/views/Exercise.vue b/slader-legacy-frontend/src/views/Exercise.vue
new file mode 100644
index 0000000..d6ebcc5
--- /dev/null
+++ b/slader-legacy-frontend/src/views/Exercise.vue
@@ -0,0 +1,126 @@
+
+
+
+
+ mdi-arrow-left-circle
+
+ 题 {{ exercise }}
+
+
+
+
+
+
+
+
diff --git a/slader-legacy-frontend/src/views/Home.vue b/slader-legacy-frontend/src/views/Home.vue
new file mode 100644
index 0000000..38e5b46
--- /dev/null
+++ b/slader-legacy-frontend/src/views/Home.vue
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
diff --git a/slader-legacy-frontend/src/views/Section.vue b/slader-legacy-frontend/src/views/Section.vue
new file mode 100644
index 0000000..3ee615e
--- /dev/null
+++ b/slader-legacy-frontend/src/views/Section.vue
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
diff --git a/slader-legacy-frontend/src/views/Textbook.vue b/slader-legacy-frontend/src/views/Textbook.vue
new file mode 100644
index 0000000..b4a4706
--- /dev/null
+++ b/slader-legacy-frontend/src/views/Textbook.vue
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
diff --git a/slader-legacy-frontend/vue.config.js b/slader-legacy-frontend/vue.config.js
new file mode 100644
index 0000000..2ae460b
--- /dev/null
+++ b/slader-legacy-frontend/vue.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ transpileDependencies: [
+ 'vuetify'
+ ]
+}