Compare commits
No commits in common. "develop" and "master" have entirely different histories.
|
|
@ -1,23 +0,0 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
69
README.md
69
README.md
|
|
@ -1,68 +1,3 @@
|
|||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
||||
# h5educoder
|
||||
|
||||
## Available Scripts
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### `npm start`
|
||||
|
||||
Runs the app in the development mode.<br />
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
|
||||
|
||||
The page will reload if you make edits.<br />
|
||||
You will also see any lint errors in the console.
|
||||
|
||||
### `npm test`
|
||||
|
||||
Launches the test runner in the interactive watch mode.<br />
|
||||
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
||||
|
||||
### `npm run build`
|
||||
|
||||
Builds the app for production to the `build` folder.<br />
|
||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
||||
|
||||
The build is minified and the filenames include the hashes.<br />
|
||||
Your app is ready to be deployed!
|
||||
|
||||
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
||||
|
||||
### `npm run eject`
|
||||
|
||||
**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
|
||||
|
||||
If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
|
||||
|
||||
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
|
||||
|
||||
You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
|
||||
|
||||
## Learn More
|
||||
|
||||
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
||||
|
||||
To learn React, check out the [React documentation](https://reactjs.org/).
|
||||
|
||||
### Code Splitting
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
|
||||
|
||||
### Analyzing the Bundle Size
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
|
||||
|
||||
### Making a Progressive Web App
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
|
||||
|
||||
### Deployment
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
|
||||
|
||||
### `npm run build` fails to minify
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
|
||||
#小程序项目h5页面开发的仓库
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
const {
|
||||
override,
|
||||
addLessLoader,
|
||||
disableEsLint,
|
||||
addBundleVisualizer,
|
||||
fixBabelImports,
|
||||
} = require("customize-cra");
|
||||
|
||||
|
||||
const UglifyJsPlugin = require("uglifyjs-webpack-plugin")
|
||||
const myPlugin = [
|
||||
new UglifyJsPlugin(
|
||||
{
|
||||
uglifyOptions: {
|
||||
warnings: false,
|
||||
compress: {
|
||||
drop_debugger: true,
|
||||
drop_console: true
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
|
||||
module.exports = override(
|
||||
disableEsLint(),
|
||||
process.env.BUNDLE_VISUALIZE == 1 && addBundleVisualizer(),
|
||||
fixBabelImports('import', {
|
||||
libraryName: 'antd-mobile',
|
||||
style: 'css',
|
||||
}),
|
||||
addLessLoader({
|
||||
strictMath: true,
|
||||
noIeCompat: true
|
||||
}),
|
||||
(config) => {
|
||||
if (process.env.NODE_ENV === "production") config.devtool = false;
|
||||
if (process.env.NODE_ENV !== "development") config.plugins = [...config.plugins, ...myPlugin]
|
||||
if (process.env.NODE_ENV !== "development") {
|
||||
config.output.publicPath = `/h5educoderbuild/`;
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
);
|
||||
File diff suppressed because it is too large
Load Diff
58
package.json
58
package.json
|
|
@ -1,58 +0,0 @@
|
|||
{
|
||||
"name": "h5",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@types/marked": "^3.0.2",
|
||||
"ace-builds": "^1.4.8",
|
||||
"antd-mobile": "^2.3.1",
|
||||
"axios": "^0.19.2",
|
||||
"code-prettify": "^0.1.0",
|
||||
"dompurify": "^2.0.11",
|
||||
"katex": "^0.11.1",
|
||||
"marked": "^1.0.0",
|
||||
"md5": "^2.2.1",
|
||||
"react": "^16.12.0",
|
||||
"react-ace": "^8.1.0",
|
||||
"react-cookie": "^4.0.3",
|
||||
"react-cookies": "^0.1.1",
|
||||
"react-dom": "^16.12.0",
|
||||
"react-router": "^5.1.2",
|
||||
"react-router-dom": "^5.1.2",
|
||||
"js-base64": "2.6.4",
|
||||
"react-scripts": "3.4.0",
|
||||
"typescript": "^3.9.10",
|
||||
"uglifyjs-webpack-plugin": "^2.2.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-app-rewired start",
|
||||
"build": "react-app-rewired build ",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/katex": "^0.11.1",
|
||||
"babel-plugin-import": "^1.13.0",
|
||||
"customize-cra": "^0.5.0",
|
||||
"less": "^3.11.1",
|
||||
"less-loader": "^5.0.0",
|
||||
"react-app-rewired": "^2.1.5",
|
||||
"webpack-bundle-analyzer": "^3.6.0"
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 66 KiB |
|
|
@ -1,34 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta http-equiv="Cache-Control" content="no-siteapp" />
|
||||
<meta name="renderer" content="webkit" />
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
|
||||
<meta name=”Keywords” Content=”EduCoder,信息技术实践教学,精品课程网,慕课MOOC″>
|
||||
<meta name=”Keywords” Content=”实践课程,项目实战,java实训,python实战,人工智能技术,后端开发学习,移动开发入门″>
|
||||
<meta name=”Keywords” Content=”翻转课堂,高效课堂创建,教学模式″>
|
||||
<meta name=”Keywords” Content=”实训项目,python教程,C语言入门,java书,php后端开发,app前端开发,数据库技术″>
|
||||
<meta name=”Keywords” Content=”在线竞赛,计算机应用大赛,编程大赛,大学生计算机设计大赛,全国高校绿色计算机大赛″>
|
||||
<meta name=”Description”
|
||||
Content=”EduCoder是信息技术类实践教学平台。EduCoder涵盖了计算机、大数据、云计算、人工智能、软件工程、物联网等专业课程。超10000个实训案例及22000个技能评测点,建立学、练、评、测一体化实验环境。”>
|
||||
<meta name=”Description”
|
||||
Content=”EduCoder实践课程,旨在于通过企业级实战实训案例,帮助众多程序员提升各项业务能力。解决学生、学员、企业员工等程序设计能力、算法设计能力、问题求解能力、应用开发能力、系统运维能力等。”>
|
||||
<meta name=”Description”
|
||||
Content=”EduCoder翻转课堂教学模式,颠覆了传统教学模式,让教师与学生的关系由“权威”变成了“伙伴”。将学习的主动权转交给学生,使学生可个性化化学,学生的学习主体得到了彰显。”>
|
||||
<meta name=”Description” Content=”EduCoder实训项目为单个知识点关卡实践训练,帮助学生巩固单一弱点,强化学习。 ”>
|
||||
<meta name=”Description” Content=”EduCoder实践教学平台,各类大赛为进一步提高各类学生综合运用高级语言程序设计能力,培养创新意识和实践探索精神,发掘优秀软件人才。 ”>
|
||||
<title>EduCoder</title>
|
||||
<script src="/run_prettify.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.4 KiB |
|
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
!function(){/*
|
||||
|
||||
Copyright (C) 2013 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Copyright (C) 2006 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
(function(){function aa(g){function r(){try{L.doScroll("left")}catch(ba){k.setTimeout(r,50);return}x("poll")}function x(r){if("readystatechange"!=r.type||"complete"==z.readyState)("load"==r.type?k:z)[B](n+r.type,x,!1),!l&&(l=!0)&&g.call(k,r.type||r)}var X=z.addEventListener,l=!1,E=!0,v=X?"addEventListener":"attachEvent",B=X?"removeEventListener":"detachEvent",n=X?"":"on";if("complete"==z.readyState)g.call(k,"lazy");else{if(z.createEventObject&&L.doScroll){try{E=!k.frameElement}catch(ba){}E&&r()}z[v](n+
|
||||
"DOMContentLoaded",x,!1);z[v](n+"readystatechange",x,!1);k[v](n+"load",x,!1)}}function T(){U&&aa(function(){var g=M.length;ca(g?function(){for(var r=0;r<g;++r)(function(g){k.setTimeout(function(){k.exports[M[g]].apply(k,arguments)},0)})(r)}:void 0)})}for(var k=window,z=document,L=z.documentElement,N=z.head||z.getElementsByTagName("head")[0]||L,B="",F=z.getElementsByTagName("script"),l=F.length;0<=--l;){var O=F[l],Y=O.src.match(/^[^?#]*\/run_prettify\.js(\?[^#]*)?(?:#.*)?$/);if(Y){B=Y[1]||"";O.parentNode.removeChild(O);
|
||||
break}}var U=!0,H=[],P=[],M=[];B.replace(/[?&]([^&=]+)=([^&]+)/g,function(g,r,x){x=decodeURIComponent(x);r=decodeURIComponent(r);"autorun"==r?U=!/^[0fn]/i.test(x):"lang"==r?H.push(x):"skin"==r?P.push(x):"callback"==r&&M.push(x)});l=0;for(B=H.length;l<B;++l)(function(){var g=z.createElement("script");g.onload=g.onerror=g.onreadystatechange=function(){!g||g.readyState&&!/loaded|complete/.test(g.readyState)||(g.onerror=g.onload=g.onreadystatechange=null,--S,S||k.setTimeout(T,0),g.parentNode&&g.parentNode.removeChild(g),
|
||||
g=null)};g.type="text/javascript";g.src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/lang-"+encodeURIComponent(H[l])+".js";N.insertBefore(g,N.firstChild)})(H[l]);for(var S=H.length,F=[],l=0,B=P.length;l<B;++l)F.push("https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/skins/"+encodeURIComponent(P[l])+".css");F.push("https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/prettify.css");(function(g){function r(l){if(l!==x){var k=z.createElement("link");k.rel="stylesheet";
|
||||
k.type="text/css";l+1<x&&(k.error=k.onerror=function(){r(l+1)});k.href=g[l];N.appendChild(k)}}var x=g.length;r(0)})(F);var ca=function(){"undefined"!==typeof window&&(window.PR_SHOULD_USE_CONTINUATION=!0);var g;(function(){function r(a){function d(e){var a=e.charCodeAt(0);if(92!==a)return a;var c=e.charAt(1);return(a=k[c])?a:"0"<=c&&"7">=c?parseInt(e.substring(1),8):"u"===c||"x"===c?parseInt(e.substring(2),16):e.charCodeAt(1)}function f(e){if(32>e)return(16>e?"\\x0":"\\x")+e.toString(16);e=String.fromCharCode(e);
|
||||
return"\\"===e||"-"===e||"]"===e||"^"===e?"\\"+e:e}function c(e){var c=e.substring(1,e.length-1).match(RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g"));e=[];var a="^"===c[0],b=["["];a&&b.push("^");for(var a=a?1:0,h=c.length;a<h;++a){var m=c[a];if(/\\[bdsw]/i.test(m))b.push(m);else{var m=d(m),p;a+2<h&&"-"===c[a+1]?(p=d(c[a+2]),a+=2):p=m;e.push([m,p]);65>p||122<m||(65>p||90<m||e.push([Math.max(65,m)|32,Math.min(p,90)|32]),97>p||122<m||
|
||||
e.push([Math.max(97,m)&-33,Math.min(p,122)&-33]))}}e.sort(function(e,a){return e[0]-a[0]||a[1]-e[1]});c=[];h=[];for(a=0;a<e.length;++a)m=e[a],m[0]<=h[1]+1?h[1]=Math.max(h[1],m[1]):c.push(h=m);for(a=0;a<c.length;++a)m=c[a],b.push(f(m[0])),m[1]>m[0]&&(m[1]+1>m[0]&&b.push("-"),b.push(f(m[1])));b.push("]");return b.join("")}function g(e){for(var a=e.source.match(RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)",
|
||||
"g")),b=a.length,d=[],h=0,m=0;h<b;++h){var p=a[h];"("===p?++m:"\\"===p.charAt(0)&&(p=+p.substring(1))&&(p<=m?d[p]=-1:a[h]=f(p))}for(h=1;h<d.length;++h)-1===d[h]&&(d[h]=++r);for(m=h=0;h<b;++h)p=a[h],"("===p?(++m,d[m]||(a[h]="(?:")):"\\"===p.charAt(0)&&(p=+p.substring(1))&&p<=m&&(a[h]="\\"+d[p]);for(h=0;h<b;++h)"^"===a[h]&&"^"!==a[h+1]&&(a[h]="");if(e.ignoreCase&&A)for(h=0;h<b;++h)p=a[h],e=p.charAt(0),2<=p.length&&"["===e?a[h]=c(p):"\\"!==e&&(a[h]=p.replace(/[a-zA-Z]/g,function(a){a=a.charCodeAt(0);
|
||||
return"["+String.fromCharCode(a&-33,a|32)+"]"}));return a.join("")}for(var r=0,A=!1,q=!1,I=0,b=a.length;I<b;++I){var t=a[I];if(t.ignoreCase)q=!0;else if(/[a-z]/i.test(t.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,""))){A=!0;q=!1;break}}for(var k={b:8,t:9,n:10,v:11,f:12,r:13},u=[],I=0,b=a.length;I<b;++I){t=a[I];if(t.global||t.multiline)throw Error(""+t);u.push("(?:"+g(t)+")")}return new RegExp(u.join("|"),q?"gi":"g")}function l(a,d){function f(a){var b=a.nodeType;if(1==b){if(!c.test(a.className)){for(b=
|
||||
a.firstChild;b;b=b.nextSibling)f(b);b=a.nodeName.toLowerCase();if("br"===b||"li"===b)g[q]="\n",A[q<<1]=r++,A[q++<<1|1]=a}}else if(3==b||4==b)b=a.nodeValue,b.length&&(b=d?b.replace(/\r\n?/g,"\n"):b.replace(/[ \t\r\n]+/g," "),g[q]=b,A[q<<1]=r,r+=b.length,A[q++<<1|1]=a)}var c=/(?:^|\s)nocode(?:\s|$)/,g=[],r=0,A=[],q=0;f(a);return{a:g.join("").replace(/\n$/,""),c:A}}function k(a,d,f,c,g){f&&(a={h:a,l:1,j:null,m:null,a:f,c:null,i:d,g:null},c(a),g.push.apply(g,a.g))}function z(a){for(var d=void 0,f=a.firstChild;f;f=
|
||||
f.nextSibling)var c=f.nodeType,d=1===c?d?a:f:3===c?S.test(f.nodeValue)?a:d:d;return d===a?void 0:d}function E(a,d){function f(a){for(var q=a.i,r=a.h,b=[q,"pln"],t=0,A=a.a.match(g)||[],u={},e=0,l=A.length;e<l;++e){var D=A[e],w=u[D],h=void 0,m;if("string"===typeof w)m=!1;else{var p=c[D.charAt(0)];if(p)h=D.match(p[1]),w=p[0];else{for(m=0;m<n;++m)if(p=d[m],h=D.match(p[1])){w=p[0];break}h||(w="pln")}!(m=5<=w.length&&"lang-"===w.substring(0,5))||h&&"string"===typeof h[1]||(m=!1,w="src");m||(u[D]=w)}p=t;
|
||||
t+=D.length;if(m){m=h[1];var C=D.indexOf(m),G=C+m.length;h[2]&&(G=D.length-h[2].length,C=G-m.length);w=w.substring(5);k(r,q+p,D.substring(0,C),f,b);k(r,q+p+C,m,F(w,m),b);k(r,q+p+G,D.substring(G),f,b)}else b.push(q+p,w)}a.g=b}var c={},g;(function(){for(var f=a.concat(d),q=[],k={},b=0,t=f.length;b<t;++b){var n=f[b],u=n[3];if(u)for(var e=u.length;0<=--e;)c[u.charAt(e)]=n;n=n[1];u=""+n;k.hasOwnProperty(u)||(q.push(n),k[u]=null)}q.push(/[\0-\uffff]/);g=r(q)})();var n=d.length;return f}function v(a){var d=
|
||||
[],f=[];a.tripleQuotedStrings?d.push(["str",/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""]):a.multiLineStrings?d.push(["str",/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"]):d.push(["str",/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"]);a.verbatimStrings&&
|
||||
f.push(["str",/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null]);var c=a.hashComments;c&&(a.cStyleComments?(1<c?d.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"]):d.push(["com",/^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"]),f.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,null])):d.push(["com",/^#[^\r\n]*/,null,"#"]));a.cStyleComments&&(f.push(["com",/^\/\/[^\r\n]*/,null]),f.push(["com",/^\/\*[\s\S]*?(?:\*\/|$)/,
|
||||
null]));if(c=a.regexLiterals){var g=(c=1<c?"":"\n\r")?".":"[\\S\\s]";f.push(["lang-regex",RegExp("^(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*("+("/(?=[^/*"+c+"])(?:[^/\\x5B\\x5C"+c+"]|\\x5C"+g+"|\\x5B(?:[^\\x5C\\x5D"+c+"]|\\x5C"+g+")*(?:\\x5D|$))+/")+")")])}(c=a.types)&&f.push(["typ",c]);c=(""+a.keywords).replace(/^ | $/g,"");c.length&&f.push(["kwd",
|
||||
new RegExp("^(?:"+c.replace(/[\s,]+/g,"|")+")\\b"),null]);d.push(["pln",/^\s+/,null," \r\n\t\u00a0"]);c="^.[^\\s\\w.$@'\"`/\\\\]*";a.regexLiterals&&(c+="(?!s*/)");f.push(["lit",/^@[a-z_$][a-z_$@0-9]*/i,null],["typ",/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],["pln",/^[a-z_$][a-z_$@0-9]*/i,null],["lit",/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,null,"0123456789"],["pln",/^\\[\s\S]?/,null],["pun",new RegExp(c),null]);return E(d,f)}function B(a,d,f){function c(a){var b=
|
||||
a.nodeType;if(1==b&&!r.test(a.className))if("br"===a.nodeName.toLowerCase())g(a),a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)c(a);else if((3==b||4==b)&&f){var e=a.nodeValue,d=e.match(n);d&&(b=e.substring(0,d.index),a.nodeValue=b,(e=e.substring(d.index+d[0].length))&&a.parentNode.insertBefore(q.createTextNode(e),a.nextSibling),g(a),b||a.parentNode.removeChild(a))}}function g(a){function c(a,b){var e=b?a.cloneNode(!1):a,p=a.parentNode;if(p){var p=c(p,1),d=a.nextSibling;
|
||||
p.appendChild(e);for(var f=d;f;f=d)d=f.nextSibling,p.appendChild(f)}return e}for(;!a.nextSibling;)if(a=a.parentNode,!a)return;a=c(a.nextSibling,0);for(var e;(e=a.parentNode)&&1===e.nodeType;)a=e;b.push(a)}for(var r=/(?:^|\s)nocode(?:\s|$)/,n=/\r\n?|\n/,q=a.ownerDocument,k=q.createElement("li");a.firstChild;)k.appendChild(a.firstChild);for(var b=[k],t=0;t<b.length;++t)c(b[t]);d===(d|0)&&b[0].setAttribute("value",d);var l=q.createElement("ol");l.className="linenums";d=Math.max(0,d-1|0)||0;for(var t=
|
||||
0,u=b.length;t<u;++t)k=b[t],k.className="L"+(t+d)%10,k.firstChild||k.appendChild(q.createTextNode("\u00a0")),l.appendChild(k);a.appendChild(l)}function n(a,d){for(var f=d.length;0<=--f;){var c=d[f];V.hasOwnProperty(c)?Q.console&&console.warn("cannot override language handler %s",c):V[c]=a}}function F(a,d){a&&V.hasOwnProperty(a)||(a=/^\s*</.test(d)?"default-markup":"default-code");return V[a]}function H(a){var d=a.j;try{var f=l(a.h,a.l),c=f.a;a.a=c;a.c=f.c;a.i=0;F(d,c)(a);var g=/\bMSIE\s(\d+)/.exec(navigator.userAgent),
|
||||
g=g&&8>=+g[1],d=/\n/g,r=a.a,k=r.length,f=0,q=a.c,n=q.length,c=0,b=a.g,t=b.length,v=0;b[t]=k;var u,e;for(e=u=0;e<t;)b[e]!==b[e+2]?(b[u++]=b[e++],b[u++]=b[e++]):e+=2;t=u;for(e=u=0;e<t;){for(var x=b[e],z=b[e+1],w=e+2;w+2<=t&&b[w+1]===z;)w+=2;b[u++]=x;b[u++]=z;e=w}b.length=u;var h=a.h;a="";h&&(a=h.style.display,h.style.display="none");try{for(;c<n;){var m=q[c+2]||k,p=b[v+2]||k,w=Math.min(m,p),C=q[c+1],G;if(1!==C.nodeType&&(G=r.substring(f,w))){g&&(G=G.replace(d,"\r"));C.nodeValue=G;var Z=C.ownerDocument,
|
||||
W=Z.createElement("span");W.className=b[v+1];var B=C.parentNode;B.replaceChild(W,C);W.appendChild(C);f<m&&(q[c+1]=C=Z.createTextNode(r.substring(w,m)),B.insertBefore(C,W.nextSibling))}f=w;f>=m&&(c+=2);f>=p&&(v+=2)}}finally{h&&(h.style.display=a)}}catch(y){Q.console&&console.log(y&&y.stack||y)}}var Q="undefined"!==typeof window?window:{},J=["break,continue,do,else,for,if,return,while"],K=[[J,"auto,case,char,const,default,double,enum,extern,float,goto,inline,int,long,register,restrict,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
|
||||
"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],R=[K,"alignas,alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,delegate,dynamic_cast,explicit,export,friend,generic,late_check,mutable,namespace,noexcept,noreturn,nullptr,property,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],L=[K,"abstract,assert,boolean,byte,extends,finally,final,implements,import,instanceof,interface,null,native,package,strictfp,super,synchronized,throws,transient"],
|
||||
M=[K,"abstract,add,alias,as,ascending,async,await,base,bool,by,byte,checked,decimal,delegate,descending,dynamic,event,finally,fixed,foreach,from,get,global,group,implicit,in,interface,internal,into,is,join,let,lock,null,object,out,override,orderby,params,partial,readonly,ref,remove,sbyte,sealed,select,set,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,value,var,virtual,where,yield"],K=[K,"abstract,async,await,constructor,debugger,enum,eval,export,from,function,get,import,implements,instanceof,interface,let,null,of,set,undefined,var,with,yield,Infinity,NaN"],
|
||||
N=[J,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],O=[J,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],J=[J,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],P=/^(DIR|FILE|array|vector|(de|priority_)?queue|(forward_)?list|stack|(const_)?(reverse_)?iterator|(unordered_)?(multi)?(set|map)|bitset|u?(int|float)\d*)\b/,
|
||||
S=/\S/,T=v({keywords:[R,M,L,K,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",N,O,J],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),V={};n(T,["default-code"]);n(E([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",
|
||||
/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),"default-markup htm html mxml xhtml xml xsl".split(" "));n(E([["pln",/^[\s]+/,null," \t\r\n"],["atv",/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
|
||||
["pun",/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);n(E([],[["atv",/^[\s\S]+/]]),["uq.val"]);n(v({keywords:R,hashComments:!0,cStyleComments:!0,types:P}),"c cc cpp cxx cyc m".split(" "));n(v({keywords:"null,true,false"}),["json"]);n(v({keywords:M,hashComments:!0,cStyleComments:!0,
|
||||
verbatimStrings:!0,types:P}),["cs"]);n(v({keywords:L,cStyleComments:!0}),["java"]);n(v({keywords:J,hashComments:!0,multiLineStrings:!0}),["bash","bsh","csh","sh"]);n(v({keywords:N,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),["cv","py","python"]);n(v({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:2}),
|
||||
["perl","pl","pm"]);n(v({keywords:O,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb","ruby"]);n(v({keywords:K,cStyleComments:!0,regexLiterals:!0}),["javascript","js","ts","typescript"]);n(v({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes",hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);n(E([],[["str",/^[\s\S]+/]]),
|
||||
["regex"]);var U=Q.PR={createSimpleLexer:E,registerLangHandler:n,sourceDecorator:v,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ",prettyPrintOne:function(a,d,f){f=f||!1;d=d||null;var c=document.createElement("div");c.innerHTML="<pre>"+a+"</pre>";c=c.firstChild;f&&B(c,f,!0);H({j:d,m:f,h:c,l:1,a:null,i:null,c:null,g:null});
|
||||
return c.innerHTML},prettyPrint:g=function(a,d){function f(){for(var c=Q.PR_SHOULD_USE_CONTINUATION?b.now()+250:Infinity;t<r.length&&b.now()<c;t++){for(var d=r[t],k=h,n=d;n=n.previousSibling;){var q=n.nodeType,l=(7===q||8===q)&&n.nodeValue;if(l?!/^\??prettify\b/.test(l):3!==q||/\S/.test(n.nodeValue))break;if(l){k={};l.replace(/\b(\w+)=([\w:.%+-]+)/g,function(a,b,c){k[b]=c});break}}n=d.className;if((k!==h||u.test(n))&&!e.test(n)){q=!1;for(l=d.parentNode;l;l=l.parentNode)if(w.test(l.tagName)&&l.className&&
|
||||
u.test(l.className)){q=!0;break}if(!q){d.className+=" prettyprinted";q=k.lang;if(!q){var q=n.match(v),A;!q&&(A=z(d))&&D.test(A.tagName)&&(q=A.className.match(v));q&&(q=q[1])}if(x.test(d.tagName))l=1;else var l=d.currentStyle,y=g.defaultView,l=(l=l?l.whiteSpace:y&&y.getComputedStyle?y.getComputedStyle(d,null).getPropertyValue("white-space"):0)&&"pre"===l.substring(0,3);y=k.linenums;(y="true"===y||+y)||(y=(y=n.match(/\blinenums\b(?::(\d+))?/))?y[1]&&y[1].length?+y[1]:!0:!1);y&&B(d,y,l);H({j:q,h:d,m:y,
|
||||
l:l,a:null,i:null,c:null,g:null})}}}t<r.length?Q.setTimeout(f,250):"function"===typeof a&&a()}for(var c=d||document.body,g=c.ownerDocument||document,c=[c.getElementsByTagName("pre"),c.getElementsByTagName("code"),c.getElementsByTagName("xmp")],r=[],k=0;k<c.length;++k)for(var n=0,l=c[k].length;n<l;++n)r.push(c[k][n]);var c=null,b=Date;b.now||(b={now:function(){return+new Date}});var t=0,v=/\blang(?:uage)?-([\w.]+)(?!\S)/,u=/\bprettyprint\b/,e=/\bprettyprinted\b/,x=/pre|xmp/i,D=/^code$/i,w=/^(?:pre|code|xmp)$/i,
|
||||
h={};f()}},R=Q.define;"function"===typeof R&&R.amd&&R("google-code-prettify",[],function(){return U})})();return g}();S||k.setTimeout(T,0)})();}()
|
||||
37
src/App.js
37
src/App.js
|
|
@ -1,37 +0,0 @@
|
|||
import React, { Suspense, lazy } from 'react'
|
||||
import {
|
||||
BrowserRouter as Router,
|
||||
Route,
|
||||
Switch
|
||||
} from 'react-router-dom'
|
||||
|
||||
import ErrorBoundary from './components/error-boundary'
|
||||
import { initAxiosInterceptors } from './util'
|
||||
|
||||
const TaskPanel = lazy(() => import('./routes/task-panel'))
|
||||
const HackPanel = lazy(() => import('./routes/hack-panel'))
|
||||
const NoticeDetail = lazy(() => import('./routes/notice'))
|
||||
|
||||
initAxiosInterceptors()
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="app">
|
||||
{/* <ErrorBoundary> */}
|
||||
<Router basename="/h5educoderbuild" >
|
||||
<Suspense fallback={<div></div>}>
|
||||
<Switch>
|
||||
<Route path='/educodermd/Notice/:courseid/:infromid/:educoder_session/:autologin_trustie' component={NoticeDetail} />
|
||||
<Route path='/educodermd/hack/:identifier/:educoder_session/:autologin_trustie' component={HackPanel} />
|
||||
<Route path='/educodermd/:identifier/:educoder_session/:autologin_trustie' component={TaskPanel} />
|
||||
|
||||
</Switch>
|
||||
</Suspense>
|
||||
</Router>
|
||||
{/* </ErrorBoundary> */}
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import App from './App';
|
||||
|
||||
test('renders learn react link', () => {
|
||||
const { getByText } = render(<App />);
|
||||
const linkElement = getByText(/learn react/i);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
import React, { useEffect, useRef, useMemo } from 'react'
|
||||
import 'katex/dist/katex.min.css'
|
||||
import marked, { getTocContent, cleanToc, getMathExpressions, resetMathExpressions, lines } from './marked'
|
||||
import 'code-prettify'
|
||||
// import dompurify from 'dompurify'
|
||||
import { renderToString } from 'katex'
|
||||
|
||||
const preRegex = /<pre[^>]*>/g
|
||||
function _unescape(str: string) {
|
||||
let div = document.createElement('div')
|
||||
div.innerHTML = str
|
||||
return div.childNodes.length === 0 ? "" : div.childNodes[0].nodeValue
|
||||
}
|
||||
|
||||
interface IProps {
|
||||
value: string
|
||||
className?: string
|
||||
style?: any,
|
||||
showLines?: number,
|
||||
showTextOnly?: boolean
|
||||
}
|
||||
|
||||
export default ({
|
||||
value = '',
|
||||
className,
|
||||
showTextOnly,
|
||||
showLines,
|
||||
style = {},
|
||||
}: IProps) => {
|
||||
let str = String(value);
|
||||
|
||||
const html = useMemo(() => {
|
||||
// let proxy = "http://test-data.educoder.net"
|
||||
let proxy='https://data.educoder.net'
|
||||
console.log("str:", str)
|
||||
try {
|
||||
const reg = /\(\s+\/api\/attachments\/|\(\/api\/attachments\/|\(\/attachments\/download\//g;
|
||||
const reg2 = /\"\/api\/attachments\/|\"\/attachments\/download\//g;
|
||||
const reg3 = /\(\s+\/files\/uploads\/|\(\/files\/uploads\//g;
|
||||
str = str.replace(reg, "(" + proxy + "/api/attachments/")
|
||||
.replace(reg2, '"' + proxy+ "/api/attachments/")
|
||||
.replace(reg3, '"' + proxy + "/files/uploads/")
|
||||
|
||||
} catch (e) { };
|
||||
let rs = marked(str)
|
||||
console.log("rs:", rs)
|
||||
|
||||
const math_expressions:any = getMathExpressions()
|
||||
if (str.match(/\[TOC\]/)) {
|
||||
rs = rs.replace("<p>[TOC]</p>", getTocContent())
|
||||
cleanToc()
|
||||
}
|
||||
rs = rs.replace(/(__special_katext_id_\d+__)/g, (_match: any, capture: string | number) => {
|
||||
const { type, expression } = math_expressions[capture]
|
||||
return renderToString(_unescape(expression) || '', { displayMode: type === 'block', throwOnError: false, output: 'html' })
|
||||
})
|
||||
|
||||
rs = rs.replace(/▁/g, "▁▁▁")
|
||||
resetMathExpressions()
|
||||
// return dompurify.sanitize(rs)
|
||||
if (showTextOnly) {
|
||||
const dom = document.createElement("div")
|
||||
dom.innerHTML = rs
|
||||
return dom.innerText;
|
||||
}
|
||||
return rs;
|
||||
|
||||
}, [str])
|
||||
|
||||
const el = useRef<HTMLDivElement>()
|
||||
lines["WebkitLineClamp"] = showLines;
|
||||
if(showLines){
|
||||
style = {...style,...lines}
|
||||
};
|
||||
|
||||
function onAncherHandler(e: any) {
|
||||
let target = e.target
|
||||
if (target.tagName.toUpperCase() === 'A') {
|
||||
let ancher = target.getAttribute('href')
|
||||
if (ancher.startsWith('#')) {
|
||||
e.preventDefault()
|
||||
let viewEl = document.getElementById(ancher.replace('#', ''))
|
||||
if (viewEl) {
|
||||
viewEl.scrollIntoView(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (el.current && html) {
|
||||
if (html.match(preRegex)) {
|
||||
(window as any).PR.prettyPrint()
|
||||
}
|
||||
}
|
||||
if (el.current) {
|
||||
el.current.addEventListener('click', onAncherHandler)
|
||||
return () => {
|
||||
el.current.removeEventListener('click', onAncherHandler)
|
||||
resetMathExpressions()
|
||||
cleanToc()
|
||||
}
|
||||
}
|
||||
}, [html, el.current, onAncherHandler])
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
ref={el}
|
||||
style={{...style}}
|
||||
className={`${className ? className : ''} markdown-body`}
|
||||
dangerouslySetInnerHTML={{ __html: html }}
|
||||
></div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,181 +0,0 @@
|
|||
import marked from 'marked'
|
||||
import { escape } from 'marked/src/helpers'
|
||||
|
||||
function indentCodeCompensation(raw, text) {
|
||||
const matchIndentToCode = raw.match(/^(\s+)(?:```)/)
|
||||
if (matchIndentToCode === null) {
|
||||
return text
|
||||
}
|
||||
const indentToCode = matchIndentToCode[1]
|
||||
return text
|
||||
.split('\n')
|
||||
.map(node => {
|
||||
|
||||
|
||||
const matchIndentInNode = node.match(/^\s+/)
|
||||
if (matchIndentInNode === null) {
|
||||
return node
|
||||
}
|
||||
const [indentInNode] = matchIndentInNode
|
||||
if (indentInNode.length >= indentToCode.length) {
|
||||
return node.slice(indentToCode.length)
|
||||
}
|
||||
return node
|
||||
})
|
||||
.join('\n')
|
||||
}
|
||||
// interface IToc {
|
||||
// anchor: string
|
||||
// level: number
|
||||
// text: string
|
||||
// }
|
||||
//兼容之前的 ##标题式写法
|
||||
let toc = []
|
||||
let ctx= ["<ul>"]
|
||||
const renderer = new marked.Renderer()
|
||||
const headingRegex = /^ *(#{1,6}) *([^\n]+?) *(?:#+ *)?(?:\n+|$)/
|
||||
|
||||
export function cleanToc() {
|
||||
toc.length = 0
|
||||
ctx = ["<ul>"]
|
||||
}
|
||||
|
||||
export const lines = {
|
||||
overflow: "hidden",
|
||||
WebkitBoxOrient: "vertical",
|
||||
display: "-webkit-box",
|
||||
WebkitLineClamp:2,
|
||||
}
|
||||
|
||||
function buildToc(coll, k, level, ctx) {
|
||||
if (k >= coll.length || coll[k].level <= level) { return k }
|
||||
var node = coll[k]
|
||||
ctx.push("<li><a href='#" + node.anchor + "'>" + node.text + "</a>")
|
||||
k++
|
||||
var childCtx = []
|
||||
k = buildToc(coll, k, node.level, childCtx)
|
||||
if (childCtx.length > 0) {
|
||||
ctx.push("<ul>")
|
||||
childCtx.forEach(function (idm) {
|
||||
ctx.push(idm)
|
||||
})
|
||||
ctx.push("</ul>")
|
||||
}
|
||||
ctx.push("</li>")
|
||||
k = buildToc(coll, k, level, ctx)
|
||||
return k
|
||||
}
|
||||
|
||||
export function getTocContent() {
|
||||
buildToc(toc, 0, 0, ctx)
|
||||
ctx.push("</ul>")
|
||||
return ctx.join("")
|
||||
}
|
||||
|
||||
const tokenizer = {
|
||||
heading(src) {
|
||||
const cap = headingRegex.exec(src)
|
||||
if (cap) {
|
||||
return {
|
||||
type: 'heading',
|
||||
raw: cap[0],
|
||||
depth: cap[1].length,
|
||||
text: cap[2]
|
||||
}
|
||||
}
|
||||
},
|
||||
fences(src) {
|
||||
const cap = this.rules.block.fences.exec(src)
|
||||
if (cap) {
|
||||
const raw = cap[0]
|
||||
let text = indentCodeCompensation(raw, cap[3] || '')
|
||||
const lang = cap[2] ? cap[2].trim() : cap[2]
|
||||
if (['latex', 'katex', 'math'].indexOf(lang) >= 0) {
|
||||
const id = next_id()
|
||||
const expression = text
|
||||
text = id
|
||||
math_expressions[id] = { type: 'block', expression }
|
||||
}
|
||||
return {
|
||||
type: 'code',
|
||||
raw,
|
||||
lang,
|
||||
text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const latexRegex = /(?:\${2})([^\n`]+?)(?:\${2})/gi
|
||||
let katex_count = 0
|
||||
const next_id = () => `__special_katext_id_${katex_count++}__`
|
||||
let math_expressions = {}
|
||||
|
||||
export function getMathExpressions() {
|
||||
return math_expressions
|
||||
}
|
||||
|
||||
export function resetMathExpressions() {
|
||||
katex_count = 0
|
||||
math_expressions = {}
|
||||
}
|
||||
|
||||
function replace_math_with_ids(text) {
|
||||
text = text.replace(latexRegex, (_match, expression) => {
|
||||
const id = next_id()
|
||||
math_expressions[id] = { type: 'inline', expression }
|
||||
return id
|
||||
})
|
||||
return text
|
||||
}
|
||||
|
||||
const original_listitem = renderer.listitem
|
||||
renderer.listitem = function (text) {
|
||||
return original_listitem(replace_math_with_ids(text))
|
||||
}
|
||||
|
||||
const original_paragraph = renderer.paragraph
|
||||
renderer.paragraph = function (text) {
|
||||
return original_paragraph(replace_math_with_ids(text))
|
||||
}
|
||||
|
||||
const original_tablecell = renderer.tablecell
|
||||
renderer.tablecell = function (content, flags) {
|
||||
return original_tablecell(replace_math_with_ids(content), flags)
|
||||
}
|
||||
|
||||
renderer.code = function (code, infostring, escaped) {
|
||||
const lang = (infostring || '').match(/\S*/)[0]
|
||||
if (!lang) {
|
||||
return '<pre class="prettyprint linenums"><code>'
|
||||
+ (escaped ? code : escape(code, true))
|
||||
+ '</code></pre>'
|
||||
}
|
||||
|
||||
if (['latex', 'katex', 'math'].indexOf(lang) >= 0) {
|
||||
return `<p class='editormd-tex'>${code}</p>`
|
||||
} else {
|
||||
return `<pre class="prettyprint linenums"><code class="language-${infostring}">${escaped ? code : escape(code, true)}</code></pre>\n`
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
renderer.heading = function (text, level, raw) {
|
||||
let anchor = this.options.headerPrefix + raw.toLowerCase().replace(/[^\w\\u4e00-\\u9fa5]]+/g, '-')
|
||||
toc.push({
|
||||
anchor,
|
||||
level,
|
||||
text
|
||||
})
|
||||
return '<h' + level + ' id="' + anchor + '">' + text + '</h' + level + '>'
|
||||
}
|
||||
|
||||
marked.setOptions({
|
||||
silent: true,
|
||||
gfm: true,
|
||||
pedantic: false
|
||||
})
|
||||
|
||||
marked.use({ tokenizer, renderer })
|
||||
|
||||
export default marked
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import React from 'react'
|
||||
export default class ErrorBoundary extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = { hasError: false }
|
||||
}
|
||||
|
||||
static getDerivedStateFromError(error) {
|
||||
// Update state so the next render will show the fallback UI.
|
||||
return { hasError: true }
|
||||
}
|
||||
|
||||
componentDidCatch(error, errorInfo) {
|
||||
// You can also log the error to an error reporting service
|
||||
console.log(error, errorInfo)
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
// You can render any custom fallback UI
|
||||
return <h1>Something went wrong.</h1>
|
||||
}
|
||||
|
||||
return this.props.children
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
import React from 'react'
|
||||
import './img-preview.less'
|
||||
|
||||
export default ({ url, onCancel }) => {
|
||||
return (
|
||||
<div className="img-preview-wrapper" onClick={onCancel}>
|
||||
<img src={url} alt='大图预览' />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
.img-preview-wrapper {
|
||||
position: fixed;
|
||||
z-index: 204;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: rgba(0, 0, 0, .7);
|
||||
|
||||
img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
.loading-tip {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
background: #213857;
|
||||
color: #fff;
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
import React from 'react'
|
||||
import './loading.css'
|
||||
|
||||
export default () => {
|
||||
return <div className="loading-tip">
|
||||
<p>loading ...</p>
|
||||
</div>
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
import React from 'react'
|
||||
import { createPortal } from 'react-dom'
|
||||
|
||||
export default class Dialog extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
const doc = window.document
|
||||
this.node = doc.createElement('div')
|
||||
doc.body.appendChild(this.node)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children } = this.props
|
||||
return createPortal(children, this.node)
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.document.body.removeChild(this.node);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
import React, { useEffect, useRef } from 'react'
|
||||
import 'katex/dist/katex.min.css';
|
||||
|
||||
import marked, { getTocContent, cleanToc } from '../util/marked'
|
||||
|
||||
let preRegex = /<pre[^>]*>/g
|
||||
|
||||
export default ({ value = '', is_md = true, className, style = {} }) => {
|
||||
let str = String(value)
|
||||
let html = is_md ? marked(str) : value
|
||||
if (str.match(/\[TOC\]/)) {
|
||||
html = html.replace("<p>[TOC]</p>", getTocContent())
|
||||
cleanToc()
|
||||
}
|
||||
|
||||
html = html.replace(/▁/g, "▁▁▁")
|
||||
const el = useRef()
|
||||
|
||||
function onAncherHandler(e) {
|
||||
let target = e.target
|
||||
if (target.tagName.toUpperCase() === 'A') {
|
||||
let ancher = target.getAttribute('href')
|
||||
if (ancher.startsWith('#')) {
|
||||
e.preventDefault()
|
||||
let viewEl = document.getElementById(ancher.replace('#', ''))
|
||||
if (viewEl) {
|
||||
viewEl.parentNode.scrollTop = viewEl.offsetTop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (el.current && html) {
|
||||
if (html.match(preRegex)) {
|
||||
window.PR.prettyPrint()
|
||||
}
|
||||
}
|
||||
if (el.current) {
|
||||
el.current.addEventListener('click', onAncherHandler)
|
||||
return () => {
|
||||
el.current.removeEventListener('click', onAncherHandler)
|
||||
}
|
||||
}
|
||||
}, [html, el.current, onAncherHandler])
|
||||
|
||||
return (<div ref={el} style={style} className={`${className ? className : ''} markdown-body`} dangerouslySetInnerHTML={{ __html: html }}></div>)
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
import React, { useEffect, useState, useRef } from 'react'
|
||||
import mediator from '../../util/mediator'
|
||||
|
||||
function padLeft(s) {
|
||||
return s.toString().padStart(2, '0')
|
||||
}
|
||||
function getTimer(sec) {
|
||||
const minuts = Math.floor(sec / 60)
|
||||
const second = sec % 60
|
||||
const hour = Math.floor(minuts / 60)
|
||||
return `${padLeft(hour)}:${padLeft(minuts - hour * 60)}:${padLeft(second)}`
|
||||
}
|
||||
|
||||
//评测计时
|
||||
//identifier taskId
|
||||
export default ({ identifier, onUpdateCostTime, status, defaultTime = 0,type }) => {
|
||||
|
||||
const [costTime, setCostTime] = useState(defaultTime)
|
||||
const lastV = useRef(defaultTime)
|
||||
|
||||
useEffect(() => {
|
||||
lastV.current = defaultTime
|
||||
setCostTime(defaultTime)
|
||||
//已经评测完成的不需要再计时
|
||||
|
||||
if (status !== 2) {
|
||||
let timeHandler = function () {
|
||||
setCostTime(costTime => costTime + 1)
|
||||
lastV.current = lastV.current + 1
|
||||
}
|
||||
let tid = window.setInterval(timeHandler, 1000)
|
||||
let unSub = mediator.subscribe('update-cost-time', () => {
|
||||
onUpdateCostTime(identifier, { time: lastV.current }).then(() => {
|
||||
mediator.publish('reset-game')
|
||||
})
|
||||
})
|
||||
return () => {
|
||||
clearInterval(tid)
|
||||
unSub()
|
||||
|
||||
|
||||
if(type===1){
|
||||
let bodys = {
|
||||
answer_long_time: lastV.current*1000,
|
||||
};
|
||||
let headers = {
|
||||
type: 'application/json',
|
||||
};
|
||||
let blob = new Blob([JSON.stringify(bodys)], headers);
|
||||
window.navigator.sendBeacon(
|
||||
`https://data.educoder.net/api/myproblems/${identifier}/save_long_time.json?answer_long_time=${lastV.current*1000}`,
|
||||
blob,
|
||||
);
|
||||
mediator.publish('reset-game')
|
||||
return
|
||||
}
|
||||
onUpdateCostTime(identifier, { time: lastV.current }).then(() => {
|
||||
mediator.publish('reset-game')
|
||||
})
|
||||
}
|
||||
}
|
||||
}, [identifier, onUpdateCostTime, status, defaultTime])
|
||||
|
||||
|
||||
return (
|
||||
<span>{getTimer(costTime)}</span>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
import React, { useEffect, useRef } from 'react';
|
||||
|
||||
export default function useInterval(callback, delay) {
|
||||
const savedCallback = useRef();
|
||||
|
||||
// 保存新回调
|
||||
useEffect(() => {
|
||||
savedCallback.current = callback;
|
||||
});
|
||||
|
||||
// 建立 interval
|
||||
useEffect(() => {
|
||||
function tick() {
|
||||
savedCallback.current();
|
||||
}
|
||||
if (delay !== null) {
|
||||
let id = setInterval(tick, delay);
|
||||
return () => clearInterval(id);
|
||||
}
|
||||
}, [delay]);
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
import React, { useRef, useEffect } from 'react'
|
||||
|
||||
export default ({ onLeft, onRight, children, cls }) => {
|
||||
const ref = useRef()
|
||||
const width = document.documentElement.clientWidth || document.body.clientWidth
|
||||
let startX
|
||||
, startY
|
||||
, distX
|
||||
, distY
|
||||
, threshold = width / 2
|
||||
, elapsedTime
|
||||
, startTime
|
||||
, quickTime = 320
|
||||
|
||||
function ontouchstart(e) {
|
||||
let obj = e.changedTouches[0]
|
||||
startX = obj.pageX
|
||||
startY = obj.pageY
|
||||
startTime = new Date().getTime()
|
||||
}
|
||||
function ontouchend(e) {
|
||||
let obj = e.changedTouches[0]
|
||||
distY = obj.pageY - startY
|
||||
distX = obj.pageX - startX
|
||||
elapsedTime = new Date().getTime() - startTime
|
||||
if ((Math.abs(distX) > threshold || elapsedTime <= quickTime) && Math.abs(distX) > Math.abs(distY)) {
|
||||
if (distX < 0) {
|
||||
if (onLeft) {
|
||||
onLeft()
|
||||
}
|
||||
} else {
|
||||
if (onRight) {
|
||||
onRight()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
let el = ref.current
|
||||
if (el) {
|
||||
el.addEventListener("touchstart", ontouchstart)
|
||||
el.addEventListener("touchend", ontouchend)
|
||||
}
|
||||
return () => {
|
||||
el.removeEventListener('touchstart', ontouchstart)
|
||||
el.removeEventListener('touchend', ontouchend)
|
||||
}
|
||||
}, [ref.current, ontouchstart, ontouchend])
|
||||
|
||||
|
||||
return (
|
||||
<div ref={ref} className={cls} style={{ width: '100%', height: '100%' }}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
329
src/iconfont.css
329
src/iconfont.css
File diff suppressed because one or more lines are too long
593
src/index.css
593
src/index.css
|
|
@ -1,593 +0,0 @@
|
|||
*,
|
||||
*:before,
|
||||
*:after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
font-family: sans-serif;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.ant-popover-buttons {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
#root,
|
||||
.app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
p,
|
||||
h2,
|
||||
h3,
|
||||
h4 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
|
||||
.markdown-body ul,
|
||||
.mardown-body ol {
|
||||
list-style-type: decimal !important;
|
||||
}
|
||||
|
||||
.markdown-body p {
|
||||
font-size: 16px;
|
||||
line-height: 25px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.markdown-body hr:after,
|
||||
.markdown-body hr:before {
|
||||
content: "";
|
||||
display: table
|
||||
}
|
||||
|
||||
/*! github-markdown-css | The MIT License (MIT) | Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com) | https://github.com/sindresorhus/github-markdown-css */
|
||||
@font-face {
|
||||
font-family: octicons-anchor;
|
||||
src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==)format("woff")
|
||||
}
|
||||
|
||||
.markdown-body {
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
color: #333;
|
||||
overflow: hidden;
|
||||
font-family: "微软雅黑", "Microsoft YaHei", Helvetica, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Monaco, monospace, Tahoma, STXihei, "华文细黑", STHeiti, "Helvetica Neue", "Droid Sans", "wenquanyi micro hei", FreeSans, Arimo, Arial, SimSun, "宋体", Heiti, "黑体", sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
word-wrap: break-word
|
||||
}
|
||||
|
||||
.markdown-body strong {
|
||||
font-weight: 700
|
||||
}
|
||||
|
||||
.markdown-body h1 {
|
||||
margin: .67em 0
|
||||
}
|
||||
|
||||
.markdown-body img {
|
||||
border: 0
|
||||
}
|
||||
|
||||
.markdown-body hr {
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
height: 0
|
||||
}
|
||||
|
||||
.markdown-body input {
|
||||
color: inherit;
|
||||
margin: 0;
|
||||
line-height: normal;
|
||||
font: 13px/1.4 Helvetica, arial, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"
|
||||
}
|
||||
|
||||
.markdown-body html input[disabled] {
|
||||
cursor: default
|
||||
}
|
||||
|
||||
.markdown-body input[type=checkbox] {
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
padding: 0
|
||||
}
|
||||
|
||||
.markdown-body * {
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box
|
||||
}
|
||||
|
||||
.markdown-body a {
|
||||
background: 0 0;
|
||||
color: #4183c4 !important;
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
.markdown-body a:active,
|
||||
.markdown-body a:hover {
|
||||
outline: 0;
|
||||
text-decoration: underline
|
||||
}
|
||||
|
||||
.markdown-body hr {
|
||||
margin: 15px 0;
|
||||
overflow: hidden;
|
||||
background: 0 0;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #ddd
|
||||
}
|
||||
|
||||
.markdown-body h1,
|
||||
.markdown-body h2 {
|
||||
padding-bottom: .3em;
|
||||
border-bottom: 1px solid #eee
|
||||
}
|
||||
|
||||
.markdown-body blockquote {
|
||||
margin: 0
|
||||
}
|
||||
|
||||
.markdown-body ol ol,
|
||||
.markdown-body ul ol {
|
||||
list-style-type: lower-roman
|
||||
}
|
||||
|
||||
.markdown-body ol ol ol,
|
||||
.markdown-body ol ul ol,
|
||||
.markdown-body ul ol ol,
|
||||
.markdown-body ul ul ol {
|
||||
list-style-type: lower-alpha
|
||||
}
|
||||
|
||||
.markdown-body dd {
|
||||
margin-left: 0
|
||||
}
|
||||
|
||||
.markdown-body code {
|
||||
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace
|
||||
}
|
||||
|
||||
.markdown-body pre {
|
||||
font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
word-wrap: normal
|
||||
}
|
||||
|
||||
.markdown-body .octicon {
|
||||
font: normal normal 16px octicons-anchor;
|
||||
line-height: 1;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
user-select: none
|
||||
}
|
||||
|
||||
.markdown-body .octicon-link:before {
|
||||
content: '\f05c'
|
||||
}
|
||||
|
||||
.markdown-body>:first-child {
|
||||
margin-top: 0 !important
|
||||
}
|
||||
|
||||
.markdown-body>:last-child {
|
||||
margin-bottom: 0 !important
|
||||
}
|
||||
|
||||
.markdown-body .anchor {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: block;
|
||||
padding-right: 6px;
|
||||
padding-left: 30px;
|
||||
margin-left: -30px
|
||||
}
|
||||
|
||||
.markdown-body .anchor:focus {
|
||||
outline: 0
|
||||
}
|
||||
|
||||
.markdown-body h1,
|
||||
.markdown-body h2,
|
||||
.markdown-body h3,
|
||||
.markdown-body h4,
|
||||
.markdown-body h5,
|
||||
.markdown-body h6 {
|
||||
position: relative;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 16px;
|
||||
font-weight: 700;
|
||||
line-height: 1.4
|
||||
}
|
||||
|
||||
.markdown-body h1 .octicon-link,
|
||||
.markdown-body h2 .octicon-link,
|
||||
.markdown-body h3 .octicon-link,
|
||||
.markdown-body h4 .octicon-link,
|
||||
.markdown-body h5 .octicon-link,
|
||||
.markdown-body h6 .octicon-link {
|
||||
display: none;
|
||||
color: #000;
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
.markdown-body h1:hover .anchor,
|
||||
.markdown-body h2:hover .anchor,
|
||||
.markdown-body h3:hover .anchor,
|
||||
.markdown-body h4:hover .anchor,
|
||||
.markdown-body h5:hover .anchor,
|
||||
.markdown-body h6:hover .anchor {
|
||||
padding-left: 8px;
|
||||
margin-left: -30px;
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
.markdown-body h1:hover .anchor .octicon-link,
|
||||
.markdown-body h2:hover .anchor .octicon-link,
|
||||
.markdown-body h3:hover .anchor .octicon-link,
|
||||
.markdown-body h4:hover .anchor .octicon-link,
|
||||
.markdown-body h5:hover .anchor .octicon-link,
|
||||
.markdown-body h6:hover .anchor .octicon-link {
|
||||
display: inline-block
|
||||
}
|
||||
|
||||
.markdown-body h1 {
|
||||
font-size: 2.25em;
|
||||
line-height: 1.2
|
||||
}
|
||||
|
||||
.markdown-body h1 .anchor {
|
||||
line-height: 1
|
||||
}
|
||||
|
||||
.markdown-body h2 {
|
||||
font-size: 1.75em;
|
||||
line-height: 1.225
|
||||
}
|
||||
|
||||
.markdown-body h2 .anchor {
|
||||
line-height: 1
|
||||
}
|
||||
|
||||
.markdown-body h3 {
|
||||
font-size: 1.5em;
|
||||
line-height: 1.43
|
||||
}
|
||||
|
||||
.markdown-body h3 .anchor,
|
||||
.markdown-body h4 .anchor {
|
||||
line-height: 1.2
|
||||
}
|
||||
|
||||
.markdown-body h4 {
|
||||
font-size: 1.25em
|
||||
}
|
||||
|
||||
.markdown-body h5 .anchor,
|
||||
.markdown-body h6 .anchor {
|
||||
line-height: 1.1
|
||||
}
|
||||
|
||||
.markdown-body h5 {
|
||||
font-size: 1em
|
||||
}
|
||||
|
||||
.markdown-body h6 {
|
||||
font-size: 1em;
|
||||
color: #777
|
||||
}
|
||||
|
||||
.markdown-body blockquote,
|
||||
.markdown-body dl,
|
||||
.markdown-body ol,
|
||||
.markdown-body p,
|
||||
.markdown-body pre,
|
||||
.markdown-body table,
|
||||
.markdown-body ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px
|
||||
}
|
||||
|
||||
.markdown-body ol,
|
||||
.markdown-body ul {
|
||||
padding-left: 2em
|
||||
}
|
||||
|
||||
.markdown-body ol ol,
|
||||
.markdown-body ol ul,
|
||||
.markdown-body ul ol,
|
||||
.markdown-body ul ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0
|
||||
}
|
||||
|
||||
.markdown-body li>p {
|
||||
margin-top: 16px
|
||||
}
|
||||
|
||||
.markdown-body dl {
|
||||
padding: 0
|
||||
}
|
||||
|
||||
.markdown-body dl dt {
|
||||
padding: 0;
|
||||
margin-top: 16px;
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
font-weight: 700
|
||||
}
|
||||
|
||||
.markdown-body dl dd {
|
||||
padding: 0 16px;
|
||||
margin-bottom: 16px
|
||||
}
|
||||
|
||||
.markdown-body blockquote {
|
||||
padding: 0 15px;
|
||||
color: #777;
|
||||
border-left: 4px solid #ddd
|
||||
}
|
||||
|
||||
.markdown-body blockquote>:first-child {
|
||||
margin-top: 0
|
||||
}
|
||||
|
||||
.markdown-body blockquote>:last-child {
|
||||
margin-bottom: 0
|
||||
}
|
||||
|
||||
.markdown-body table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
word-break: normal;
|
||||
word-break: keep-all
|
||||
}
|
||||
|
||||
.markdown-body table th {
|
||||
font-weight: 700
|
||||
}
|
||||
|
||||
.markdown-body table td,
|
||||
.markdown-body table th {
|
||||
padding: 6px 13px;
|
||||
border: 1px solid #ddd
|
||||
}
|
||||
|
||||
.markdown-body table tr {
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #ccc
|
||||
}
|
||||
|
||||
.markdown-body table tr:nth-child(2n) {
|
||||
background-color: #f8f8f8
|
||||
}
|
||||
|
||||
.markdown-body img {
|
||||
max-width: 100%;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box
|
||||
}
|
||||
|
||||
.markdown-body code {
|
||||
padding: .2em 0;
|
||||
margin: 0;
|
||||
font-size: 85%;
|
||||
background-color: rgba(0, 0, 0, .04);
|
||||
border-radius: 3px
|
||||
}
|
||||
|
||||
.markdown-body code:after,
|
||||
.markdown-body code:before {
|
||||
letter-spacing: -.2em;
|
||||
content: "\00a0"
|
||||
}
|
||||
|
||||
.markdown-body pre>code {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 100%;
|
||||
word-break: normal;
|
||||
white-space: pre;
|
||||
background: 0 0;
|
||||
border: 0
|
||||
}
|
||||
|
||||
.markdown-body .highlight {
|
||||
margin-bottom: 16px
|
||||
}
|
||||
|
||||
.markdown-body .highlight pre,
|
||||
.markdown-body pre {
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
font-size: 85%;
|
||||
background-color: #f7f7f7;
|
||||
border-radius: 3px
|
||||
}
|
||||
|
||||
.markdown-body .highlight pre {
|
||||
margin-bottom: 0;
|
||||
word-break: normal
|
||||
}
|
||||
|
||||
.markdown-body pre code {
|
||||
display: inline;
|
||||
max-width: initial;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: initial;
|
||||
line-height: inherit;
|
||||
word-wrap: normal;
|
||||
background-color: transparent;
|
||||
border: 0
|
||||
}
|
||||
|
||||
.markdown-body pre code:after,
|
||||
.markdown-body pre code:before {
|
||||
content: normal
|
||||
}
|
||||
|
||||
.markdown-body .pl-c {
|
||||
color: #969896
|
||||
}
|
||||
|
||||
.markdown-body .pl-c1,
|
||||
.markdown-body .pl-mdh,
|
||||
.markdown-body .pl-mm,
|
||||
.markdown-body .pl-mp,
|
||||
.markdown-body .pl-mr,
|
||||
.markdown-body .pl-s1 .pl-v,
|
||||
.markdown-body .pl-s3,
|
||||
.markdown-body .pl-sc,
|
||||
.markdown-body .pl-sv {
|
||||
color: #0086b3
|
||||
}
|
||||
|
||||
.markdown-body .pl-e,
|
||||
.markdown-body .pl-en {
|
||||
color: #795da3
|
||||
}
|
||||
|
||||
.markdown-body .pl-s1 .pl-s2,
|
||||
.markdown-body .pl-smi,
|
||||
.markdown-body .pl-smp,
|
||||
.markdown-body .pl-stj,
|
||||
.markdown-body .pl-vo,
|
||||
.markdown-body .pl-vpf {
|
||||
color: #333
|
||||
}
|
||||
|
||||
.markdown-body .pl-ent {
|
||||
color: #63a35c
|
||||
}
|
||||
|
||||
.markdown-body .pl-k,
|
||||
.markdown-body .pl-s,
|
||||
.markdown-body .pl-st {
|
||||
color: #a71d5d
|
||||
}
|
||||
|
||||
.markdown-body .pl-pds,
|
||||
.markdown-body .pl-s1,
|
||||
.markdown-body .pl-s1 .pl-pse .pl-s2,
|
||||
.markdown-body .pl-sr,
|
||||
.markdown-body .pl-sr .pl-cce,
|
||||
.markdown-body .pl-sr .pl-sra,
|
||||
.markdown-body .pl-sr .pl-sre,
|
||||
.markdown-body .pl-src {
|
||||
color: #df5000
|
||||
}
|
||||
|
||||
.markdown-body .pl-mo,
|
||||
.markdown-body .pl-v {
|
||||
color: #1d3e81
|
||||
}
|
||||
|
||||
.markdown-body .pl-id {
|
||||
color: #b52a1d
|
||||
}
|
||||
|
||||
.markdown-body .pl-ii {
|
||||
background-color: #b52a1d;
|
||||
color: #f8f8f8
|
||||
}
|
||||
|
||||
.markdown-body .pl-sr .pl-cce {
|
||||
color: #63a35c;
|
||||
font-weight: 700
|
||||
}
|
||||
|
||||
.markdown-body .pl-ml {
|
||||
color: #693a17
|
||||
}
|
||||
|
||||
.markdown-body .pl-mh,
|
||||
.markdown-body .pl-mh .pl-en,
|
||||
.markdown-body .pl-ms {
|
||||
color: #1d3e81;
|
||||
font-weight: 700
|
||||
}
|
||||
|
||||
.markdown-body .pl-mq {
|
||||
color: teal
|
||||
}
|
||||
|
||||
.markdown-body .pl-mi {
|
||||
color: #333;
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
.markdown-body .pl-mb {
|
||||
color: #333;
|
||||
font-weight: 700
|
||||
}
|
||||
|
||||
.markdown-body .pl-md,
|
||||
.markdown-body .pl-mdhf {
|
||||
background-color: #ffecec;
|
||||
color: #bd2c00
|
||||
}
|
||||
|
||||
.markdown-body .pl-mdht,
|
||||
.markdown-body .pl-mi1 {
|
||||
background-color: #eaffea;
|
||||
color: #55a532
|
||||
}
|
||||
|
||||
.markdown-body .pl-mdr {
|
||||
color: #795da3;
|
||||
font-weight: 700
|
||||
}
|
||||
|
||||
.markdown-body kbd {
|
||||
display: inline-block;
|
||||
padding: 3px 5px;
|
||||
font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
line-height: 10px;
|
||||
color: #555;
|
||||
vertical-align: middle;
|
||||
background-color: #fcfcfc;
|
||||
border: 1px solid #ccc;
|
||||
border-bottom-color: #bbb;
|
||||
border-radius: 3px;
|
||||
box-shadow: inset 0 -1px 0 #bbb
|
||||
}
|
||||
|
||||
.markdown-body .task-list-item+.task-list-item {
|
||||
margin-top: 3px
|
||||
}
|
||||
|
||||
.markdown-body .task-list-item input {
|
||||
float: left;
|
||||
margin: .3em 0 .25em -1.6em;
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
.markdown-body :checked+.radio-label {
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
border-color: #4183c4
|
||||
}
|
||||
16
src/index.js
16
src/index.js
|
|
@ -1,16 +0,0 @@
|
|||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import './index.css'
|
||||
import './iconfont.css'
|
||||
import App from './App'
|
||||
|
||||
import * as serviceWorker from './serviceWorker'
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById('root'))
|
||||
|
||||
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: https://bit.ly/CRA-PWA
|
||||
serviceWorker.unregister()
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
|
||||
<g fill="#61DAFB">
|
||||
<path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
|
||||
<circle cx="420.9" cy="296.5" r="45.7"/>
|
||||
<path d="M520.5 78.1z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.6 KiB |
|
|
@ -1 +0,0 @@
|
|||
/// <reference types="react-scripts" />
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,151 +0,0 @@
|
|||
.wx-pt-btn {
|
||||
margin-top: 0.2rem;
|
||||
border-radius: 22px;
|
||||
width: 72px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
font-size: 16px;
|
||||
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
background: #2EA4FF;
|
||||
}
|
||||
|
||||
.inputBox {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.challengestitle {
|
||||
font-size: 1.3rem;
|
||||
font-weight: 800;
|
||||
color: rgba(48, 49, 51, 1);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.am-modal-content {
|
||||
border-radius: 1rem 1rem 0rem 0rem;
|
||||
}
|
||||
|
||||
.am-list-header {
|
||||
height: 2.75rem;
|
||||
}
|
||||
|
||||
.Jumpoff {
|
||||
font-size: 0.8rem;
|
||||
font-weight: 400;
|
||||
color: rgba(144, 147, 153, 1);
|
||||
}
|
||||
|
||||
.JumpoffFF9C3D {
|
||||
color: #FF9C3D;
|
||||
}
|
||||
|
||||
.closebutton {
|
||||
font-size: 0.8rem;
|
||||
font-weight: 400;
|
||||
color: rgba(48, 49, 51, 1);
|
||||
}
|
||||
|
||||
.am-list-line::after {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
.am-list-item .am-list-line .am-list-content {
|
||||
background: #fafafa;
|
||||
border-radius: 0.5rem;
|
||||
margin-bottom: 0.625rem;
|
||||
padding: 0.625rem;
|
||||
font-weight: 400;
|
||||
color: rgba(144, 147, 153, 1);
|
||||
font-size: 1rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.am-list-body {
|
||||
padding-top: 0.625rem;
|
||||
}
|
||||
|
||||
.conlistfont {
|
||||
max-width: 16rem;
|
||||
font-size: 1rem;
|
||||
color: rgba(48, 49, 51, 1);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap
|
||||
}
|
||||
|
||||
.conlistfontclose {
|
||||
max-width: 16rem;
|
||||
font-size: 1rem;
|
||||
color: #C0C4CC !important;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap
|
||||
}
|
||||
|
||||
.colorC0C4CC {
|
||||
color: #C0C4CC;
|
||||
}
|
||||
|
||||
.am-list-item.am-list-item-active {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
.iconwanchengjiaobiao {
|
||||
position: absolute;
|
||||
top: -0.625rem;
|
||||
right: 0.0625rem;
|
||||
color: #19CB70;
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.am-modal-title {
|
||||
font-size: 1rem !important;
|
||||
line-height: 1.5rem !important;
|
||||
}
|
||||
|
||||
.am-modal-transparent {
|
||||
width: 20rem !important;
|
||||
}
|
||||
|
||||
.color51 {
|
||||
color: rgb(51, 163, 244);
|
||||
}
|
||||
|
||||
.am-modal-button-group-v .am-modal-button {
|
||||
color: rgb(51, 163, 244);
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.inputBox {
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
position: fixed;
|
||||
bottom: 0px;
|
||||
}
|
||||
|
||||
.wx-code-area {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
pre.prettyprint {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.fl {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.fr {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.ml10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
|
@ -1,349 +0,0 @@
|
|||
|
||||
import './index.css';
|
||||
import './katex.min.css';
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import axios from 'axios';
|
||||
import { WingBlank, WhiteSpace, TabBar, Modal, List, Toast } from 'antd-mobile';
|
||||
import { setCookie } from '../../util';
|
||||
import { useParams, useLocation, useHistory, useRouteMatch } from 'react-router-dom'
|
||||
import mediator from '../../util/mediator';
|
||||
// import RenderHtml from '../../components/render-html';
|
||||
import RenderHtml from '../../components/RenderHtml/index';
|
||||
axios.defaults.withCredentials = true;
|
||||
export default (props) => {
|
||||
|
||||
const { identifier, educoder_session, autologin_trustie } = useParams()
|
||||
const history = useHistory()
|
||||
const location = useLocation()
|
||||
const routeMatch = useRouteMatch()
|
||||
|
||||
const [showmode, setshowmode] = useState(false);
|
||||
const [game_challenges, setgame_challenges] = useState(null);
|
||||
const [getchallenges, setchallenges] = useState([]);
|
||||
const [identitytype, setidentitytype] = useState(false);
|
||||
const [challengeposition, setchallengeposition] = useState(0);
|
||||
const [buttonarray, setbuttonarray] = useState(['关卡', '', '', '代码']);
|
||||
const [daimaodal, setdaimaodal] = useState(false);
|
||||
const [myshixun_id, setmyshixun_id] = useState(null);
|
||||
const [task_pass, settask_pass] = useState("null");
|
||||
|
||||
const isPlay = useRef(false)
|
||||
|
||||
useEffect(() => {
|
||||
isPlay.current = false
|
||||
}, [myshixun_id])
|
||||
|
||||
const copyAccessKey = () => {
|
||||
//因为我的input框里面还有button 按钮,所以在选择节点的时候,一定要只选择input
|
||||
var copyDOM = document.querySelector(".inputBox input"); //需要复制文字的节点
|
||||
var range = document.createRange(); //创建一个range
|
||||
window.getSelection().removeAllRanges(); //清楚页面中已有的selection
|
||||
range.selectNode(copyDOM); // 选中需要复制的节点
|
||||
window.getSelection().addRange(range); // 执行选中元素
|
||||
var successful = document.execCommand('copy'); // 执行 copy 操作
|
||||
if (successful) {
|
||||
Toast.info('复制成功!')
|
||||
} else {
|
||||
Toast.info('复制失败,请手动复制!')
|
||||
}
|
||||
// 移除选中的元素
|
||||
window.getSelection().removeAllRanges();
|
||||
}
|
||||
|
||||
const challenges = (identifier, position, task_passtype) => {
|
||||
// const url = `https://data.educoder.net/api/myshixuns/${identifier}/challenges.json`;
|
||||
const url = `/myshixuns/${identifier}/challenges.json`;
|
||||
|
||||
axios.get(url, {}).then((response) => {
|
||||
if (response.data) {
|
||||
let type = 0
|
||||
response.data.map((item, key) => {
|
||||
if (key === position - 1) {
|
||||
type = item.status;
|
||||
}
|
||||
})
|
||||
|
||||
let newbuttonarray = buttonarray;
|
||||
if (position != 1 && response.data.length != 1) {
|
||||
newbuttonarray[1] = '上一关';
|
||||
} else {
|
||||
newbuttonarray[1] = '';
|
||||
}
|
||||
|
||||
if (task_passtype === true) {
|
||||
if (position != response.data.length) {
|
||||
newbuttonarray[2] = '下一关';
|
||||
} else {
|
||||
newbuttonarray[2] = '';
|
||||
}
|
||||
}
|
||||
|
||||
if (task_passtype === false) {
|
||||
if (position != response.data.length && type === 2) {
|
||||
newbuttonarray[2] = '下一关';
|
||||
} else {
|
||||
newbuttonarray[2] = '';
|
||||
}
|
||||
}
|
||||
setbuttonarray(newbuttonarray);
|
||||
setchallenges(response.data);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getTaskInfo = (game_identifier) => {
|
||||
if (!game_identifier) {
|
||||
Toast.info("该实训不支持跳关");
|
||||
return
|
||||
}
|
||||
isPlay.current = false
|
||||
const url = `/tasks/${game_identifier}.json`;
|
||||
|
||||
axios.get(url, {}).then((response) => {
|
||||
let task_passtype = false;
|
||||
setshowmode(false)
|
||||
if (response.data.challenge) {
|
||||
let task_pass = response.data.challenge.task_pass
|
||||
settask_pass(task_pass)
|
||||
setchallengeposition(response.data.challenge.position)
|
||||
setgame_challenges(response.data.challenge)
|
||||
setmyshixun_id(response.data.challenge.id)
|
||||
}
|
||||
props.onGetTaskInfo(response.data)
|
||||
PR.prettyPrint()
|
||||
if (response.data.shixun) {
|
||||
if (response.data.user) {
|
||||
if (response.data.user.identity) {
|
||||
|
||||
let identity = response.data.user.identity;
|
||||
|
||||
if (identity === 1) {
|
||||
task_passtype = true
|
||||
} else if (identity === 2) {
|
||||
task_passtype = true
|
||||
} else if (identity === 3) {
|
||||
task_passtype = true
|
||||
} else if (identity === 4) {
|
||||
task_passtype = true
|
||||
} else if (identity === 5) {
|
||||
// 已认证老师允许跳关
|
||||
task_passtype = true
|
||||
} else {
|
||||
if (response.data.shixun.task_pass === true) {
|
||||
task_passtype = true
|
||||
} else {
|
||||
task_passtype = false
|
||||
}
|
||||
}
|
||||
setidentitytype(task_passtype)
|
||||
if (response.data.myshixun.identifier) {
|
||||
challenges(response.data.myshixun.identifier, response.data.challenge.position, task_passtype)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
function changeTask(taskId, delCode = true) {
|
||||
let rex = new RegExp(identifier, 'g');
|
||||
let url = location.pathname.replace(rex, taskId)
|
||||
if (delCode) {
|
||||
if (!routeMatch.isExact) {
|
||||
url = url.replace('/code', '')
|
||||
}
|
||||
}
|
||||
history.replace(url)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
let cookies = [];
|
||||
cookies.push({ id: "educoder_session", value: educoder_session })
|
||||
cookies.push({ id: "autologin_trustie", value: autologin_trustie })
|
||||
setCookie(cookies)
|
||||
}, [educoder_session, autologin_trustie])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
function init() {
|
||||
getTaskInfo(identifier)
|
||||
}
|
||||
init()
|
||||
}, [identifier]);
|
||||
|
||||
|
||||
const useCurrentValue = (val) => {
|
||||
setshowmode(val);
|
||||
}
|
||||
|
||||
const postcheckpoint = (type) => {
|
||||
if (getchallenges) {
|
||||
if (getchallenges.length > 0) {
|
||||
getchallenges.map((item, key) => {
|
||||
if (type === 0) {
|
||||
if (key === challengeposition - 2) {
|
||||
changeTask(item.identifier)
|
||||
}
|
||||
} else if (type === 1) {
|
||||
if (key === challengeposition) {
|
||||
changeTask(item.identifier)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const renderContent = (pageText) => {
|
||||
if (pageText === "关卡") {
|
||||
useCurrentValue(true)
|
||||
} else if (pageText === "代码") {
|
||||
weplay(myshixun_id)
|
||||
} else if (pageText === "上一关") {
|
||||
postcheckpoint(0)
|
||||
} else if (pageText === "下一关") {
|
||||
postcheckpoint(1)
|
||||
}
|
||||
}
|
||||
|
||||
const weplay = (myshixun_id) => {
|
||||
if (myshixun_id) {
|
||||
const url = `/weapps/challenges/${myshixun_id}/is_play.json`;
|
||||
|
||||
axios.get(url, {}).then((response) => {
|
||||
if (response.data) {
|
||||
if (response.data.status === 0) {
|
||||
isPlay.current = true
|
||||
if (routeMatch.isExact) {
|
||||
let gameurl = `/educodermd/${identifier}/${educoder_session}/${autologin_trustie}/code`;
|
||||
props.history.push(gameurl);
|
||||
}
|
||||
props.callback && props.callback()
|
||||
} else {
|
||||
if (response.data.status === -5) {
|
||||
setdaimaodal(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
function toTask() {
|
||||
if (!isPlay.current) {
|
||||
weplay(myshixun_id)
|
||||
} else {
|
||||
props.callback()
|
||||
}
|
||||
}
|
||||
function resetGame() {
|
||||
getTaskInfo(identifier)
|
||||
}
|
||||
function onNextGame(id) {
|
||||
changeTask(id, false)
|
||||
}
|
||||
let unSub = mediator.subscribe('to-task', toTask)
|
||||
let unSubReset = mediator.subscribe('reset-game', resetGame)
|
||||
let unSubNextGame = mediator.subscribe('next-game', onNextGame)
|
||||
return () => {
|
||||
unSub()
|
||||
unSubReset()
|
||||
unSubNextGame()
|
||||
}
|
||||
}, [myshixun_id, weplay, isPlay.current]);
|
||||
|
||||
return (
|
||||
<div className="wx-code-flex">
|
||||
<div style={{ position: 'fixed', height: '100%', width: '100%', top: 0, overflow: 'hidden' }}>
|
||||
<TabBar
|
||||
unselectedTintColor="#949494"
|
||||
tintColor="#33A3F4"
|
||||
barTintColor="white"
|
||||
tabBarPosition="bottom"
|
||||
prerenderingSiblingsNumber={0}
|
||||
>
|
||||
{buttonarray.map((item, key) => {
|
||||
return (
|
||||
<TabBar.Item
|
||||
title={item === "代码" ? "" : item}
|
||||
key={key}
|
||||
selectedIcon={<div>
|
||||
{item === "关卡" ? <i className={"iconfont iconguankamulu"} /> :
|
||||
item === "上一关" ? <i className={"iconfont iconshangyiguan"} /> :
|
||||
item === "下一关" ? <i className={"iconfont iconxiayiguan"} /> :
|
||||
item === "代码" ? <div className="wx-pt-btn">代码</div> : ""}
|
||||
</div>
|
||||
}
|
||||
selected={true}
|
||||
onPress={() => renderContent(item)}
|
||||
>
|
||||
<WhiteSpace size="lg" />
|
||||
|
||||
<WingBlank>
|
||||
{game_challenges === null ? "" : <div className="challengestitle">第{game_challenges && game_challenges.position}关: {game_challenges && game_challenges.subject}</div>}
|
||||
</WingBlank>
|
||||
<WhiteSpace size="lg" />
|
||||
<WingBlank>
|
||||
{game_challenges === null ? "" : <RenderHtml value={task_pass} style={{ height: 'calc(100vh - 88px)', paddingBottom: '50px' }} />}
|
||||
</WingBlank>
|
||||
<div className='inputBox'>
|
||||
<input
|
||||
className={'copyInput apiInput'}
|
||||
value={`https://www.educoder.net/tasks/${identifier}`}
|
||||
readOnly={true}
|
||||
/>
|
||||
</div>
|
||||
</TabBar.Item>
|
||||
)
|
||||
})}
|
||||
</TabBar>
|
||||
</div>
|
||||
<Modal
|
||||
visible={daimaodal}
|
||||
transparent
|
||||
maskClosable={false}
|
||||
onClose={() => setdaimaodal(false)}
|
||||
title={`该项目近期将提供小程序入口,请利用下面的网址在电脑端操作:`}
|
||||
footer={[{ text: '我知道了', onPress: () => setdaimaodal(false) }]}
|
||||
wrapProps={{ onTouchStart: null }}
|
||||
>
|
||||
<div style={{ height: 100, overflow: 'scroll' }}>
|
||||
<div className="mt10">实训地址:https://www.educoder.ne</div>
|
||||
<div>t/tasks/{identifier}</div>
|
||||
<div className="mt10 color51 ml10" onClick={() => { copyAccessKey() }}>复制链接
|
||||
<i className="iconfont iconfuzhi1 ml5 color51"></i>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal
|
||||
popup
|
||||
visible={showmode}
|
||||
onClose={() => setshowmode(false)}
|
||||
animationType="slide-up"
|
||||
>
|
||||
<List renderHeader={() => {
|
||||
return (
|
||||
<div>
|
||||
<div className="fl Jumpoff">共{getchallenges && getchallenges.length}关 {identitytype === true ? "" : <span className="JumpoffFF9C3D">(该实训不支持跳关)</span>}</div>
|
||||
<div className="fr closebutton" onClick={() => setshowmode(false)}>关闭</div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
} className="popup-list">
|
||||
{getchallenges.map((i, index) => (
|
||||
<List.Item key={index} onClick={() => changeTask(i.identifier)}><div className="fl colorC0C4CC" >第{i.position}关</div><div className={i.identifier ? "conlistfont fl ml10" : "conlistfontclose fl ml10"}>
|
||||
{i.name}
|
||||
</div>
|
||||
{i.status === 2 ? <i className="iconfont iconwanchengjiaobiao"></i> : ""}</List.Item>
|
||||
))}
|
||||
</List>
|
||||
</Modal>
|
||||
</div>
|
||||
|
||||
);
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue