Compare commits
	
		
			6 Commits
		
	
	
		
			0d630f4ee7
			...
			3ae33607cc
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 3ae33607cc | |||
| 8b0fcca7bc | |||
| b839c99028 | |||
| c2e4a97373 | |||
| 449ac13557 | |||
| 7880218a0b | 
							
								
								
									
										7
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
.idea/*
 | 
			
		||||
slader-legacy-backend/node_modules/*
 | 
			
		||||
slader-legacy-backend/.env
 | 
			
		||||
/slader-legacy-backend/pnpm-lock.yaml
 | 
			
		||||
/slader-legacy-backend/slader.db
 | 
			
		||||
/slader-legacy-frontend/.env
 | 
			
		||||
/slader-legacy-frontend/pnpm-lock.yaml
 | 
			
		||||
							
								
								
									
										27
									
								
								slader-legacy-backend/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								slader-legacy-backend/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "slader-legacy-backend",
 | 
			
		||||
  "version": "1.0.0",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "main": "src/index.js",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "test": "echo \"Error: no test specified\" && exit 1"
 | 
			
		||||
  },
 | 
			
		||||
  "author": "",
 | 
			
		||||
  "license": "ISC",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@types/better-sqlite3": "^5.4.3",
 | 
			
		||||
    "@types/cors": "^2.8.12",
 | 
			
		||||
    "@types/express": "^4.17.13",
 | 
			
		||||
    "@types/node": "^16.4.8",
 | 
			
		||||
    "better-sqlite3": "^7.4.3",
 | 
			
		||||
    "cors": "^2.8.5",
 | 
			
		||||
    "dotenv": "^10.0.0",
 | 
			
		||||
    "express": "^4.17.1",
 | 
			
		||||
    "express-async-handler": "^1.1.4",
 | 
			
		||||
    "express-validator": "^6.12.1",
 | 
			
		||||
    "reflect-metadata": "^0.1.13",
 | 
			
		||||
    "ts-node": "^10.1.0",
 | 
			
		||||
    "typedi": "^0.10.0",
 | 
			
		||||
    "typescript": "^4.3.5"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								slader-legacy-backend/src/config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								slader-legacy-backend/src/config.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
require('dotenv').config()
 | 
			
		||||
let appConfig = {
 | 
			
		||||
    port: parseInt(process.env.SL_PORT as any)
 | 
			
		||||
}
 | 
			
		||||
export {appConfig}
 | 
			
		||||
							
								
								
									
										27
									
								
								slader-legacy-backend/src/entity-fill.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								slader-legacy-backend/src/entity-fill.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
import {IExercise, ITextbook, IToc} from "./types"
 | 
			
		||||
 | 
			
		||||
export function fillIToc(single: any) {
 | 
			
		||||
    return <IToc>{
 | 
			
		||||
        section: single.section,
 | 
			
		||||
        count: single.count,
 | 
			
		||||
        pageBegin: single.pageBegin,
 | 
			
		||||
        pageEnd: single.pageEnd
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function fillITextbook(single: any) {
 | 
			
		||||
    return <ITextbook>{
 | 
			
		||||
        title: single.title,
 | 
			
		||||
        quantity: single.quantity
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function fillIExercise(single: any) {
 | 
			
		||||
    return <IExercise>{
 | 
			
		||||
        exercise: single.exercise,
 | 
			
		||||
        section: single.section,
 | 
			
		||||
        part: single.part,
 | 
			
		||||
        page: single.page,
 | 
			
		||||
        html: single.html
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										36
									
								
								slader-legacy-backend/src/includes.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								slader-legacy-backend/src/includes.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
import {validationResult} from "express-validator"
 | 
			
		||||
import {IResultJson} from "./types"
 | 
			
		||||
import express from "express"
 | 
			
		||||
import Database from "better-sqlite3"
 | 
			
		||||
import path from "path"
 | 
			
		||||
 | 
			
		||||
let db = Database(path.join(__dirname, '../slader.db'), {verbose: message => console.log('SQLITE3: ' + message)})
 | 
			
		||||
 | 
			
		||||
export {db}
 | 
			
		||||
export const resultJson = {
 | 
			
		||||
    success(data: any) {
 | 
			
		||||
        return <IResultJson>{
 | 
			
		||||
            status: true,
 | 
			
		||||
            data: data
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    error(data: any) {
 | 
			
		||||
        return <IResultJson>{
 | 
			
		||||
            status: false,
 | 
			
		||||
            data: data
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function hasValidationErrors(req: express.Request, res: express.Response) {
 | 
			
		||||
    let errors = validationResult(req)
 | 
			
		||||
    if (!errors.isEmpty()) {
 | 
			
		||||
        res.json(resultJson.error(errors.array()))
 | 
			
		||||
        return true
 | 
			
		||||
    }
 | 
			
		||||
    return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getTimestampInSeconds() {
 | 
			
		||||
    return Math.floor(Date.now() / 1000)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								slader-legacy-backend/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								slader-legacy-backend/src/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
import express from 'express'
 | 
			
		||||
import cors from 'cors'
 | 
			
		||||
import {textbookRouter} from "./routers/textbook-router"
 | 
			
		||||
import {appConfig} from "./config"
 | 
			
		||||
 | 
			
		||||
let app = express()
 | 
			
		||||
app.use(cors())
 | 
			
		||||
 | 
			
		||||
app.use('/textbook', textbookRouter)
 | 
			
		||||
 | 
			
		||||
app.listen(appConfig.port, () => {
 | 
			
		||||
    console.log('Server has started at port ' + appConfig.port)
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										65
									
								
								slader-legacy-backend/src/models/textbook-model.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								slader-legacy-backend/src/models/textbook-model.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
import 'reflect-metadata'
 | 
			
		||||
import {Service} from "typedi"
 | 
			
		||||
import {db} from "../includes"
 | 
			
		||||
import {fillIExercise, fillITextbook, fillIToc} from "../entity-fill"
 | 
			
		||||
import {text} from "express"
 | 
			
		||||
 | 
			
		||||
@Service()
 | 
			
		||||
export class TextbookModel {
 | 
			
		||||
    existTextbook(textbook: string) {
 | 
			
		||||
        let raw = db.prepare('select rowid from solutions where textbook=? limit 1').get(textbook)
 | 
			
		||||
        return !!raw?.rowid
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    existSection(textbook: string, section: string) {
 | 
			
		||||
        let raw = db.prepare('select rowid from solutions where textbook=? and section=? limit 1').get(textbook, section)
 | 
			
		||||
        return !!raw?.rowid
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    existExercise(textbook: string, section: string, exercise: string) {
 | 
			
		||||
        let raw = db.prepare('select rowid from solutions ' +
 | 
			
		||||
            'where textbook=? and section=? and exercise=? limit 1').get(textbook, section, exercise)
 | 
			
		||||
        return !!raw?.rowid
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getTextbooks() {
 | 
			
		||||
        let raw = db.prepare('SELECT textbook as title,count(rowid) as quantity from solutions GROUP BY textbook').all()
 | 
			
		||||
        return raw.map(value => fillITextbook(value))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    findExercisesByTextbookSection(textbook: string, section: string) {
 | 
			
		||||
        let raw = db.prepare('SELECT exercise,section,part,page,html ' +
 | 
			
		||||
            'from solutions ' +
 | 
			
		||||
            'where textbook=? ' +
 | 
			
		||||
            'and section=? order by exercise asc').all(textbook, section)
 | 
			
		||||
        return raw.map(value => fillIExercise(value))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    findExercise(textbook: string, section: string, exercise: string) {
 | 
			
		||||
        let raw = db.prepare('SELECT exercise,section,part,page,html ' +
 | 
			
		||||
            'from solutions ' +
 | 
			
		||||
            'where textbook=? ' +
 | 
			
		||||
            'and section=? and exercise=?').get(textbook, section, exercise)
 | 
			
		||||
        return fillIExercise(raw)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    findExercisesByTextbookPage(textbook: string, page: number) {
 | 
			
		||||
        let raw = db.prepare('SELECT exercise,section,part,page,html ' +
 | 
			
		||||
            'from solutions ' +
 | 
			
		||||
            'where textbook=? ' +
 | 
			
		||||
            'and page=? order by exercise asc').all(textbook, page)
 | 
			
		||||
        return raw.map(value => fillIExercise(value))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    findTocByTextbook(textbook: string) {
 | 
			
		||||
        let raw = db.prepare('SELECT section, ' +
 | 
			
		||||
            'count(rowid) as count, ' +
 | 
			
		||||
            'min(page) as pageBegin, ' +
 | 
			
		||||
            'max(page) as pageEnd ' +
 | 
			
		||||
            'FROM "solutions" ' +
 | 
			
		||||
            'where textbook=? ' +
 | 
			
		||||
            'group by section ' +
 | 
			
		||||
            'order by pageBegin asc').all(textbook)
 | 
			
		||||
        return raw.map(value => fillIToc(value))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										53
									
								
								slader-legacy-backend/src/routers/textbook-router.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								slader-legacy-backend/src/routers/textbook-router.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
import 'reflect-metadata'
 | 
			
		||||
import express from "express"
 | 
			
		||||
import {param, query} from "express-validator"
 | 
			
		||||
import {Container} from "typedi"
 | 
			
		||||
import {TextbookModel} from "../models/textbook-model"
 | 
			
		||||
import expressAsyncHandler from "express-async-handler"
 | 
			
		||||
import {TextbookService} from "../services/textbook-service"
 | 
			
		||||
import {hasValidationErrors} from "../includes"
 | 
			
		||||
 | 
			
		||||
let textbookRouter = express.Router()
 | 
			
		||||
let textbookModel = Container.get(TextbookModel)
 | 
			
		||||
let textbookService = Container.get(TextbookService)
 | 
			
		||||
textbookRouter.get('/',
 | 
			
		||||
    expressAsyncHandler(async (req: express.Request, res: express.Response) => {
 | 
			
		||||
        res.json(await textbookService.listTextbooks())
 | 
			
		||||
    })
 | 
			
		||||
)
 | 
			
		||||
textbookRouter.get('/:textbook/:section?/:exercise?',
 | 
			
		||||
    param('textbook').notEmpty().bail().custom(input => {
 | 
			
		||||
        if (!textbookModel.existTextbook(input)) {
 | 
			
		||||
            throw new Error('textbook not exist')
 | 
			
		||||
        }
 | 
			
		||||
        return true
 | 
			
		||||
    }),
 | 
			
		||||
    query('page').optional().isInt({min: 1}),
 | 
			
		||||
    param('section').optional().notEmpty().bail().custom((input, {req}) => {
 | 
			
		||||
        if (!textbookModel.existSection(req.params!.textbook, input)) {
 | 
			
		||||
            throw new Error('section not exist')
 | 
			
		||||
        }
 | 
			
		||||
        return true
 | 
			
		||||
    }),
 | 
			
		||||
    param('exercise').optional().notEmpty().bail().custom((input, {req}) => {
 | 
			
		||||
        if (!textbookModel.existExercise(req.params!.textbook, req.params!.section, input)) {
 | 
			
		||||
            throw new Error('exercise not exist')
 | 
			
		||||
        }
 | 
			
		||||
        return true
 | 
			
		||||
    }),
 | 
			
		||||
    expressAsyncHandler(async (req: express.Request, res: express.Response) => {
 | 
			
		||||
        if (hasValidationErrors(req, res)) return
 | 
			
		||||
        if (req.query.page) {
 | 
			
		||||
            res.json(await textbookService.getPage(req.params.textbook, Number(req.query.page)))
 | 
			
		||||
        } else if (req.params.exercise) {
 | 
			
		||||
            res.json(await textbookService.getExercise(req.params.textbook, req.params.section, req.params.exercise))
 | 
			
		||||
        } else if (req.params.section) {
 | 
			
		||||
            res.json(await textbookService.getSection(req.params.textbook, req.params.section))
 | 
			
		||||
        } else {
 | 
			
		||||
            res.json(await textbookService.getTextbook(req.params.textbook))
 | 
			
		||||
        }
 | 
			
		||||
    })
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export {textbookRouter}
 | 
			
		||||
							
								
								
									
										30
									
								
								slader-legacy-backend/src/services/textbook-service.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								slader-legacy-backend/src/services/textbook-service.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
import 'reflect-metadata'
 | 
			
		||||
import {Inject, Service} from "typedi"
 | 
			
		||||
import {TextbookModel} from "../models/textbook-model"
 | 
			
		||||
import {resultJson} from "../includes"
 | 
			
		||||
 | 
			
		||||
@Service()
 | 
			
		||||
export class TextbookService {
 | 
			
		||||
    @Inject()
 | 
			
		||||
    textbookModel!: TextbookModel
 | 
			
		||||
 | 
			
		||||
    async getTextbook(textbook: string) {
 | 
			
		||||
        return resultJson.success(this.textbookModel.findTocByTextbook(textbook))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async getSection(textbook: string, section: string) {
 | 
			
		||||
        return resultJson.success(this.textbookModel.findExercisesByTextbookSection(textbook, section))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async getExercise(textbook: string, section: string, exercise: string) {
 | 
			
		||||
        return resultJson.success(this.textbookModel.findExercise(textbook, section, exercise))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async getPage(textbook: string, page: number) {
 | 
			
		||||
        return resultJson.success(this.textbookModel.findExercisesByTextbookPage(textbook, page))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async listTextbooks() {
 | 
			
		||||
        return resultJson.success(this.textbookModel.getTextbooks())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								slader-legacy-backend/src/types.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								slader-legacy-backend/src/types.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
export interface IResultJson {
 | 
			
		||||
    status: boolean,
 | 
			
		||||
    data: any
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IToc {
 | 
			
		||||
    section: string,
 | 
			
		||||
    count: number,
 | 
			
		||||
    pageBegin: number,
 | 
			
		||||
    pageEnd: number
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ITextbook {
 | 
			
		||||
    title: string,
 | 
			
		||||
    quantity: number
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IExercise {
 | 
			
		||||
    exercise: string,
 | 
			
		||||
    section: string,
 | 
			
		||||
    part: string,
 | 
			
		||||
    page: number,
 | 
			
		||||
    html: string
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										86
									
								
								slader-legacy-backend/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								slader-legacy-backend/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
{
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    /* Visit https://aka.ms/tsconfig.json to read more about this file */
 | 
			
		||||
 | 
			
		||||
    /* Basic Options */
 | 
			
		||||
    // "incremental": true,                         /* Enable incremental compilation */
 | 
			
		||||
    "target": "ES2016",
 | 
			
		||||
    /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
 | 
			
		||||
    "module": "commonjs",
 | 
			
		||||
    /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
 | 
			
		||||
    // "lib": [],                                   /* Specify library files to be included in the compilation. */
 | 
			
		||||
    "allowJs": true,
 | 
			
		||||
    /* Allow javascript files to be compiled. */
 | 
			
		||||
    // "checkJs": true,                             /* Report errors in .js files. */
 | 
			
		||||
    // "jsx": "preserve",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
 | 
			
		||||
    // "declaration": true,                         /* Generates corresponding '.d.ts' file. */
 | 
			
		||||
    // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */
 | 
			
		||||
    // "sourceMap": true,                           /* Generates corresponding '.map' file. */
 | 
			
		||||
    // "outFile": "./",                             /* Concatenate and emit output to single file. */
 | 
			
		||||
    "outDir": "./build",
 | 
			
		||||
    /* Redirect output structure to the directory. */
 | 
			
		||||
    "rootDir": "./src",
 | 
			
		||||
    /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
 | 
			
		||||
    // "composite": true,                           /* Enable project compilation */
 | 
			
		||||
    // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */
 | 
			
		||||
    // "removeComments": true,                      /* Do not emit comments to output. */
 | 
			
		||||
    // "noEmit": true,                              /* Do not emit outputs. */
 | 
			
		||||
    // "importHelpers": true,                       /* Import emit helpers from 'tslib'. */
 | 
			
		||||
    // "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
 | 
			
		||||
    // "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
 | 
			
		||||
 | 
			
		||||
    /* Strict Type-Checking Options */
 | 
			
		||||
    "strict": true,
 | 
			
		||||
    /* Enable all strict type-checking options. */
 | 
			
		||||
    // "noImplicitAny": true,                       /* Raise error on expressions and declarations with an implied 'any' type. */
 | 
			
		||||
    // "strictNullChecks": true,                    /* Enable strict null checks. */
 | 
			
		||||
    // "strictFunctionTypes": true,                 /* Enable strict checking of function types. */
 | 
			
		||||
    // "strictBindCallApply": true,                 /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
 | 
			
		||||
    // "strictPropertyInitialization": true,        /* Enable strict checking of property initialization in classes. */
 | 
			
		||||
    // "noImplicitThis": true,                      /* Raise error on 'this' expressions with an implied 'any' type. */
 | 
			
		||||
    // "alwaysStrict": true,                        /* Parse in strict mode and emit "use strict" for each source file. */
 | 
			
		||||
 | 
			
		||||
    /* Additional Checks */
 | 
			
		||||
    // "noUnusedLocals": true,                      /* Report errors on unused locals. */
 | 
			
		||||
    // "noUnusedParameters": true,                  /* Report errors on unused parameters. */
 | 
			
		||||
    // "noImplicitReturns": true,                   /* Report error when not all code paths in function return a value. */
 | 
			
		||||
    // "noFallthroughCasesInSwitch": true,          /* Report errors for fallthrough cases in switch statement. */
 | 
			
		||||
    // "noUncheckedIndexedAccess": true,            /* Include 'undefined' in index signature results */
 | 
			
		||||
    // "noPropertyAccessFromIndexSignature": true,  /* Require undeclared properties from index signatures to use element accesses. */
 | 
			
		||||
 | 
			
		||||
    /* Module Resolution Options */
 | 
			
		||||
    // "moduleResolution": "node",                  /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
 | 
			
		||||
    // "baseUrl": "./",                             /* Base directory to resolve non-absolute module names. */
 | 
			
		||||
    // "paths": {},                                 /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
 | 
			
		||||
    // "rootDirs": [],                              /* List of root folders whose combined content represents the structure of the project at runtime. */
 | 
			
		||||
    "typeRoots": [
 | 
			
		||||
      //      "./node_modules/**/*",
 | 
			
		||||
      "./node_modules/@types"
 | 
			
		||||
    ],
 | 
			
		||||
    /* List of folders to include type definitions from. */
 | 
			
		||||
    // "types": [],                                 /* Type declaration files to be included in compilation. */
 | 
			
		||||
    // "allowSyntheticDefaultImports": true,        /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
 | 
			
		||||
    "esModuleInterop": true,
 | 
			
		||||
    /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
 | 
			
		||||
    // "preserveSymlinks": true,                    /* Do not resolve the real path of symlinks. */
 | 
			
		||||
    // "allowUmdGlobalAccess": true,                /* Allow accessing UMD globals from modules. */
 | 
			
		||||
 | 
			
		||||
    /* Source Map Options */
 | 
			
		||||
    // "sourceRoot": "",                            /* Specify the location where debugger should locate TypeScript files instead of source locations. */
 | 
			
		||||
    // "mapRoot": "",                               /* Specify the location where debugger should locate map files instead of generated locations. */
 | 
			
		||||
    // "inlineSourceMap": true,                     /* Emit a single file with source maps instead of having a separate file. */
 | 
			
		||||
    // "inlineSources": true,                       /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
 | 
			
		||||
 | 
			
		||||
    /* Experimental Options */
 | 
			
		||||
    "experimentalDecorators": true,
 | 
			
		||||
    /* Enables experimental support for ES7 decorators. */
 | 
			
		||||
    "emitDecoratorMetadata": true,
 | 
			
		||||
    /* Enables experimental support for emitting type metadata for decorators. */
 | 
			
		||||
 | 
			
		||||
    /* Advanced Options */
 | 
			
		||||
    "skipLibCheck": true,
 | 
			
		||||
    /* Skip type checking of declaration files. */
 | 
			
		||||
    "forceConsistentCasingInFileNames": true
 | 
			
		||||
    /* Disallow inconsistently-cased references to the same file. */
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								slader-legacy-frontend/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								slader-legacy-frontend/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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?
 | 
			
		||||
							
								
								
									
										1
									
								
								slader-legacy-frontend/.npmrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								slader-legacy-frontend/.npmrc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
shamefully-hoist=true
 | 
			
		||||
							
								
								
									
										24
									
								
								slader-legacy-frontend/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								slader-legacy-frontend/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -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/).
 | 
			
		||||
							
								
								
									
										5
									
								
								slader-legacy-frontend/babel.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								slader-legacy-frontend/babel.config.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
module.exports = {
 | 
			
		||||
  presets: [
 | 
			
		||||
    '@vue/cli-plugin-babel/preset'
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								slader-legacy-frontend/config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								slader-legacy-frontend/config.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
require('dotenv').config()
 | 
			
		||||
let appConfig={
 | 
			
		||||
    baseUrl:process.env.VUE_APP_BASE_URL
 | 
			
		||||
}
 | 
			
		||||
console.log(appConfig)
 | 
			
		||||
export {appConfig}
 | 
			
		||||
							
								
								
									
										54
									
								
								slader-legacy-frontend/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								slader-legacy-frontend/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -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"
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								slader-legacy-frontend/public/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								slader-legacy-frontend/public/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 4.2 KiB  | 
							
								
								
									
										19
									
								
								slader-legacy-frontend/public/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								slader-legacy-frontend/public/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="utf-8">
 | 
			
		||||
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
 | 
			
		||||
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
 | 
			
		||||
<!--    <link rel="icon" href="<%= BASE_URL %>favicon.ico">-->
 | 
			
		||||
    <title><%= htmlWebpackPlugin.options.title %></title>
 | 
			
		||||
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <noscript>
 | 
			
		||||
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
 | 
			
		||||
    </noscript>
 | 
			
		||||
    <div id="app"></div>
 | 
			
		||||
    <!-- built files will be auto injected -->
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										922
									
								
								slader-legacy-frontend/public/test.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										922
									
								
								slader-legacy-frontend/public/test.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,922 @@
 | 
			
		||||
<article class="solution user-content"
 | 
			
		||||
         data-columns="1"
 | 
			
		||||
         data-editor-version="1"
 | 
			
		||||
>
 | 
			
		||||
    <header>
 | 
			
		||||
        <section class="top">
 | 
			
		||||
            <div class="user-attribution inline-picture-name size-small">
 | 
			
		||||
                <a href="/profile/SarahSchrijvers/" class="profile-image ">
 | 
			
		||||
                    <span class="profile-hover"></span>
 | 
			
		||||
                    <img src="https://d2nchlq0f2u6vy.cloudfront.net/cache/ed/d4/edd40ad50572b1124d30dbcadb608de2.jpg"
 | 
			
		||||
                         alt="Sarah Schrijvers"/>
 | 
			
		||||
                </a>
 | 
			
		||||
                <a href="/profile/SarahSchrijvers/" class="profile-name">Sarah Schrijvers<span class="moderator-flare" title="moderator"></span></a>
 | 
			
		||||
            </div>
 | 
			
		||||
            <section class="object-ratings-wrap">
 | 
			
		||||
                <section class="object-ratings large animatable solutions  unbound">
 | 
			
		||||
                    <div class="score">
 | 
			
		||||
                        <span>5.0</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <span class="rating-trigger icon-star"></span>
 | 
			
		||||
                    <div class="stars actionable"
 | 
			
		||||
                         data-user-rating="0"
 | 
			
		||||
                         data-url="/reputation/content-rating/"
 | 
			
		||||
                         data-object-id="26-2565690">
 | 
			
		||||
                        <span class="icon-star hvr-icon-pop" data-rating="1"></span>
 | 
			
		||||
                        <span class="icon-star hvr-icon-pop" data-rating="2"></span>
 | 
			
		||||
                        <span class="icon-star hvr-icon-pop" data-rating="3"></span>
 | 
			
		||||
                        <span class="icon-star hvr-icon-pop" data-rating="4"></span>
 | 
			
		||||
                        <span class="icon-star hvr-icon-pop" data-rating="5"></span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </section>
 | 
			
		||||
            </section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            <section class="open-comments unbound">
 | 
			
		||||
                <section class="anon-solution-uuid"
 | 
			
		||||
                         data-anon-solution-uuid="0e867829-fce4-4b23-b12c-ecdf7db28d25"></section>
 | 
			
		||||
                <span class="icon-comment" id="open-comments-btn"></span>
 | 
			
		||||
            </section>
 | 
			
		||||
 | 
			
		||||
        </section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    </header>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <section class="contents " data-content-id="0e867829-fce4-4b23-b12c-ecdf7db28d25">
 | 
			
		||||
 | 
			
		||||
        <section class="explanation">
 | 
			
		||||
            <div class="solution-row delete-column-options">
 | 
			
		||||
 | 
			
		||||
                <div class="solution-cell delete-row-column">
 | 
			
		||||
                    <a href="#" class="delete-column" aria-label="delete this column" title="delete this column"
 | 
			
		||||
                       data-x="1"
 | 
			
		||||
                       data-url="/edit-solution/delete-column/"><i class="icon-remove"></i></a>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            <div class="solution-row explanation-row">
 | 
			
		||||
                <div class="row-counter">
 | 
			
		||||
                    <span>1</span>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="solution-cell explanation"
 | 
			
		||||
                     data-complete="complete"
 | 
			
		||||
                >
 | 
			
		||||
                    <div class="solution-content-tools unbound"
 | 
			
		||||
                         data-tools-cell-id="51-9673568"
 | 
			
		||||
                         data-annotations-url="/textbook/annotations/">
 | 
			
		||||
                        <a href="#" aria-label="annotation icon" class="annotation-icon  icon-comment tool-icon"></a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="solution-content">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        <!-- If solution was created with the legacy editor AND the explanation_cell's latex_image field returns truthy, render img tags -->
 | 
			
		||||
 | 
			
		||||
                        <img src="https://d2nchlq0f2u6vy.cloudfront.net/18/03/13/6e3a59711be10db4f872f1dbbb706814/aa0226e1882218d5cea4d3960d5643b2/lateximg.png?tcb=1623075276"
 | 
			
		||||
                             class="image-reg" alt=""/>
 | 
			
		||||
 | 
			
		||||
                        <img src="https://d2nchlq0f2u6vy.cloudfront.net/18/03/13/6e3a59711be10db4f872f1dbbb706814/aa0226e1882218d5cea4d3960d5643b2/lateximg_large.png?tcb=1623075276"
 | 
			
		||||
                             class="image-large" alt=""/>
 | 
			
		||||
 | 
			
		||||
                        <!-- If explanation_cell contains LaTeX AND (editor_version == 2), render .react-result-cell -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="delete-row-options delete-row-column">
 | 
			
		||||
                    <a href="#" class="delete-row" aria-label="delete this row" title="delete this row"
 | 
			
		||||
                       data-url="/edit-solution/delete-row/"
 | 
			
		||||
                       data-y="2"><i class="icon-remove"></i></a>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div class="solution-row explanation-row">
 | 
			
		||||
                <div class="row-counter">
 | 
			
		||||
                    <span>2</span>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="solution-cell explanation"
 | 
			
		||||
                     data-complete="complete"
 | 
			
		||||
                >
 | 
			
		||||
                    <div class="solution-content-tools unbound"
 | 
			
		||||
                         data-tools-cell-id="51-9673567"
 | 
			
		||||
                         data-annotations-url="/textbook/annotations/">
 | 
			
		||||
                        <a href="#" aria-label="annotation icon" class="annotation-icon  icon-comment tool-icon"></a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="solution-content">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        <!-- If solution was created with the legacy editor AND the explanation_cell's latex_image field returns truthy, render img tags -->
 | 
			
		||||
 | 
			
		||||
                        <img src="https://d2nchlq0f2u6vy.cloudfront.net/18/03/13/6e3a59711be10db4f872f1dbbb706814/96f610e947aeae6c982684698b442004/lateximg.png?tcb=1623075276"
 | 
			
		||||
                             class="image-reg" alt=""/>
 | 
			
		||||
 | 
			
		||||
                        <img src="https://d2nchlq0f2u6vy.cloudfront.net/18/03/13/6e3a59711be10db4f872f1dbbb706814/96f610e947aeae6c982684698b442004/lateximg_large.png?tcb=1623075276"
 | 
			
		||||
                             class="image-large" alt=""/>
 | 
			
		||||
 | 
			
		||||
                        <!-- If explanation_cell contains LaTeX AND (editor_version == 2), render .react-result-cell -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="delete-row-options delete-row-column">
 | 
			
		||||
                    <a href="#" class="delete-row" aria-label="delete this row" title="delete this row"
 | 
			
		||||
                       data-url="/edit-solution/delete-row/"
 | 
			
		||||
                       data-y="3"><i class="icon-remove"></i></a>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
        </section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        <div class="solution-row result-row">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            <div class="solution-cell result"
 | 
			
		||||
                 data-complete="complete"
 | 
			
		||||
            >
 | 
			
		||||
                <div class="solution-content-tools unbound"
 | 
			
		||||
                     data-tools-cell-id="52-2688409"
 | 
			
		||||
                     data-annotations-url="/textbook/annotations/">
 | 
			
		||||
                    <a href="#" aria-label="annotation icon" class="annotation-icon  icon-comment tool-icon"></a>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="solution-content">
 | 
			
		||||
                    <span class="result-heading">RESULT</span>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    <!-- If solution was created with the legacy editor AND the result's latex_image field returns truthy, render img tags -->
 | 
			
		||||
 | 
			
		||||
                    <img src="https://d2nchlq0f2u6vy.cloudfront.net/18/03/13/6e3a59711be10db4f872f1dbbb706814/22c90bf1c7fe82f3bad3c39e0a4b8d39/lateximg.png?tcb=1623075276"
 | 
			
		||||
                         class="image-reg" alt=""/>
 | 
			
		||||
 | 
			
		||||
                    <img src="https://d2nchlq0f2u6vy.cloudfront.net/18/03/13/6e3a59711be10db4f872f1dbbb706814/22c90bf1c7fe82f3bad3c39e0a4b8d39/lateximg_large.png?tcb=1623075276"
 | 
			
		||||
                         class="image-large" alt=""/>
 | 
			
		||||
 | 
			
		||||
                    <!-- If result contains LaTeX AND (editor_version == 2), render .react-result-cell -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        <div class="unfinished-hover">
 | 
			
		||||
            <p>Your solution is not live yet. Click to edit.</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <section class="annotations">
 | 
			
		||||
            <a href="#" class="annotations-close" aria-label="close annotation"></a>
 | 
			
		||||
            <h4 class="Annotation__heading">Annotations</h4>
 | 
			
		||||
            <div class="contents loading"></div>
 | 
			
		||||
        </section>
 | 
			
		||||
    </section>
 | 
			
		||||
 | 
			
		||||
    <script type="text/javascript"
 | 
			
		||||
            src="https://d2nchlq0f2u6vy.cloudfront.net/js/react/webpack_bundles/resultCell-3ba9283f7955ff829635.js"></script>
 | 
			
		||||
    <script type="text/javascript"
 | 
			
		||||
            src="https://d2nchlq0f2u6vy.cloudfront.net/js/react/webpack_bundles/vendor-3ba9283f7955ff829635.js"></script>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <section class="nativo-container ads-to-hide"></section>
 | 
			
		||||
 | 
			
		||||
    <footer class="comment-footer">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        <section class="object-comments unbound" data-comments='0'>
 | 
			
		||||
            <section class="comments">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            </section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            <section class="add-comment">
 | 
			
		||||
                <form data-url="/comments/add-comment/" class="comment-form comment">
 | 
			
		||||
                    <input type="hidden" name="csrfmiddlewaretoken"
 | 
			
		||||
                           value="diz4CND75kEK6WdLWbQyuDG6Q6UgqDL61fByVDRv5gO5H5d8PcOgfkCqSwquQFQO">
 | 
			
		||||
                    <input type="hidden" name="comment_object" value="26-2565690" id="id_comment_object">
 | 
			
		||||
                    <input type="hidden" name="in_response_to" value=""/>
 | 
			
		||||
                    <div class="field-group">
 | 
			
		||||
                        <textarea name="comment" placeholder="Enter your comment here" class="latex-editable unbound"
 | 
			
		||||
                                  aria-labelledby="add-comment"></textarea>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="actions">
 | 
			
		||||
                        <input type="submit" class="button small submit Sldr__button" id="add-comment" value="Submit"/>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </form>
 | 
			
		||||
            </section>
 | 
			
		||||
 | 
			
		||||
        </section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    </footer>
 | 
			
		||||
</article>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div class='related_textbook_container'
 | 
			
		||||
     data-url="/textbook/related-textbook-list/9780073383095-discrete-mathematics-with-applications-7th-edition/"><span
 | 
			
		||||
        class="loader bg-white"></span></div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<article class="solution user-content
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  "
 | 
			
		||||
         data-columns="2"
 | 
			
		||||
         data-editor-version="1"
 | 
			
		||||
>
 | 
			
		||||
 | 
			
		||||
    <header>
 | 
			
		||||
        <section class="top">
 | 
			
		||||
 | 
			
		||||
            <div class="user-attribution inline-picture-name size-small">
 | 
			
		||||
                <a href="/profile/Medhit/" class="profile-image ">
 | 
			
		||||
                    <span class="profile-hover"></span>
 | 
			
		||||
                    <img src="https://d2nchlq0f2u6vy.cloudfront.net/images/profile/default_profile_pic_thumb.png"
 | 
			
		||||
                         alt="Medhit"/>
 | 
			
		||||
                </a>
 | 
			
		||||
                <a href="/profile/Medhit/" class="profile-name">Medhit</a>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <section class="object-ratings-wrap">
 | 
			
		||||
                <section class="object-ratings large animatable solutions  unbound">
 | 
			
		||||
                    <div class="score">
 | 
			
		||||
                        <span>1.4</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <span class="rating-trigger icon-star"></span>
 | 
			
		||||
                    <div class="stars actionable"
 | 
			
		||||
                         data-user-rating="0"
 | 
			
		||||
                         data-url="/reputation/content-rating/"
 | 
			
		||||
                         data-object-id="26-861361">
 | 
			
		||||
                        <span class="icon-star hvr-icon-pop" data-rating="1"></span>
 | 
			
		||||
                        <span class="icon-star hvr-icon-pop" data-rating="2"></span>
 | 
			
		||||
                        <span class="icon-star hvr-icon-pop" data-rating="3"></span>
 | 
			
		||||
                        <span class="icon-star hvr-icon-pop" data-rating="4"></span>
 | 
			
		||||
                        <span class="icon-star hvr-icon-pop" data-rating="5"></span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </section>
 | 
			
		||||
            </section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            <section class="open-comments unbound">
 | 
			
		||||
                <section class="anon-solution-uuid"
 | 
			
		||||
                         data-anon-solution-uuid="e3afbd90-c19b-4de5-913c-27f6f5535ffc"></section>
 | 
			
		||||
                <span class="icon-comment" id="open-comments-btn"></span>
 | 
			
		||||
            </section>
 | 
			
		||||
 | 
			
		||||
        </section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    </header>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <section class="contents " data-content-id="e3afbd90-c19b-4de5-913c-27f6f5535ffc">
 | 
			
		||||
 | 
			
		||||
        <section class="explanation">
 | 
			
		||||
            <div class="solution-row delete-column-options">
 | 
			
		||||
 | 
			
		||||
                <div class="solution-cell delete-row-column">
 | 
			
		||||
                    <a href="#" class="delete-column" aria-label="delete this column" title="delete this column"
 | 
			
		||||
                       data-x="1"
 | 
			
		||||
                       data-url="/edit-solution/delete-column/"><i class="icon-remove"></i></a>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
                <div class="solution-cell delete-row-column">
 | 
			
		||||
                    <a href="#" class="delete-column" aria-label="delete this column" title="delete this column"
 | 
			
		||||
                       data-x="2"
 | 
			
		||||
                       data-url="/edit-solution/delete-column/"><i class="icon-remove"></i></a>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            <div class="solution-row explanation-row">
 | 
			
		||||
                <div class="row-counter">
 | 
			
		||||
                    <span>1</span>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="solution-cell explanation"
 | 
			
		||||
                     data-complete="complete"
 | 
			
		||||
                >
 | 
			
		||||
                    <div class="solution-content-tools unbound"
 | 
			
		||||
                         data-tools-cell-id="51-2542846"
 | 
			
		||||
                         data-annotations-url="/textbook/annotations/">
 | 
			
		||||
                        <a href="#" aria-label="annotation icon" class="annotation-icon  icon-comment tool-icon"></a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="solution-content">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        <!-- If solution was created with the legacy editor AND the explanation_cell's latex_image field returns truthy, render img tags -->
 | 
			
		||||
 | 
			
		||||
                        <img src="https://d2nchlq0f2u6vy.cloudfront.net/14/12/20/9880aa4032dc9e50ddb889139266fcd6/2e054653349fd64e9d802747cb98be45/lateximg.png?tcb=1623075276"
 | 
			
		||||
                             class="image-reg" alt=""/>
 | 
			
		||||
 | 
			
		||||
                        <img src="https://d2nchlq0f2u6vy.cloudfront.net/14/12/20/9880aa4032dc9e50ddb889139266fcd6/2e054653349fd64e9d802747cb98be45/lateximg_large.png?tcb=1623075276"
 | 
			
		||||
                             class="image-large" alt=""/>
 | 
			
		||||
 | 
			
		||||
                        <!-- If explanation_cell contains LaTeX AND (editor_version == 2), render .react-result-cell -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="solution-cell explanation"
 | 
			
		||||
                     data-complete="complete"
 | 
			
		||||
                >
 | 
			
		||||
                    <div class="solution-content-tools unbound"
 | 
			
		||||
                         data-tools-cell-id="51-2542847"
 | 
			
		||||
                         data-annotations-url="/textbook/annotations/">
 | 
			
		||||
                        <a href="#" aria-label="annotation icon" class="annotation-icon  icon-comment tool-icon"></a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="solution-content">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        <!-- If explanation_cell does NOT contain LaTeX and (editor__version == 2), render .react-result-cell -->
 | 
			
		||||
 | 
			
		||||
                        <!-- Finally, render a simple paragraph tag if the previous conditions are NOT met -->
 | 
			
		||||
                        <p class="center">
 | 
			
		||||
                            the expression of every letter is given in the prompt </p>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="delete-row-options delete-row-column">
 | 
			
		||||
                    <a href="#" class="delete-row" aria-label="delete this row" title="delete this row"
 | 
			
		||||
                       data-url="/edit-solution/delete-row/"
 | 
			
		||||
                       data-y="2"><i class="icon-remove"></i></a>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div class="solution-row explanation-row">
 | 
			
		||||
                <div class="row-counter">
 | 
			
		||||
                    <span>2</span>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="solution-cell explanation"
 | 
			
		||||
                     data-complete="complete"
 | 
			
		||||
                >
 | 
			
		||||
                    <div class="solution-content-tools unbound"
 | 
			
		||||
                         data-tools-cell-id="51-2542848"
 | 
			
		||||
                         data-annotations-url="/textbook/annotations/">
 | 
			
		||||
                        <a href="#" aria-label="annotation icon" class="annotation-icon  icon-comment tool-icon"></a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="solution-content">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        <!-- If solution was created with the legacy editor AND the explanation_cell's latex_image field returns truthy, render img tags -->
 | 
			
		||||
 | 
			
		||||
                        <img src="https://d2nchlq0f2u6vy.cloudfront.net/14/12/20/9880aa4032dc9e50ddb889139266fcd6/7d3a1a6d1262e52f459b128481173319/lateximg.png?tcb=1623075276"
 | 
			
		||||
                             class="image-reg" alt=""/>
 | 
			
		||||
 | 
			
		||||
                        <img src="https://d2nchlq0f2u6vy.cloudfront.net/14/12/20/9880aa4032dc9e50ddb889139266fcd6/7d3a1a6d1262e52f459b128481173319/lateximg_large.png?tcb=1623075276"
 | 
			
		||||
                             class="image-large" alt=""/>
 | 
			
		||||
 | 
			
		||||
                        <!-- If explanation_cell contains LaTeX AND (editor_version == 2), render .react-result-cell -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        <a href="https://d2nchlq0f2u6vy.cloudfront.net/14/12/20/9880aa4032dc9e50ddb889139266fcd6/7d3a1a6d1262e52f459b128481173319/0ba70ccb8c5e4773a20fe9b8bf1268f0.png"
 | 
			
		||||
                           target="_blank">
 | 
			
		||||
                            <img src="https://d2nchlq0f2u6vy.cloudfront.net/14/12/20/9880aa4032dc9e50ddb889139266fcd6/7d3a1a6d1262e52f459b128481173319/0ba70ccb8c5e4773a20fe9b8bf1268f0.png?tcb=1623075276"
 | 
			
		||||
                                 class="image"/>
 | 
			
		||||
                        </a>
 | 
			
		||||
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="solution-cell explanation"
 | 
			
		||||
                     data-complete="complete"
 | 
			
		||||
                >
 | 
			
		||||
                    <div class="solution-content-tools unbound"
 | 
			
		||||
                         data-tools-cell-id="51-2542849"
 | 
			
		||||
                         data-annotations-url="/textbook/annotations/">
 | 
			
		||||
                        <a href="#" aria-label="annotation icon" class="annotation-icon  icon-comment tool-icon"></a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="solution-content">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        <!-- If explanation_cell does NOT contain LaTeX and (editor__version == 2), render .react-result-cell -->
 | 
			
		||||
 | 
			
		||||
                        <!-- Finally, render a simple paragraph tag if the previous conditions are NOT met -->
 | 
			
		||||
                        <p>
 | 
			
		||||
                            the symbol shown in this step if for inclusive distinction as explained in pp 4 and 5 </p>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="delete-row-options delete-row-column">
 | 
			
		||||
                    <a href="#" class="delete-row" aria-label="delete this row" title="delete this row"
 | 
			
		||||
                       data-url="/edit-solution/delete-row/"
 | 
			
		||||
                       data-y="3"><i class="icon-remove"></i></a>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div class="solution-row explanation-row">
 | 
			
		||||
                <div class="row-counter">
 | 
			
		||||
                    <span>3</span>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="solution-cell explanation"
 | 
			
		||||
                     data-complete="complete"
 | 
			
		||||
                >
 | 
			
		||||
                    <div class="solution-content-tools unbound"
 | 
			
		||||
                         data-tools-cell-id="51-2542930"
 | 
			
		||||
                         data-annotations-url="/textbook/annotations/">
 | 
			
		||||
                        <a href="#" aria-label="annotation icon" class="annotation-icon  icon-comment tool-icon"></a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="solution-content">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        <!-- If solution was created with the legacy editor AND the explanation_cell's latex_image field returns truthy, render img tags -->
 | 
			
		||||
 | 
			
		||||
                        <img src="https://d2nchlq0f2u6vy.cloudfront.net/14/12/20/9880aa4032dc9e50ddb889139266fcd6/fd363a042d21f5e8ccf4ce2e0295553c/lateximg.png?tcb=1623075276"
 | 
			
		||||
                             class="image-reg" alt=""/>
 | 
			
		||||
 | 
			
		||||
                        <img src="https://d2nchlq0f2u6vy.cloudfront.net/14/12/20/9880aa4032dc9e50ddb889139266fcd6/fd363a042d21f5e8ccf4ce2e0295553c/lateximg_large.png?tcb=1623075276"
 | 
			
		||||
                             class="image-large" alt=""/>
 | 
			
		||||
 | 
			
		||||
                        <!-- If explanation_cell contains LaTeX AND (editor_version == 2), render .react-result-cell -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        <a href="https://d2nchlq0f2u6vy.cloudfront.net/14/12/20/9880aa4032dc9e50ddb889139266fcd6/fd363a042d21f5e8ccf4ce2e0295553c/f40fbf5bfcba4f6f997743fa8c1324b3.png"
 | 
			
		||||
                           target="_blank">
 | 
			
		||||
                            <img src="https://d2nchlq0f2u6vy.cloudfront.net/14/12/20/9880aa4032dc9e50ddb889139266fcd6/fd363a042d21f5e8ccf4ce2e0295553c/f40fbf5bfcba4f6f997743fa8c1324b3.png?tcb=1623075276"
 | 
			
		||||
                                 class="image"/>
 | 
			
		||||
                        </a>
 | 
			
		||||
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="solution-cell explanation"
 | 
			
		||||
                     data-complete="complete"
 | 
			
		||||
                >
 | 
			
		||||
                    <div class="solution-content-tools unbound"
 | 
			
		||||
                         data-tools-cell-id="51-2542931"
 | 
			
		||||
                         data-annotations-url="/textbook/annotations/">
 | 
			
		||||
                        <a href="#" aria-label="annotation icon" class="annotation-icon  icon-comment tool-icon"></a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="solution-content">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        <!-- If explanation_cell does NOT contain LaTeX and (editor__version == 2), render .react-result-cell -->
 | 
			
		||||
 | 
			
		||||
                        <!-- Finally, render a simple paragraph tag if the previous conditions are NOT met -->
 | 
			
		||||
                        <p class="center">
 | 
			
		||||
                            the arrow denotes an implication as shown in pp 6</p>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="delete-row-options delete-row-column">
 | 
			
		||||
                    <a href="#" class="delete-row" aria-label="delete this row" title="delete this row"
 | 
			
		||||
                       data-url="/edit-solution/delete-row/"
 | 
			
		||||
                       data-y="4"><i class="icon-remove"></i></a>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
        </section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        <div class="solution-row result-row">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            <div class="solution-cell result"
 | 
			
		||||
                 data-complete="complete"
 | 
			
		||||
            >
 | 
			
		||||
                <div class="solution-content-tools unbound"
 | 
			
		||||
                     data-tools-cell-id="52-672847"
 | 
			
		||||
                     data-annotations-url="/textbook/annotations/">
 | 
			
		||||
                    <a href="#" aria-label="annotation icon" class="annotation-icon  icon-comment tool-icon"></a>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="solution-content">
 | 
			
		||||
                    <span class="result-heading">RESULT</span>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    <!-- If result does NOT contain LaTeX and (editor__version == 2), render .react-result-cell -->
 | 
			
		||||
 | 
			
		||||
                    <!-- Finally, render a simple paragraph tag if the previous conditions are NOT met -->
 | 
			
		||||
                    <p class="center">
 | 
			
		||||
                        the final result is shown in line 3</p>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        <div class="unfinished-hover">
 | 
			
		||||
            <p>Your solution is not live yet. Click to edit.</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <section class="annotations">
 | 
			
		||||
            <a href="#" class="annotations-close" aria-label="close annotation"></a>
 | 
			
		||||
            <h4 class="Annotation__heading">Annotations</h4>
 | 
			
		||||
            <div class="contents loading"></div>
 | 
			
		||||
        </section>
 | 
			
		||||
    </section>
 | 
			
		||||
 | 
			
		||||
    <script type="text/javascript"
 | 
			
		||||
            src="https://d2nchlq0f2u6vy.cloudfront.net/js/react/webpack_bundles/resultCell-3ba9283f7955ff829635.js"></script>
 | 
			
		||||
    <script type="text/javascript"
 | 
			
		||||
            src="https://d2nchlq0f2u6vy.cloudfront.net/js/react/webpack_bundles/vendor-3ba9283f7955ff829635.js"></script>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <footer class="comment-footer">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        <section class="object-comments unbound" data-comments='5'>
 | 
			
		||||
            <section class="comments">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="comment unbound user-content" data-uuid="6c9ef089-a8d4-4fb1-9aeb-b7ee8a8588ab">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    <div class="comment-details">
 | 
			
		||||
 | 
			
		||||
                        <div class="user-attribution inline-name size-small">
 | 
			
		||||
                            <a href="/profile/arpan.majee/" class="profile-image ">
 | 
			
		||||
                                <span class="profile-hover"></span>
 | 
			
		||||
                                <img src="https://d2nchlq0f2u6vy.cloudfront.net/cache/e0/18/e0186d4e4141dc6048a6d96485258997.jpg"
 | 
			
		||||
                                     alt="Arpan Majee"/>
 | 
			
		||||
                            </a>
 | 
			
		||||
                            <a href="/profile/arpan.majee/" class="profile-name">Arpan Majee</a>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
                        <span class="comment-reply-button">reply</span>
 | 
			
		||||
 | 
			
		||||
                        <section class="object-votes unbound"
 | 
			
		||||
                                 data-object-id="136-255689"
 | 
			
		||||
                                 data-url="/reputation/content-vote/">
 | 
			
		||||
                            <span class="upvote vote"><a href="#" data-vote="1" aria-label="upvote comment"
 | 
			
		||||
                                                         class="vote "><i class="icon-caret-up"></i></a></span>
 | 
			
		||||
                            <span class="score">2 </span>
 | 
			
		||||
                            <span class="downvote vote"><a href="#" data-vote="-1" aria-label="downvote comment"
 | 
			
		||||
                                                           class="vote "><i class="icon-caret-down"></i></a></span>
 | 
			
		||||
                        </section>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="body editable-content preview"
 | 
			
		||||
                         data-editable-id="6c9ef089-a8d4-4fb1-9aeb-b7ee8a8588ab">
 | 
			
		||||
                        <div class="rendered">Shouldn't it rather be m only if (e ∨ p) i.e. m → (e ∨ p)?</div>
 | 
			
		||||
                        <textarea aria-label="edit comment">Shouldn't it rather be m only if (e ∨ p) i.e. m → (e ∨ p)?</textarea>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="replies">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        <form data-url="/comments/add-comment/" class="comment-form comment reply-form hidden">
 | 
			
		||||
                            <input type="hidden" name="csrfmiddlewaretoken"
 | 
			
		||||
                                   value="diz4CND75kEK6WdLWbQyuDG6Q6UgqDL61fByVDRv5gO5H5d8PcOgfkCqSwquQFQO">
 | 
			
		||||
                            <input type="hidden" name="comment_object" value="26-861361"/>
 | 
			
		||||
                            <input type="hidden" name="in_response_to" value="6c9ef089-a8d4-4fb1-9aeb-b7ee8a8588ab"/>
 | 
			
		||||
                            <div class="field-group">
 | 
			
		||||
                                <textarea name="comment" placeholder="Reply to Arpan Majee"
 | 
			
		||||
                                          class="latex-editable unbound" aria-labelledby="submit-reply"></textarea>
 | 
			
		||||
                            </div>
 | 
			
		||||
                            <div class="actions">
 | 
			
		||||
                                <input type="submit" class="button small submit" id="submit-reply" value="Submit"/>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </form>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="comment unbound user-content" data-uuid="22c2aa40-a739-42e8-accb-2e7a6e11066c">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    <div class="comment-details">
 | 
			
		||||
 | 
			
		||||
                        <div class="user-attribution inline-name size-small">
 | 
			
		||||
                            <a href="/profile/alon.hilleltuch/" class="profile-image ">
 | 
			
		||||
                                <span class="profile-hover"></span>
 | 
			
		||||
                                <img src="https://d2nchlq0f2u6vy.cloudfront.net/images/profile/default_profile_pic_thumb.png"
 | 
			
		||||
                                     alt="Alon"/>
 | 
			
		||||
                            </a>
 | 
			
		||||
                            <a href="/profile/alon.hilleltuch/" class="profile-name">Alon</a>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
                        <span class="comment-reply-button">reply</span>
 | 
			
		||||
 | 
			
		||||
                        <section class="object-votes unbound"
 | 
			
		||||
                                 data-object-id="136-370027"
 | 
			
		||||
                                 data-url="/reputation/content-vote/">
 | 
			
		||||
                            <span class="upvote vote"><a href="#" data-vote="1" aria-label="upvote comment"
 | 
			
		||||
                                                         class="vote "><i class="icon-caret-up"></i></a></span>
 | 
			
		||||
                            <span class="score">1 </span>
 | 
			
		||||
                            <span class="downvote vote"><a href="#" data-vote="-1" aria-label="downvote comment"
 | 
			
		||||
                                                           class="vote "><i class="icon-caret-down"></i></a></span>
 | 
			
		||||
                        </section>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="body editable-content preview"
 | 
			
		||||
                         data-editable-id="22c2aa40-a739-42e8-accb-2e7a6e11066c">
 | 
			
		||||
                        <div class="rendered"><--> is IF AND ONLY IF....check in first chapter under definition 5.
 | 
			
		||||
                            p->q has a table of English statements describing it, one is "p only if q"
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <textarea aria-label="edit comment"><--> is IF AND ONLY IF....check in first chapter under definition 5. p->q has a table of English statements describing it, one is "p only if q"</textarea>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="replies">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        <form data-url="/comments/add-comment/" class="comment-form comment reply-form hidden">
 | 
			
		||||
                            <input type="hidden" name="csrfmiddlewaretoken"
 | 
			
		||||
                                   value="diz4CND75kEK6WdLWbQyuDG6Q6UgqDL61fByVDRv5gO5H5d8PcOgfkCqSwquQFQO">
 | 
			
		||||
                            <input type="hidden" name="comment_object" value="26-861361"/>
 | 
			
		||||
                            <input type="hidden" name="in_response_to" value="22c2aa40-a739-42e8-accb-2e7a6e11066c"/>
 | 
			
		||||
                            <div class="field-group">
 | 
			
		||||
                                <textarea name="comment" placeholder="Reply to Alon" class="latex-editable unbound"
 | 
			
		||||
                                          aria-labelledby="submit-reply"></textarea>
 | 
			
		||||
                            </div>
 | 
			
		||||
                            <div class="actions">
 | 
			
		||||
                                <input type="submit" class="button small submit" id="submit-reply" value="Submit"/>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </form>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="comment unbound user-content" data-uuid="9a2755d4-930a-4276-b641-5da8cfe09f69">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    <div class="comment-details">
 | 
			
		||||
 | 
			
		||||
                        <div class="user-attribution inline-name size-small">
 | 
			
		||||
                            <a href="/profile/IcEiE/" class="profile-image ">
 | 
			
		||||
                                <span class="profile-hover"></span>
 | 
			
		||||
                                <img src="https://d2nchlq0f2u6vy.cloudfront.net/images/profile/default_profile_pic_thumb.png"
 | 
			
		||||
                                     alt="IcEiE"/>
 | 
			
		||||
                            </a>
 | 
			
		||||
                            <a href="/profile/IcEiE/" class="profile-name">IcEiE</a>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
                        <span class="comment-reply-button">reply</span>
 | 
			
		||||
 | 
			
		||||
                        <section class="object-votes unbound"
 | 
			
		||||
                                 data-object-id="136-260396"
 | 
			
		||||
                                 data-url="/reputation/content-vote/">
 | 
			
		||||
                            <span class="upvote vote"><a href="#" data-vote="1" aria-label="upvote comment"
 | 
			
		||||
                                                         class="vote "><i class="icon-caret-up"></i></a></span>
 | 
			
		||||
                            <span class="score">0 </span>
 | 
			
		||||
                            <span class="downvote vote"><a href="#" data-vote="-1" aria-label="downvote comment"
 | 
			
		||||
                                                           class="vote "><i class="icon-caret-down"></i></a></span>
 | 
			
		||||
                        </section>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="body editable-content preview"
 | 
			
		||||
                         data-editable-id="9a2755d4-930a-4276-b641-5da8cfe09f69">
 | 
			
		||||
                        <div class="rendered">They say ONLY IF. I take this as you will use <--> between (e or a)
 | 
			
		||||
                            and m. (e or a) <--> m. So this also means that if you went to the movie then you most
 | 
			
		||||
                            be at least 18 years old or have permission from parent.
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <textarea aria-label="edit comment">They say ONLY IF. I take this as you will use <--> between (e or a) and m.  (e or a) <--> m. So this also means that if you went to the movie then you most be at least 18 years old or have permission from parent.</textarea>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="replies">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        <form data-url="/comments/add-comment/" class="comment-form comment reply-form hidden">
 | 
			
		||||
                            <input type="hidden" name="csrfmiddlewaretoken"
 | 
			
		||||
                                   value="diz4CND75kEK6WdLWbQyuDG6Q6UgqDL61fByVDRv5gO5H5d8PcOgfkCqSwquQFQO">
 | 
			
		||||
                            <input type="hidden" name="comment_object" value="26-861361"/>
 | 
			
		||||
                            <input type="hidden" name="in_response_to" value="9a2755d4-930a-4276-b641-5da8cfe09f69"/>
 | 
			
		||||
                            <div class="field-group">
 | 
			
		||||
                                <textarea name="comment" placeholder="Reply to IcEiE" class="latex-editable unbound"
 | 
			
		||||
                                          aria-labelledby="submit-reply"></textarea>
 | 
			
		||||
                            </div>
 | 
			
		||||
                            <div class="actions">
 | 
			
		||||
                                <input type="submit" class="button small submit" id="submit-reply" value="Submit"/>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </form>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="comment unbound user-content" data-uuid="6a60c759-eb57-44fb-803f-f424839be495">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    <div class="comment-details">
 | 
			
		||||
 | 
			
		||||
                        <div class="user-attribution inline-name size-small">
 | 
			
		||||
                            <a href="/profile/14ptrevi/" class="profile-image ">
 | 
			
		||||
                                <span class="profile-hover"></span>
 | 
			
		||||
                                <img src="https://d2nchlq0f2u6vy.cloudfront.net/cache/1b/07/1b07a3d7c46be9f01b3a6666a2e93c4a.jpg"
 | 
			
		||||
                                     alt="Pearl"/>
 | 
			
		||||
                            </a>
 | 
			
		||||
                            <a href="/profile/14ptrevi/" class="profile-name">Pearl</a>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
                        <span class="comment-reply-button">reply</span>
 | 
			
		||||
 | 
			
		||||
                        <section class="object-votes unbound"
 | 
			
		||||
                                 data-object-id="136-238008"
 | 
			
		||||
                                 data-url="/reputation/content-vote/">
 | 
			
		||||
                            <span class="upvote vote"><a href="#" data-vote="1" aria-label="upvote comment"
 | 
			
		||||
                                                         class="vote "><i class="icon-caret-up"></i></a></span>
 | 
			
		||||
                            <span class="score">-11 </span>
 | 
			
		||||
                            <span class="downvote vote"><a href="#" data-vote="-1" aria-label="downvote comment"
 | 
			
		||||
                                                           class="vote "><i class="icon-caret-down"></i></a></span>
 | 
			
		||||
                        </section>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="body editable-content preview"
 | 
			
		||||
                         data-editable-id="6a60c759-eb57-44fb-803f-f424839be495">
 | 
			
		||||
                        <div class="rendered">???</div>
 | 
			
		||||
                        <textarea aria-label="edit comment">???</textarea>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="replies">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        <form data-url="/comments/add-comment/" class="comment-form comment reply-form hidden">
 | 
			
		||||
                            <input type="hidden" name="csrfmiddlewaretoken"
 | 
			
		||||
                                   value="diz4CND75kEK6WdLWbQyuDG6Q6UgqDL61fByVDRv5gO5H5d8PcOgfkCqSwquQFQO">
 | 
			
		||||
                            <input type="hidden" name="comment_object" value="26-861361"/>
 | 
			
		||||
                            <input type="hidden" name="in_response_to" value="6a60c759-eb57-44fb-803f-f424839be495"/>
 | 
			
		||||
                            <div class="field-group">
 | 
			
		||||
                                <textarea name="comment" placeholder="Reply to Pearl" class="latex-editable unbound"
 | 
			
		||||
                                          aria-labelledby="submit-reply"></textarea>
 | 
			
		||||
                            </div>
 | 
			
		||||
                            <div class="actions">
 | 
			
		||||
                                <input type="submit" class="button small submit" id="submit-reply" value="Submit"/>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </form>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <div class="comment unbound user-content" data-uuid="b5246ca6-3ad9-4e17-a825-265124199397">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    <div class="comment-details">
 | 
			
		||||
 | 
			
		||||
                        <div class="user-attribution inline-name size-small">
 | 
			
		||||
                            <a href="/profile/MuhammadMustafa/" class="profile-image ">
 | 
			
		||||
                                <span class="profile-hover"></span>
 | 
			
		||||
                                <img src="https://d2nchlq0f2u6vy.cloudfront.net/cache/c3/2d/c32de46bcda295e8d5d51ca883999884.jpg"
 | 
			
		||||
                                     alt="MuhammadMustafa"/>
 | 
			
		||||
                            </a>
 | 
			
		||||
                            <a href="/profile/MuhammadMustafa/" class="profile-name">MuhammadMustafa</a>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
                        <span class="comment-reply-button">reply</span>
 | 
			
		||||
 | 
			
		||||
                        <section class="object-votes unbound"
 | 
			
		||||
                                 data-object-id="136-237695"
 | 
			
		||||
                                 data-url="/reputation/content-vote/">
 | 
			
		||||
                            <span class="upvote vote"><a href="#" data-vote="1" aria-label="upvote comment"
 | 
			
		||||
                                                         class="vote "><i class="icon-caret-up"></i></a></span>
 | 
			
		||||
                            <span class="score">-17 </span>
 | 
			
		||||
                            <span class="downvote vote"><a href="#" data-vote="-1" aria-label="downvote comment"
 | 
			
		||||
                                                           class="vote "><i class="icon-caret-down"></i></a></span>
 | 
			
		||||
                        </section>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="body editable-content preview"
 | 
			
		||||
                         data-editable-id="b5246ca6-3ad9-4e17-a825-265124199397">
 | 
			
		||||
                        <div class="rendered">This is wrong unfortunately, as if (e v p) is false then m can be true and
 | 
			
		||||
                            this is unacceptable in the statement.
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <textarea aria-label="edit comment">This is wrong unfortunately, as if (e v p) is false then m can be true and this is unacceptable in the statement.</textarea>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="replies">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        <form data-url="/comments/add-comment/" class="comment-form comment reply-form hidden">
 | 
			
		||||
                            <input type="hidden" name="csrfmiddlewaretoken"
 | 
			
		||||
                                   value="diz4CND75kEK6WdLWbQyuDG6Q6UgqDL61fByVDRv5gO5H5d8PcOgfkCqSwquQFQO">
 | 
			
		||||
                            <input type="hidden" name="comment_object" value="26-861361"/>
 | 
			
		||||
                            <input type="hidden" name="in_response_to" value="b5246ca6-3ad9-4e17-a825-265124199397"/>
 | 
			
		||||
                            <div class="field-group">
 | 
			
		||||
                                <textarea name="comment" placeholder="Reply to MuhammadMustafa"
 | 
			
		||||
                                          class="latex-editable unbound" aria-labelledby="submit-reply"></textarea>
 | 
			
		||||
                            </div>
 | 
			
		||||
                            <div class="actions">
 | 
			
		||||
                                <input type="submit" class="button small submit" id="submit-reply" value="Submit"/>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </form>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            </section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            <section class="add-comment">
 | 
			
		||||
                <form data-url="/comments/add-comment/" class="comment-form comment">
 | 
			
		||||
                    <input type="hidden" name="csrfmiddlewaretoken"
 | 
			
		||||
                           value="diz4CND75kEK6WdLWbQyuDG6Q6UgqDL61fByVDRv5gO5H5d8PcOgfkCqSwquQFQO">
 | 
			
		||||
                    <input type="hidden" name="comment_object" value="26-861361" id="id_comment_object">
 | 
			
		||||
                    <input type="hidden" name="in_response_to" value=""/>
 | 
			
		||||
                    <div class="field-group">
 | 
			
		||||
                        <textarea name="comment" placeholder="Enter your comment here" class="latex-editable unbound"
 | 
			
		||||
                                  aria-labelledby="add-comment"></textarea>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="actions">
 | 
			
		||||
                        <input type="submit" class="button small submit Sldr__button" id="add-comment" value="Submit"/>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </form>
 | 
			
		||||
            </section>
 | 
			
		||||
 | 
			
		||||
        </section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    </footer>
 | 
			
		||||
</article>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<script type="text/javascript"
 | 
			
		||||
        src="https://d2nchlq0f2u6vy.cloudfront.net/js/react/webpack_bundles/resultCell-3ba9283f7955ff829635.js"></script>
 | 
			
		||||
<script type="text/javascript"
 | 
			
		||||
        src="https://d2nchlq0f2u6vy.cloudfront.net/js/react/webpack_bundles/vendor-3ba9283f7955ff829635.js"></script>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div class="edit-toolbar">
 | 
			
		||||
    <a href="#" class="edit-math" aria-label="edit math" data-tool="math"><i class="icon-superscript"></i></a>
 | 
			
		||||
 | 
			
		||||
    <a href="#" class="delete-image" aria-label="delete image" data-tool="image"><i class="icon-picture"></i>
 | 
			
		||||
        −</a>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<form class="solution-image-uploader" data-url="/edit-solution/edit-image/" style="display:none;">
 | 
			
		||||
    <input type="hidden" name="csrfmiddlewaretoken"
 | 
			
		||||
           value="diz4CND75kEK6WdLWbQyuDG6Q6UgqDL61fByVDRv5gO5H5d8PcOgfkCqSwquQFQO">
 | 
			
		||||
    <input type="hidden" name="id"/>
 | 
			
		||||
    <input type="hidden" name="type"/>
 | 
			
		||||
    <input type="hidden" name="uuid"/>
 | 
			
		||||
    <div id="solution-image-uploader" class="file-upload-field"></div>
 | 
			
		||||
</form>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<section class="Paywall__footer-counter">
 | 
			
		||||
    <div class="Paywall__footer__counter__wrapper">
 | 
			
		||||
        <section class="Paywall__left-content">
 | 
			
		||||
 | 
			
		||||
            <h3 class="Paywall__footer-counter-heading" data-sol-remaining="2">2 solutions LEFT</h3>
 | 
			
		||||
 | 
			
		||||
            <p class="Paywall__body ">
 | 
			
		||||
                Head to Quizlet explanations for unlimited expert-verified solutions.
 | 
			
		||||
            </p>
 | 
			
		||||
        </section>
 | 
			
		||||
        <section class="Paywall__right-content">
 | 
			
		||||
            <a href="https://quizlet.com/features/slader_quizlet_explanations" class="Homepage__button">Go to
 | 
			
		||||
                Quizlet</a>
 | 
			
		||||
 | 
			
		||||
            <a href="//www.slader.com/account/login/?redirect_to=None" class="Paywall__login-button">Already a
 | 
			
		||||
                subscriber? Log in</a>
 | 
			
		||||
 | 
			
		||||
        </section>
 | 
			
		||||
        <span class="Paywall__footer-counter--close"></span>
 | 
			
		||||
    </div>
 | 
			
		||||
</section>
 | 
			
		||||
							
								
								
									
										68
									
								
								slader-legacy-frontend/src/App.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								slader-legacy-frontend/src/App.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <v-app>
 | 
			
		||||
    <v-app-bar app>
 | 
			
		||||
      <v-app-bar-nav-icon @click="navigateToHome">
 | 
			
		||||
        <v-icon>mdi-home</v-icon>
 | 
			
		||||
      </v-app-bar-nav-icon>
 | 
			
		||||
      <v-toolbar-title class="text-h5">slader-legacy</v-toolbar-title>
 | 
			
		||||
      <v-spacer></v-spacer>
 | 
			
		||||
      <v-btn icon>
 | 
			
		||||
        <v-icon @click="toggleDarkTheme">mdi-brightness-6</v-icon>
 | 
			
		||||
      </v-btn>
 | 
			
		||||
    </v-app-bar>
 | 
			
		||||
    <v-main>
 | 
			
		||||
      <v-container fluid>
 | 
			
		||||
        <v-row justify="center">
 | 
			
		||||
          <v-col md="8" sm="12">
 | 
			
		||||
            <v-card :loading="cardLoading">
 | 
			
		||||
              <keep-alive>
 | 
			
		||||
                <router-view @setCardLoadingStatus="handleSetCardLoadingStatus" class="pa-4"></router-view>
 | 
			
		||||
              </keep-alive>
 | 
			
		||||
 | 
			
		||||
            </v-card>
 | 
			
		||||
          </v-col>
 | 
			
		||||
        </v-row>
 | 
			
		||||
      </v-container>
 | 
			
		||||
    </v-main>
 | 
			
		||||
    <v-footer padless>
 | 
			
		||||
      <v-col cols="12" class="text-center">
 | 
			
		||||
        slader-legacy {{ new Date().getFullYear() }}
 | 
			
		||||
      </v-col>
 | 
			
		||||
    </v-footer>
 | 
			
		||||
  </v-app>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
import TextbookBlock from "@/components/TextbookBlock"
 | 
			
		||||
import {cardLoadingStatusCheck, showServerErrorAlert} from "@/includes"
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'App',
 | 
			
		||||
  components: {
 | 
			
		||||
    TextbookBlock
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      cardLoading: true
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    handleSetCardLoadingStatus(status) {
 | 
			
		||||
      this.cardLoading = status
 | 
			
		||||
    },
 | 
			
		||||
    navigateToHome() {
 | 
			
		||||
      this.$router.push('/')
 | 
			
		||||
    },
 | 
			
		||||
    toggleDarkTheme() {
 | 
			
		||||
      this.$vuetify.theme.dark = !this.$vuetify.theme.dark
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped>
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								slader-legacy-frontend/src/assets/logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								slader-legacy-frontend/src/assets/logo.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 6.7 KiB  | 
							
								
								
									
										1
									
								
								slader-legacy-frontend/src/assets/logo.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								slader-legacy-frontend/src/assets/logo.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 87.5 100"><defs><style>.cls-1{fill:#1697f6;}.cls-2{fill:#7bc6ff;}.cls-3{fill:#1867c0;}.cls-4{fill:#aeddff;}</style></defs><title>Artboard 46</title><polyline class="cls-1" points="43.75 0 23.31 0 43.75 48.32"/><polygon class="cls-2" points="43.75 62.5 43.75 100 0 14.58 22.92 14.58 43.75 62.5"/><polyline class="cls-3" points="43.75 0 64.19 0 43.75 48.32"/><polygon class="cls-4" points="64.58 14.58 87.5 14.58 43.75 100 43.75 62.5 64.58 14.58"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 539 B  | 
							
								
								
									
										151
									
								
								slader-legacy-frontend/src/components/HelloWorld.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								slader-legacy-frontend/src/components/HelloWorld.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,151 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <v-container>
 | 
			
		||||
    <v-row class="text-center">
 | 
			
		||||
      <v-col cols="12">
 | 
			
		||||
        <v-img
 | 
			
		||||
          :src="require('../assets/logo.svg')"
 | 
			
		||||
          class="my-3"
 | 
			
		||||
          contain
 | 
			
		||||
          height="200"
 | 
			
		||||
        />
 | 
			
		||||
      </v-col>
 | 
			
		||||
 | 
			
		||||
      <v-col class="mb-4">
 | 
			
		||||
        <h1 class="display-2 font-weight-bold mb-3 elevation-4 blue--text yellow">
 | 
			
		||||
          Welcome to Vuetify
 | 
			
		||||
        </h1>
 | 
			
		||||
 | 
			
		||||
        <p class="subheading font-weight-regular">
 | 
			
		||||
          For help and collaboration with other Vuetify developers,
 | 
			
		||||
          <br>please join our online
 | 
			
		||||
          <a
 | 
			
		||||
            href="https://community.vuetifyjs.com"
 | 
			
		||||
            target="_blank"
 | 
			
		||||
          >Discord Community</a>
 | 
			
		||||
        </p>
 | 
			
		||||
      </v-col>
 | 
			
		||||
 | 
			
		||||
      <v-col
 | 
			
		||||
        class="mb-5"
 | 
			
		||||
        cols="12"
 | 
			
		||||
      >
 | 
			
		||||
        <h2 class="headline font-weight-bold mb-3">
 | 
			
		||||
          What's next?
 | 
			
		||||
        </h2>
 | 
			
		||||
 | 
			
		||||
        <v-row justify="center">
 | 
			
		||||
          <a
 | 
			
		||||
            v-for="(next, i) in whatsNext"
 | 
			
		||||
            :key="i"
 | 
			
		||||
            :href="next.href"
 | 
			
		||||
            class="subheading mx-3"
 | 
			
		||||
            target="_blank"
 | 
			
		||||
          >
 | 
			
		||||
            {{ next.text }}
 | 
			
		||||
          </a>
 | 
			
		||||
        </v-row>
 | 
			
		||||
      </v-col>
 | 
			
		||||
 | 
			
		||||
      <v-col
 | 
			
		||||
        class="mb-5"
 | 
			
		||||
        cols="12"
 | 
			
		||||
      >
 | 
			
		||||
        <h2 class="headline font-weight-bold mb-3">
 | 
			
		||||
          Important Links
 | 
			
		||||
        </h2>
 | 
			
		||||
 | 
			
		||||
        <v-row justify="center">
 | 
			
		||||
          <a
 | 
			
		||||
            v-for="(link, i) in importantLinks"
 | 
			
		||||
            :key="i"
 | 
			
		||||
            :href="link.href"
 | 
			
		||||
            class="subheading mx-3"
 | 
			
		||||
            target="_blank"
 | 
			
		||||
          >
 | 
			
		||||
            {{ link.text }}
 | 
			
		||||
          </a>
 | 
			
		||||
        </v-row>
 | 
			
		||||
      </v-col>
 | 
			
		||||
 | 
			
		||||
      <v-col
 | 
			
		||||
        class="mb-5"
 | 
			
		||||
        cols="12"
 | 
			
		||||
      >
 | 
			
		||||
        <h2 class="headline font-weight-bold mb-3">
 | 
			
		||||
          Ecosystem
 | 
			
		||||
        </h2>
 | 
			
		||||
 | 
			
		||||
        <v-row justify="center">
 | 
			
		||||
          <a
 | 
			
		||||
            v-for="(eco, i) in ecosystem"
 | 
			
		||||
            :key="i"
 | 
			
		||||
            :href="eco.href"
 | 
			
		||||
            class="subheading mx-3"
 | 
			
		||||
            target="_blank"
 | 
			
		||||
          >
 | 
			
		||||
            {{ eco.text }}
 | 
			
		||||
          </a>
 | 
			
		||||
        </v-row>
 | 
			
		||||
      </v-col>
 | 
			
		||||
    </v-row>
 | 
			
		||||
  </v-container>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
  export default {
 | 
			
		||||
    name: 'HelloWorld',
 | 
			
		||||
 | 
			
		||||
    data: () => ({
 | 
			
		||||
      ecosystem: [
 | 
			
		||||
        {
 | 
			
		||||
          text: 'vuetify-loader',
 | 
			
		||||
          href: 'https://github.com/vuetifyjs/vuetify-loader',
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'github',
 | 
			
		||||
          href: 'https://github.com/vuetifyjs/vuetify',
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'awesome-vuetify',
 | 
			
		||||
          href: 'https://github.com/vuetifyjs/awesome-vuetify',
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
      importantLinks: [
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Documentation',
 | 
			
		||||
          href: 'https://vuetifyjs.com',
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Chat',
 | 
			
		||||
          href: 'https://community.vuetifyjs.com',
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Made with Vuetify',
 | 
			
		||||
          href: 'https://madewithvuejs.com/vuetify',
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Twitter',
 | 
			
		||||
          href: 'https://twitter.com/vuetifyjs',
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Articles',
 | 
			
		||||
          href: 'https://medium.com/vuetify',
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
      whatsNext: [
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Explore components',
 | 
			
		||||
          href: 'https://vuetifyjs.com/components/api-explorer',
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Select a layout',
 | 
			
		||||
          href: 'https://vuetifyjs.com/getting-started/pre-made-layouts',
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Frequently Asked Questions',
 | 
			
		||||
          href: 'https://vuetifyjs.com/getting-started/frequently-asked-questions',
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
    }),
 | 
			
		||||
  }
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										35
									
								
								slader-legacy-frontend/src/components/StandardTable.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								slader-legacy-frontend/src/components/StandardTable.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div>
 | 
			
		||||
    <v-row align="center" class="ma-1">
 | 
			
		||||
      <v-btn icon @click="$emit('returnButton')">
 | 
			
		||||
        <v-icon>mdi-arrow-left-circle</v-icon>
 | 
			
		||||
      </v-btn>
 | 
			
		||||
      <v-spacer></v-spacer>
 | 
			
		||||
      <p class="font-weight-medium mb-0">{{ tableTitle }}</p>
 | 
			
		||||
    </v-row>
 | 
			
		||||
    <v-data-table :headers="tableHeaders" :items="tableData" :items-per-page="20"
 | 
			
		||||
                  :footer-props="{'items-per-page-options':[10,20,50,-1],showFirstLastPage:true}">
 | 
			
		||||
      <template #item.action="{item}">
 | 
			
		||||
        <v-btn icon @click="$emit('openRoute',item)">
 | 
			
		||||
          <v-icon>mdi-magnify</v-icon>
 | 
			
		||||
        </v-btn>
 | 
			
		||||
      </template>
 | 
			
		||||
    </v-data-table>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
  name: "StandardTable",
 | 
			
		||||
  emits:['returnButton','openRoute'],
 | 
			
		||||
  props:{
 | 
			
		||||
    tableTitle:String,
 | 
			
		||||
    tableHeaders:Array,
 | 
			
		||||
    tableData:Array,
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped>
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										81
									
								
								slader-legacy-frontend/src/components/TextbookBlock.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								slader-legacy-frontend/src/components/TextbookBlock.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
<template>
 | 
			
		||||
 | 
			
		||||
  <v-card outlined shaped hover height="329">
 | 
			
		||||
    <div @click="openTextbook">
 | 
			
		||||
      <v-img :src="imgSrc" height="210">
 | 
			
		||||
        <template #placeholder>
 | 
			
		||||
          <v-row class="fill-height" align="center" justify="center">
 | 
			
		||||
          <v-progress-circular
 | 
			
		||||
              indeterminate
 | 
			
		||||
              color="primary"
 | 
			
		||||
          ></v-progress-circular>
 | 
			
		||||
          </v-row>
 | 
			
		||||
        </template>
 | 
			
		||||
      </v-img>
 | 
			
		||||
      <v-card-subtitle class="text-truncate subtitle-2">
 | 
			
		||||
        {{ textbookTitleRefined }}
 | 
			
		||||
      </v-card-subtitle>
 | 
			
		||||
    </div>
 | 
			
		||||
    <v-card-actions>
 | 
			
		||||
      <v-btn text @click="showDetails=true">详情</v-btn>
 | 
			
		||||
    </v-card-actions>
 | 
			
		||||
    <v-expand-transition>
 | 
			
		||||
      <v-card
 | 
			
		||||
          v-if="showDetails"
 | 
			
		||||
          class="transition-fast-in-fast-out v-card--reveal"
 | 
			
		||||
      >
 | 
			
		||||
        <v-btn icon class="float-right" @click="showDetails=false">
 | 
			
		||||
          <v-icon>mdi-close</v-icon>
 | 
			
		||||
        </v-btn>
 | 
			
		||||
        <v-card-text class="text--primary" style="clear: both">
 | 
			
		||||
          <p>书名:{{ title }}</p>
 | 
			
		||||
          <p>题数:{{ quantity }}</p>
 | 
			
		||||
        </v-card-text>
 | 
			
		||||
      </v-card>
 | 
			
		||||
    </v-expand-transition>
 | 
			
		||||
  </v-card>
 | 
			
		||||
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import {textbookTitleRefine} from "@/includes"
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: "TextbookBlock",
 | 
			
		||||
  computed: {
 | 
			
		||||
    textbookTitleRefined() {
 | 
			
		||||
      return textbookTitleRefine(this.title)
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.imgSrc = 'https://api.skyju.cc/mobile-acg/api.php?method=get&r=' + Math.random()
 | 
			
		||||
  },
 | 
			
		||||
  props: {
 | 
			
		||||
    title: String,
 | 
			
		||||
    quantity: Number
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      showDetails: false,
 | 
			
		||||
      imgSrc: ''
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    openTextbook() {
 | 
			
		||||
      this.$router.push({name: 'textbook', params: {textbook: this.title}})
 | 
			
		||||
    },
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped>
 | 
			
		||||
 | 
			
		||||
.v-card--reveal {
 | 
			
		||||
  bottom: 0;
 | 
			
		||||
  opacity: 1 !important;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										22
									
								
								slader-legacy-frontend/src/includes.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								slader-legacy-frontend/src/includes.js
									
									
									
									
									
										Normal file
									
								
							@@ -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}
 | 
			
		||||
							
								
								
									
										12
									
								
								slader-legacy-frontend/src/main.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								slader-legacy-frontend/src/main.js
									
									
									
									
									
										Normal file
									
								
							@@ -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')
 | 
			
		||||
							
								
								
									
										8
									
								
								slader-legacy-frontend/src/plugins/vuetify.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								slader-legacy-frontend/src/plugins/vuetify.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import Vuetify from 'vuetify/lib/framework';
 | 
			
		||||
 | 
			
		||||
Vue.use(Vuetify);
 | 
			
		||||
 | 
			
		||||
export default new Vuetify({
 | 
			
		||||
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										41
									
								
								slader-legacy-frontend/src/router/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								slader-legacy-frontend/src/router/index.js
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
							
								
								
									
										5
									
								
								slader-legacy-frontend/src/views/About.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								slader-legacy-frontend/src/views/About.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="about">
 | 
			
		||||
    <h1>This is an about page</h1>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
							
								
								
									
										190
									
								
								slader-legacy-frontend/src/views/Exercise.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								slader-legacy-frontend/src/views/Exercise.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,190 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div>
 | 
			
		||||
    <v-row align="center" class="ma-1">
 | 
			
		||||
      <v-btn icon @click="returnToSection">
 | 
			
		||||
        <v-icon>mdi-arrow-left-circle</v-icon>
 | 
			
		||||
      </v-btn>
 | 
			
		||||
      <v-badge :content="badgeContent"
 | 
			
		||||
               :offset-y="12"
 | 
			
		||||
               :offset-x="15"
 | 
			
		||||
               color="grey"
 | 
			
		||||
      ><p class="font-weight-bold text-h5 mb-0 mx-5">题 {{ exercise }}</p></v-badge>
 | 
			
		||||
    </v-row>
 | 
			
		||||
    <div class="mt-5" v-html="myHtml"></div>
 | 
			
		||||
    <v-btn v-if="hasPreviousExercise" @click="goToExercise(previousExerciseIndex)" fab bottom left icon fixed
 | 
			
		||||
           elevation="2" color="green">
 | 
			
		||||
      <v-icon>mdi-arrow-left</v-icon>
 | 
			
		||||
    </v-btn>
 | 
			
		||||
    <v-btn v-if="hasNextExercise" @click="goToExercise(nextExerciseIndex)" fab bottom right icon fixed elevation="2"
 | 
			
		||||
           color="green">
 | 
			
		||||
      <v-icon>mdi-arrow-right</v-icon>
 | 
			
		||||
    </v-btn>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import {myAxios} from "@/includes"
 | 
			
		||||
import {showServerErrorAlert} from "@/includes"
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: "Exercise",
 | 
			
		||||
  created() {
 | 
			
		||||
    this.getExercise()
 | 
			
		||||
  },
 | 
			
		||||
  watch:{
 | 
			
		||||
    exercise(){
 | 
			
		||||
      console.log('watch exercise trigger')
 | 
			
		||||
      this.getExercise()
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    badgeContent() {
 | 
			
		||||
      return this.section + ' - ' + this.myPage
 | 
			
		||||
    },
 | 
			
		||||
    tableDataIndex() {
 | 
			
		||||
      if (!this.tableData) {
 | 
			
		||||
        return false
 | 
			
		||||
      }
 | 
			
		||||
      return this.tableData.findIndex(single => single.exercise === this.exercise)
 | 
			
		||||
    },
 | 
			
		||||
    hasPreviousExercise(){
 | 
			
		||||
      return this.previousExerciseIndex !== false;
 | 
			
		||||
    },
 | 
			
		||||
    hasNextExercise(){
 | 
			
		||||
      return this.nextExerciseIndex !== false;
 | 
			
		||||
    },
 | 
			
		||||
    previousExerciseIndex() {
 | 
			
		||||
      if (this.tableDataIndex === false || this.tableDataIndex === 0) {
 | 
			
		||||
        return false
 | 
			
		||||
      }
 | 
			
		||||
      return this.tableDataIndex - 1
 | 
			
		||||
    },
 | 
			
		||||
    nextExerciseIndex() {
 | 
			
		||||
      if (this.tableDataIndex === false || this.tableDataIndex === this.tableData.length - 1) {
 | 
			
		||||
        return false
 | 
			
		||||
      }
 | 
			
		||||
      return this.tableDataIndex + 1
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  props: {
 | 
			
		||||
    textbook: String,
 | 
			
		||||
    section: String,
 | 
			
		||||
    exercise: [String, Number],
 | 
			
		||||
    page: Number,
 | 
			
		||||
    part: String,
 | 
			
		||||
    html: String,
 | 
			
		||||
    tableData: Array
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    goToExercise(exerciseIndex) {
 | 
			
		||||
      this.$router.push({name: 'exercise', params: {...this.tableData[exerciseIndex], tableData: this.tableData}})
 | 
			
		||||
    },
 | 
			
		||||
    returnToSection() {
 | 
			
		||||
      this.$router.push({name: 'section', params: {textbook: this.textbook, section: this.section}})
 | 
			
		||||
    },
 | 
			
		||||
    async getExercise() {
 | 
			
		||||
      this.$emit('setCardLoadingStatus', true)
 | 
			
		||||
      console.log('get exercise')
 | 
			
		||||
      if (!this.html) {
 | 
			
		||||
        let resp = await myAxios.get('textbook/' + this.textbook + '/' + encodeURIComponent(this.section) + '/' + this.exercise)
 | 
			
		||||
        if (!resp.data.status) {
 | 
			
		||||
          showServerErrorAlert()
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
        this.myHtml = resp.data.data.html
 | 
			
		||||
        this.myPage = resp.data.data.page
 | 
			
		||||
        this.myPart = resp.data.data.part || 'exercises'
 | 
			
		||||
      } else {
 | 
			
		||||
        this.myHtml = this.html
 | 
			
		||||
        this.myPage = this.page
 | 
			
		||||
        this.myPart = this.part
 | 
			
		||||
      }
 | 
			
		||||
      this.$emit('setCardLoadingStatus', false)
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      myHtml: this.html,
 | 
			
		||||
      myPage: this.page,
 | 
			
		||||
      myPart: this.part
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
.inline-picture-name {
 | 
			
		||||
  margin: 50px 0;
 | 
			
		||||
  border-top: 5px gray solid;
 | 
			
		||||
  padding-top: 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.inline-picture-name img {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  width: 50px;
 | 
			
		||||
  height: 50px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.object-ratings-wrap {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.open-comments {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.row-counter {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  background-color: whitesmoke;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  border-top: black 1px solid;
 | 
			
		||||
  border-bottom: black 1px solid;
 | 
			
		||||
  margin: 5px 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.result-heading {
 | 
			
		||||
  display: block;
 | 
			
		||||
  font-size: 25px;
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.solution-content img {
 | 
			
		||||
  max-width: 90%;
 | 
			
		||||
  border: 1px solid black;
 | 
			
		||||
  display: block;
 | 
			
		||||
  margin: 10px auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.image-reg {
 | 
			
		||||
  display: none !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.unfinished-hover {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.annotations {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.comment-footer {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.center {
 | 
			
		||||
  text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.solution-content p {
 | 
			
		||||
  font-size: 20px;
 | 
			
		||||
  font-family: "Times New Roman", serif;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.Paywall__footer-counter {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.edit-toolbar {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										38
									
								
								slader-legacy-frontend/src/views/Home.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								slader-legacy-frontend/src/views/Home.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <v-row>
 | 
			
		||||
    <v-col v-for="(textbook,index) in textbooks" cols="4" :key="index">
 | 
			
		||||
      <textbook-block v-bind="textbook"></textbook-block>
 | 
			
		||||
    </v-col>
 | 
			
		||||
  </v-row>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import TextbookBlock from "@/components/TextbookBlock"
 | 
			
		||||
import {myAxios} from "@/includes"
 | 
			
		||||
import {showServerErrorAlert} from "@/includes"
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'Home',
 | 
			
		||||
  created() {
 | 
			
		||||
    myAxios.get('textbook').then(resp => {
 | 
			
		||||
      if (resp.data.status) {
 | 
			
		||||
        this.textbooks = resp.data.data
 | 
			
		||||
      }else{
 | 
			
		||||
        showServerErrorAlert()
 | 
			
		||||
      }
 | 
			
		||||
      this.$emit('setCardLoadingStatus',!resp.data.status)
 | 
			
		||||
    }).catch(reason => {
 | 
			
		||||
      showServerErrorAlert()
 | 
			
		||||
      this.$emit('setCardLoadingStatus',true)
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
  components: {
 | 
			
		||||
    TextbookBlock
 | 
			
		||||
  },
 | 
			
		||||
  data(){
 | 
			
		||||
    return {
 | 
			
		||||
      textbooks: []
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										83
									
								
								slader-legacy-frontend/src/views/Section.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								slader-legacy-frontend/src/views/Section.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <standard-table :table-title="section"
 | 
			
		||||
                  :table-headers="tableHeaders"
 | 
			
		||||
                  :table-data="tableData"
 | 
			
		||||
                  @returnButton="returnToTextbook"
 | 
			
		||||
                  @openRoute="openExercise"
 | 
			
		||||
  >
 | 
			
		||||
 | 
			
		||||
  </standard-table>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import StandardTable from "@/components/StandardTable"
 | 
			
		||||
import {myAxios} from '@/includes'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: "Section",
 | 
			
		||||
  components: {StandardTable},
 | 
			
		||||
  computed:{
 | 
			
		||||
    textbookSection(){
 | 
			
		||||
      return this.textbook+this.section
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  watch:{
 | 
			
		||||
    textbookSection(){
 | 
			
		||||
      this.getSection()
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    this.getSection()
 | 
			
		||||
  },
 | 
			
		||||
  props: {
 | 
			
		||||
    textbook: String,
 | 
			
		||||
    section: String
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    returnToTextbook() {
 | 
			
		||||
      this.$router.push({name: 'textbook', params: {textbook: this.textbook}})
 | 
			
		||||
    },
 | 
			
		||||
    openExercise(item) {
 | 
			
		||||
      this.$router.push({
 | 
			
		||||
        name: 'exercise',
 | 
			
		||||
        params: {...item, tableData: this.tableData}
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    getSection() {
 | 
			
		||||
      this.$emit('setCardLoadingStatus', true)
 | 
			
		||||
      console.log('ajax get section')
 | 
			
		||||
      this.tableData = []
 | 
			
		||||
      myAxios.get('textbook/' + this.textbook + '/' + encodeURIComponent(this.section)).then(resp => {
 | 
			
		||||
        if (resp.data.status) {
 | 
			
		||||
          this.tableData = resp.data.data.map((single, index, array) => {
 | 
			
		||||
            let modified = single
 | 
			
		||||
            if (!modified.part) {
 | 
			
		||||
              modified.part = 'exercises'
 | 
			
		||||
            }
 | 
			
		||||
            return modified
 | 
			
		||||
          })
 | 
			
		||||
        }
 | 
			
		||||
        this.$emit('setCardLoadingStatus', !resp.data.status)
 | 
			
		||||
      }).catch(reason => {
 | 
			
		||||
        this.$emit('setCardLoadingStatus', true)
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      tableHeaders: [
 | 
			
		||||
        {text: '题号', value: 'exercise'},
 | 
			
		||||
        {text: 'Section', value: 'section', sortable: false},
 | 
			
		||||
        {text: '类型', value: 'part', sortable: false},
 | 
			
		||||
        {text: '页码', value: 'page'},
 | 
			
		||||
        {text: '操作', value: 'action', sortable: false},
 | 
			
		||||
      ],
 | 
			
		||||
      tableData: []
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped>
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										84
									
								
								slader-legacy-frontend/src/views/Textbook.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								slader-legacy-frontend/src/views/Textbook.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
			
		||||
<template>
 | 
			
		||||
<standard-table :table-title="textbookTitleRefined"
 | 
			
		||||
                :table-headers="tableHeaders"
 | 
			
		||||
                :table-data="tableData"
 | 
			
		||||
                @returnButton="goToHomePage"
 | 
			
		||||
                @openRoute="openSection"
 | 
			
		||||
>
 | 
			
		||||
</standard-table>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import {textbookTitleRefine} from "@/includes"
 | 
			
		||||
import {myAxios} from "@/includes"
 | 
			
		||||
import Swal from "sweetalert2"
 | 
			
		||||
import StandardTable from "@/components/StandardTable"
 | 
			
		||||
import {showServerErrorAlert} from "@/includes"
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: "Textbook",
 | 
			
		||||
  components: {StandardTable},
 | 
			
		||||
  computed: {
 | 
			
		||||
    textbookTitleRefined() {
 | 
			
		||||
      return textbookTitleRefine(this.textbook)
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  watch:{
 | 
			
		||||
    textbook(){
 | 
			
		||||
      this.getTextbook()
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    goToHomePage() {
 | 
			
		||||
      this.$router.push('/')
 | 
			
		||||
    },
 | 
			
		||||
    openSection(item) {
 | 
			
		||||
      this.$router.push({name: 'section', params: {textbook: this.textbook, section: item.section}})
 | 
			
		||||
    },
 | 
			
		||||
    getTextbook(){
 | 
			
		||||
      this.$emit('setCardLoadingStatus', true)
 | 
			
		||||
      this.tableData=[]
 | 
			
		||||
      if (!this.textbook) {
 | 
			
		||||
        Swal.fire({
 | 
			
		||||
          title: '错误',
 | 
			
		||||
          text: '没有指定textbook',
 | 
			
		||||
          icon: 'error'
 | 
			
		||||
        })
 | 
			
		||||
        this.$router.push('/')
 | 
			
		||||
      }
 | 
			
		||||
      myAxios.get('textbook/' + this.textbook).then(resp => {
 | 
			
		||||
        if (resp.data.status) {
 | 
			
		||||
          this.tableData = resp.data.data
 | 
			
		||||
        }else{
 | 
			
		||||
          showServerErrorAlert()
 | 
			
		||||
        }
 | 
			
		||||
        this.$emit('setCardLoadingStatus', !resp.data.status)
 | 
			
		||||
      }).catch(reason => {
 | 
			
		||||
        this.$emit('setCardLoadingStatus', true)
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    this.getTextbook()
 | 
			
		||||
  },
 | 
			
		||||
  props: {
 | 
			
		||||
    textbook: String
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      tableHeaders: [
 | 
			
		||||
        {text: 'Section', value: 'section', sortable: false},
 | 
			
		||||
        {text: '题数', value: 'count'},
 | 
			
		||||
        {text: '页开始', value: 'pageBegin'},
 | 
			
		||||
        {text: '页结束', value: 'pageEnd'},
 | 
			
		||||
        {text: '操作', value: 'action', sortable: false}
 | 
			
		||||
      ],
 | 
			
		||||
      tableData: []
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped>
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										5
									
								
								slader-legacy-frontend/vue.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								slader-legacy-frontend/vue.config.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
module.exports = {
 | 
			
		||||
  transpileDependencies: [
 | 
			
		||||
    'vuetify'
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user