ui: upgrade to webpack5

This commit is contained in:
undefined committed 2022-08-07 03:15:36 +08:00
1 parent 8648929063
commit a05125c6b0
134 files changed
+503 -457

No files matched your search

+4 -2
View File
@@ -33,10 +33,12 @@ jobs:
path: |
${{ steps.yarn-cache-dir-path.outputs.dir }}
yarn.lock
.cache
**/tsconfig.tsbuildinfo
key: yarn-${{ hashFiles('**/package.json') }}
key: ${{ GITHUB_REF_NAME }}
restore-keys: |
yarn-
master
main
- name: Config And Install
run: |
[[ ! -z "${{secrets.NPM_TOKEN}}" ]] && echo "npmAuthToken: ${{secrets.NPM_TOKEN}}" >> .yarnrc.yml
+12 -1
View File
@@ -3,7 +3,7 @@ const path = require('path');
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'react'],
plugins: ['@typescript-eslint', 'react', 'simple-import-sort'],
env: {
browser: true,
es6: true,
@@ -138,5 +138,16 @@ module.exports = {
'jsx-a11y/anchor-is-valid': 'off',
'jsx-a11y/click-events-have-key-events': 'off',
'jsx-a11y/label-has-associated-control': 'off',
'simple-import-sort/imports': [
'warn',
{
groups: [
['^\\u0000'],
['^(?!vj)(@?\\w.+)', '^vj\\/', '^', '^\\.'],
],
},
],
'simple-import-sort/exports': 'off',
},
};
@@ -26,12 +26,6 @@ function preziParser(url: string) {
const match = url.match(preziRegex);
return match ? match[1] : url;
}
// TODO: Write regex for staging and local servers.
const mfrRegex = /^http(?:s?):\/\/(?:www\.)?mfr\.osf\.io\/render\?url=http(?:s?):\/\/osf\.io\/([a-zA-Z0-9]{1,5})\/\?action=download/;
function mfrParser(url: string) {
const match = url.match(mfrRegex);
return match ? match[1] : url;
}
const EMBED_REGEX = /@\[([a-zA-Z].+?)]\((.*?)[)]/im;
function extractVideoParameters(url: string) {
const parameterMap = new Map();
@@ -82,7 +76,6 @@ function resourceUrl(service: string, src: string, url: string, options) {
+ 'landing_data=bHVZZmNaNDBIWnNjdEVENDRhZDFNZGNIUE43MHdLNWpsdFJLb2ZHanI5N1lQVHkxSHFxazZ0UUNCRHloSXZROHh3PT0&'
+ 'landing_sign=1kD6c0N6aYpMUS0wxnQjxzSqZlEB8qNFdxtdjYhwSuI';
}
if (service === 'osf') return `https://mfr.osf.io/render?url=https://osf.io/${src}/?action=download`;
return src;
}
@@ -95,26 +88,11 @@ export function Media(md: MarkdownIt) {
vimeo: { width: 500, height: 281 },
vine: { width: 600, height: 600, embed: 'simple' },
prezi: { width: 550, height: 400 },
osf: { width: '100%', height: '100%' },
pdf: resourceUrl,
};
md.renderer.rules.video = function tokenizeReturn(tokens, idx) {
let src = md.utils.escapeHtml(tokens[idx].attrGet('src'));
const service = md.utils.escapeHtml(tokens[idx].attrGet('service')).toLowerCase();
const checkUrl = /http(?:s?):\/\/(?:www\.)?[a-zA-Z0-9-:.]{1,}\/render(?:\/)?[a-zA-Z0-9.&;?=:%]{1,}url=http(?:s?):\/\/[a-zA-Z0-9 -:.]{1,}\/[a-zA-Z0-9]{1,5}\/\?[a-zA-Z0-9.=:%]{1,}/;
let num;
if (service === 'osf' && src) {
num = Math.random() * 0x10000;
if (src.match(checkUrl)) {
return `<div id="${num}" class="mfr mfr-file"></div><script>`
+ `$(document).ready(function () {new mfr.Render("${num}", "${src}");`
+ ' }); </script>';
}
return `<div id="${num}" class="mfr mfr-file"></div><script>`
+ `$(document).ready(function () {new mfr.Render("${num}", "https://mfr.osf.io/`
+ `render?url=https://osf.io/${src}/?action=download%26mode=render");`
+ ' }); </script>';
}
if (service === 'bilibili') {
if (src.startsWith('http')) src = src.split('/').pop();
if (src.toLowerCase().startsWith('av')) src = src.toLowerCase().split('av')[1];
@@ -171,7 +149,6 @@ export function Media(md: MarkdownIt) {
else if (service === 'vimeo') src = vimeoParser(src);
else if (service === 'vine') src = vineParser(src);
else if (service === 'prezi') src = preziParser(src);
else if (service === 'osf') src = mfrParser(src);
if (src === ')') src = '';
const serviceStart = oldPos + 2;
if (!silent) {
@@ -1,25 +1,21 @@
/* eslint-disable global-require */
/* eslint-disable import/no-extraneous-dependencies */
import { dirname } from 'path';
import webpack from 'webpack';
import { CleanWebpackPlugin } from 'clean-webpack-plugin';
import CopyWebpackPlugin from 'copy-webpack-plugin';
import { ESBuildMinifyPlugin } from 'esbuild-loader';
import FriendlyErrorsPlugin from 'friendly-errors-webpack-plugin';
import ExtractCssPlugin from 'mini-css-extract-plugin';
import MonacoWebpackPlugin from 'monaco-editor-webpack-plugin';
import FriendlyErrorsPlugin from 'friendly-errors-webpack-plugin';
import CopyWebpackPlugin from 'copy-webpack-plugin';
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
import { dirname } from 'path';
import SpeedMeasurePlugin from 'speed-measure-webpack-plugin';
import webpack from 'webpack';
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
import WebpackBar from 'webpackbar';
import mapWebpackUrlPrefix from '../utils/mapWebpackUrlPrefix';
import root from '../utils/root';
const beautifyOutputUrl = mapWebpackUrlPrefix([
{ prefix: 'misc/.iconfont', replace: './ui/iconfont' },
]);
const smp = new SpeedMeasurePlugin();
export default function (env = {}) {
export default function (env: { production?: boolean, measure?: boolean } = {}) {
function esbuildLoader() {
return {
loader: 'esbuild-loader',
@@ -41,28 +37,7 @@ export default function (env = {}) {
function postcssLoader() {
return {
loader: 'postcss-loader',
options: { sourceMap: env.production, config: { path: root('postcss.config.js') } },
};
}
function fileLoader() {
return {
loader: 'file-loader',
options: {
name(resourcePath) {
if (resourcePath.includes('node_modules')) {
const extra = resourcePath.split('node_modules')[1];
const moduleName = extra.split('/')[0];
if (extra.includes('@fontsource')) {
return `fonts/${extra.substr(2).replace(/\\/g, '/')}?[contenthash]`;
}
if (['katex', 'monaco-editor'].includes(moduleName)) return `modules/${moduleName}/[name].[ext]?[contenthash]`;
return `modules/${extra.substr(1).replace(/\\/g, '/')}?[contenthash]`;
}
if (resourcePath.includes('misc/.iconfont')) return 'modules/icon/[name].[ext]?[contenthash]';
return '[path][name].[ext]?[contenthash]';
},
},
options: { postcssOptions: { sourceMap: env.production, config: root('postcss.config.js') } },
};
}
@@ -76,24 +51,45 @@ export default function (env = {}) {
};
}
const config = {
bail: true,
function stylusLoader() {
return {
loader: 'stylus-loader',
options: {
stylusOptions: {
preferPathResolver: 'webpack',
use: [require('rupture')()], // eslint-disable-line global-require
import: ['~vj/common/common.inc.styl'],
},
},
};
}
const config: import('webpack').Configuration = {
// bail: !env.production,
mode: (env.production || env.measure) ? 'production' : 'development',
profile: true,
profile: env.measure,
context: root(),
stats: {
preset: 'errors-warnings',
},
devtool: env.production ? 'source-map' : false,
entry: {
hydro: './entry.js',
polyfill: './polyfill.ts',
'default.theme': './theme/default.js',
},
cache: {
type: 'filesystem',
cacheDirectory: root('../../.cache'),
idleTimeout: 30000,
},
output: {
path: root('public'),
publicPath: '/', // overwrite in entry.js
hashFunction: 'sha1',
hashDigest: 'hex',
hashDigestLength: 10,
filename: '[name].js?[hash]',
filename: '[name].js?[contenthash]',
chunkFilename: '[name].[chunkhash].chunk.js',
},
resolve: {
@@ -114,33 +110,60 @@ export default function (env = {}) {
use: { loader: '@svgr/webpack', options: { icon: true } },
},
{
use: [fileLoader()],
type: 'asset/resource',
},
],
},
{
test: /\.(ttf|eot|woff|woff2|png|jpg|jpeg|gif)$/,
use: [fileLoader()],
type: 'asset/resource',
generator: {
filename: (pathData) => {
const p = pathData.module.resource.replace(/\\/g, '/');
const filename = p.split('/').pop();
if (p.includes('node_modules')) {
const extra = p.split('node_modules')[1];
const moduleName = extra.split('/')[0];
if (extra.includes('@fontsource')) {
return `fonts/${filename}?[hash]`;
}
if (['katex', 'monaco-editor'].includes(moduleName)) {
return `modules/${moduleName}/${filename}?[hash]`;
}
return `modules/${extra.substr(1)}?[hash]`;
}
if (p.includes('.iconfont')) return `${filename}?[hash]`;
return `${p.split('ui-default')[1].substring(1)}?[hash]`;
},
},
},
{
test: /\.ts$/,
include: /@types\//,
type: 'asset/inline',
generator: {
dataUrl: (buf) => buf.toString(),
},
},
{
test: /\.[jt]sx?$/,
exclude: /@types\//,
use: [esbuildLoader()],
},
{
test: /\.styl$/,
use: [extractCssLoader(), cssLoader(), postcssLoader(), 'stylus-loader'],
use: [extractCssLoader(), cssLoader(), postcssLoader(), stylusLoader()],
},
{
test: /\.css$/,
use: [extractCssLoader(), cssLoader(), postcssLoader()],
},
{
test: /\.wasm$/,
use: [fileLoader()],
type: 'javascript/auto',
},
],
},
experiments: {
asyncWebAssembly: true,
syncWebAssembly: true,
},
optimization: {
splitChunks: {
minSize: 256000,
@@ -149,7 +172,7 @@ export default function (env = {}) {
automaticNameDelimiter: '-',
cacheGroups: {
style: {
test: /\.(css|styl|less|sass|scss)$/,
test: /\.(css|styl|less|s[ac]ss)$/,
priority: 99,
name: 'style',
},
@@ -199,20 +222,10 @@ export default function (env = {}) {
monaco: 'monaco-editor/esm/vs/editor/editor.api',
}),
new ExtractCssPlugin({
filename: '[name].css?[hash:10]',
}),
new webpack.LoaderOptionsPlugin({
test: /\.styl$/,
stylus: {
default: {
preferPathResolver: 'webpack',
use: [require('rupture')()], // eslint-disable-line global-require
import: ['~vj/common/common.inc.styl'],
},
},
filename: '[name].css?[fullhash:10]',
}),
new FriendlyErrorsPlugin(),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new webpack.IgnorePlugin({ resourceRegExp: /(^\.\/locale$|mathjax|abcjs)/ }),
new CopyWebpackPlugin({
patterns: [
{ from: root('static') },
@@ -221,16 +234,7 @@ export default function (env = {}) {
],
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: env.production ? '"production"' : '"debug"',
VERSION: JSON.stringify(require('@hydrooj/ui-default/package.json').version),
},
}),
new webpack.LoaderOptionsPlugin({
options: {
context: root(),
customInterpolateName: beautifyOutputUrl,
},
'process.env.VERSION': JSON.stringify(require('@hydrooj/ui-default/package.json').version),
}),
new webpack.NormalModuleReplacementPlugin(/\/(vscode-)?nls\.js/, require.resolve('../../components/monaco/nls')),
new MonacoWebpackPlugin({
+5 -12
View File
@@ -19,19 +19,17 @@ async function runWebpack({
}) {
const compiler = webpack(webpackConfig({ watch, production, measure }));
if (dev) {
const server = new WebpackDevServer(compiler, {
const server = new WebpackDevServer({
port: 8000,
compress: true,
hot: true,
disableHostCheck: true,
stats: 'none',
index: root('public'),
proxy: {
context: (path) => !path.includes('sockjs-node'),
context: (path) => path !== '/ws' && !path.startsWith('/vendors.js'),
target: 'http://localhost:2333',
ws: true,
},
});
return server.listen(8000);
}, compiler);
return server.start();
}
return new Promise((resolve, reject) => {
function compilerCallback(err, stats) {
@@ -85,15 +83,10 @@ async function main() {
if (fs.existsSync('public/polyfill.js')) {
fs.copyFileSync('public/polyfill.js', `public/polyfill-${pkg.version}.js`);
}
if (fs.existsSync('public/default.theme.css')) {
fs.copyFileSync('public/default.theme.css', `public/default-${pkg.version}.theme.css`);
}
if (argv.options.production) {
fs.removeSync('public/vditor/dist/js/mathjax');
fs.removeSync('public/vditor/dist/js/echarts');
fs.removeSync('public/vditor/dist/js/graphviz');
fs.removeSync('public/vditor/dist/js/mermaid');
fs.removeSync('public/vditor/dist/js/abcjs');
const files = fs.readdirSync('public');
files.filter((i) => /(^[in]\..+|worker)\.js\.map$/.test(i)).forEach((i) => fs.removeSync(`public/${i}`));
}
@@ -1,18 +0,0 @@
/* eslint-disable import/no-extraneous-dependencies */
import { escapeRegExp } from 'lodash';
export default function mapWebpackUrlPrefix(mapList) {
const rules = mapList.map((mappingRule) => {
const regex = mappingRule.prefix.split('/').map((s) => escapeRegExp(s)).join('[\\/\\\\]');
return {
from: new RegExp(`^${regex}`, mappingRule.flag),
to: mappingRule.replace,
};
});
return function mapUrl(url) {
rules.forEach((rule) => {
url = url.replace(rule.from, rule.to);
});
return url;
};
}
@@ -1,3 +1,5 @@
import $ from 'jquery';
let removalChecker = null;
const res = [];
@@ -1,6 +1,6 @@
import { assign } from 'lodash';
import React from 'react';
import ReactDOM from 'react-dom/client';
import { assign } from 'lodash';
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
import AutoComplete from '.';
import DomainSelectAutoCompleteFC from './components/DomainSelectAutoComplete';
@@ -1,6 +1,6 @@
import { assign } from 'lodash';
import React from 'react';
import ReactDOM from 'react-dom/client';
import { assign } from 'lodash';
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
import AutoComplete from '.';
import ProblemSelectAutoCompleteFC from './components/ProblemSelectAutoComplete';
@@ -1,6 +1,6 @@
import { assign } from 'lodash';
import React from 'react';
import ReactDOM from 'react-dom/client';
import { assign } from 'lodash';
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
import AutoComplete, { AutoCompleteOptions } from '.';
import UserSelectAutoCompleteFC from './components/UserSelectAutoComplete';
@@ -1,12 +1,13 @@
/* eslint-disable jsx-a11y/role-supports-aria-props */
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
import { debounce, uniqueId } from 'lodash';
import PropTypes from 'prop-types';
import React, {
forwardRef, useState, useRef, useImperativeHandle, useEffect,
forwardRef, useEffect,
useImperativeHandle, useRef, useState,
} from 'react';
import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import PropTypes from 'prop-types';
import { debounce, uniqueId } from 'lodash';
import Icon from 'vj/components/react/IconComponent';
export interface AutoCompleteProps<Item> {
@@ -1,5 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import React from 'react';
import AutoComplete from './AutoComplete';
type DefaultProps = {
@@ -1,7 +1,7 @@
import React, { forwardRef } from 'react';
import PropTypes from 'prop-types';
import request from 'vj/utils/request';
import type { DomainDoc } from 'hydrooj/src/interface';
import PropTypes from 'prop-types';
import React, { forwardRef } from 'react';
import request from 'vj/utils/request';
import AutoComplete, { AutoCompleteHandle, AutoCompleteProps } from './AutoComplete';
const DomainSelectAutoComplete = forwardRef<AutoCompleteHandle<DomainDoc>, AutoCompleteProps<DomainDoc>>((props, ref) => (
@@ -1,5 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import React from 'react';
import AutoComplete from './AutoComplete';
type DefaultProps = {
@@ -1,8 +1,8 @@
import React, { forwardRef } from 'react';
import type { ProblemDoc } from 'hydrooj/src/interface';
import PropTypes from 'prop-types';
import React, { forwardRef } from 'react';
import api, { gql } from 'vj/utils/api';
import request from 'vj/utils/request';
import type { ProblemDoc } from 'hydrooj/src/interface';
import AutoComplete, { AutoCompleteHandle, AutoCompleteProps } from './AutoComplete';
const ProblemSelectAutoComplete = forwardRef<AutoCompleteHandle<ProblemDoc>, AutoCompleteProps<ProblemDoc>>((props, ref) => (
@@ -1,7 +1,7 @@
import React, { forwardRef } from 'react';
import PropTypes from 'prop-types';
import api, { gql } from 'vj/utils/api';
import type { Udoc } from 'hydrooj/src/interface';
import PropTypes from 'prop-types';
import React, { forwardRef } from 'react';
import api, { gql } from 'vj/utils/api';
import AutoComplete, { AutoCompleteHandle, AutoCompleteProps } from './AutoComplete';
// eslint-disable-next-line prefer-arrow-callback
@@ -1,6 +1,6 @@
import { assign } from 'lodash';
import React from 'react';
import ReactDOM from 'react-dom/client';
import { assign } from 'lodash';
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
import AutoCompleteFC from './components/AutoComplete';
@@ -1,3 +1,4 @@
import $ from 'jquery';
import _ from 'lodash';
import moment from 'moment';
import tpl from 'vj/utils/tpl';
@@ -1,8 +1,9 @@
import $ from 'jquery';
import Notification from 'vj/components/notification';
import { AutoloadPage } from 'vj/misc/Page';
import delay from 'vj/utils/delay';
import i18n from 'vj/utils/i18n';
import request from 'vj/utils/request';
import Notification from 'vj/components/notification';
const contestPage = new AutoloadPage('contestPage', () => {
$('[data-contest-code]').on('click', (ev) => {
@@ -1,3 +1,4 @@
import $ from 'jquery';
import { AutoloadPage } from 'vj/misc/Page';
const datepickerPage = new AutoloadPage('datepickerPage', async () => {
@@ -1,3 +1,4 @@
import $ from 'jquery';
import _ from 'lodash';
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
import zIndexManager from 'vj/utils/zIndexManager';
@@ -1,5 +1,6 @@
import tpl from 'vj/utils/tpl';
import $ from 'jquery';
import i18n from 'vj/utils/i18n';
import tpl from 'vj/utils/tpl';
import DomDialog, { DialogOptions } from './DomDialog';
export class Dialog {
@@ -1,8 +1,9 @@
import $ from 'jquery';
import _ from 'lodash';
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
import request from 'vj/utils/request';
import TextareaHandler from 'vj/components/editor/textareaHandler';
import Notification from 'vj/components/notification';
import request from 'vj/utils/request';
let initialized = false;
const $template = $('.dczcomments__box').eq(0).clone();
@@ -1,13 +1,13 @@
import 'jquery.easing';
import { AutoloadPage } from 'vj/misc/Page';
import CommentBox from 'vj/components/discussion/CommentBox';
import $ from 'jquery';
import { ConfirmDialog } from 'vj/components/dialog';
import CommentBox from 'vj/components/discussion/CommentBox';
import { AutoloadPage } from 'vj/misc/Page';
import delay from 'vj/utils/delay';
import { slideDown, slideUp } from 'vj/utils/slide';
import request from 'vj/utils/request';
import i18n from 'vj/utils/i18n';
import request from 'vj/utils/request';
import { slideDown, slideUp } from 'vj/utils/slide';
import tpl from 'vj/utils/tpl';
const $replyTemplate = $('.commentbox-container').eq(0).clone();
@@ -1,12 +1,12 @@
import 'jquery.easing';
import { Popover } from '@blueprintjs/core';
import $ from 'jquery';
import { chunk } from 'lodash';
import * as React from 'react';
import ReactDOM from 'react-dom/client';
import { Popover } from '@blueprintjs/core';
import { AutoloadPage } from 'vj/misc/Page';
import request from 'vj/utils/request';
import { chunk } from 'lodash';
function renderReactions(reactions, self, rootEle) {
let html = '';
@@ -1,10 +1,9 @@
import Drop from 'tether-drop';
import _ from 'lodash';
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
import Drop from 'tether-drop';
import responsiveCutoff from 'vj/breakpoints.json';
import zIndexManager from 'vj/utils/zIndexManager';
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
import { isBelow } from 'vj/utils/mediaQuery';
import zIndexManager from 'vj/utils/zIndexManager';
export default class Dropdown extends DOMAttachedObject {
static DOMAttachKey = 'vjDropdownInstance';
@@ -1,7 +1,8 @@
import $ from 'jquery';
import _ from 'lodash';
import Notification from 'vj/components/notification';
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
import { nanoid } from 'nanoid';
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
import Notification from 'vj/components/notification';
import i18n from 'vj/utils/i18n';
import request from 'vj/utils/request';
@@ -1,7 +1,8 @@
import $ from 'jquery';
import responsiveCutoff from 'vj/breakpoints.json';
import { AutoloadPage } from 'vj/misc/Page';
import { isBelow } from 'vj/utils/mediaQuery';
import { slideUp, slideDown } from 'vj/utils/slide';
import responsiveCutoff from 'vj/breakpoints.json';
import { slideDown, slideUp } from 'vj/utils/slide';
const footerPage = new AutoloadPage('footerPage', () => {
if (!$('.footer').length) return;
@@ -1,3 +1,4 @@
import $ from 'jquery';
import { AutoloadPage } from 'vj/misc/Page';
import delay from 'vj/utils/delay';
@@ -1,3 +1,4 @@
import $ from 'jquery';
import { AutoloadPage } from 'vj/misc/Page';
const lastSelectionByGroup = {};
@@ -1,3 +1,4 @@
import $ from 'jquery';
import { AutoloadPage } from 'vj/misc/Page';
const textboxPage = new AutoloadPage('textboxPage', () => {
@@ -1,6 +1,7 @@
import $ from 'jquery';
import { AutoloadPage } from 'vj/misc/Page';
import tpl from 'vj/utils/tpl';
import i18n from 'vj/utils/i18n';
import tpl from 'vj/utils/tpl';
const highlighterPage = new AutoloadPage('highlighterPage', () => {
import('./prismjs').then(({ default: prismjs }) => {
@@ -1,11 +1,14 @@
import Prism from 'prismjs';
import components from 'prismjs/components';
import getLoader from 'prismjs/dependencies';
import Prism from 'prismjs'; // eslint-disable-line
import 'prismjs/plugins/toolbar/prism-toolbar';
import 'prismjs/plugins/toolbar/prism-toolbar.css';
import 'prismjs/plugins/line-numbers/prism-line-numbers';
import 'prismjs/plugins/line-numbers/prism-line-numbers.css';
import Clipboard from 'clipboard';
import $ from 'jquery';
import components from 'prismjs/components';
import getLoader from 'prismjs/dependencies';
import Notification from 'vj/components/notification/index';
import i18n from 'vj/utils/i18n';
import languageMeta from './meta';
+1
View File
@@ -1,3 +1,4 @@
import $ from 'jquery';
import { InfoDialog } from 'vj/components/dialog';
import i18n from 'vj/utils/i18n';
import tpl from 'vj/utils/tpl';
@@ -1,6 +1,7 @@
import $ from 'jquery';
import { AutoloadPage } from 'vj/misc/Page';
import request from 'vj/utils/request';
import i18n from 'vj/utils/i18n';
import request from 'vj/utils/request';
import tpl from 'vj/utils/tpl';
const hitokotoPage = new AutoloadPage('hitokotoPage', () => {
@@ -1,3 +1,4 @@
import $ from 'jquery';
import _ from 'lodash';
import { AutoloadPage } from 'vj/misc/Page';
@@ -1,3 +1,4 @@
import $ from 'jquery';
import { AutoloadPage } from 'vj/misc/Page';
const katexPage = new AutoloadPage('katexPage', () => {
@@ -1,3 +1,4 @@
import $ from 'jquery';
import React from 'react';
import ReactDOM from 'react-dom/client';
import i18n from 'vj/utils/i18n';
@@ -1,6 +1,7 @@
import $ from 'jquery';
import _ from 'lodash';
import delay from 'vj/utils/delay';
import Tooltip from 'vj/components/tooltip/Tooltip';
import delay from 'vj/utils/delay';
import i18n from 'vj/utils/i18n';
const MARKER_ID = `marker_${Math.floor(Math.random() * 0xFFFFFF).toString(16)}`;
@@ -1,7 +1,7 @@
import $ from 'jquery';
import _ from 'lodash';
import delay from 'vj/utils/delay';
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
import delay from 'vj/utils/delay';
import Marker from './Marker';
export default class MarkerReactive extends DOMAttachedObject {
@@ -1,3 +1,4 @@
import $ from 'jquery';
import { AutoloadPage } from 'vj/misc/Page';
import request from 'vj/utils/request';
@@ -1,3 +1,4 @@
import $ from 'jquery';
import { AutoloadPage } from 'vj/misc/Page';
import tpl from 'vj/utils/tpl';
@@ -1,6 +1,7 @@
import $ from 'jquery';
import { AutoloadPage } from 'vj/misc/Page';
import { slideDown } from 'vj/utils/slide';
import delay from 'vj/utils/delay';
import { slideDown } from 'vj/utils/slide';
function expandMenu($menu) {
slideDown($menu, 500, { opacity: 0 }, { opacity: 1 });
@@ -1,11 +1,11 @@
import { AutoloadPage } from 'vj/misc/Page';
import { nanoid } from 'nanoid';
import ReconnectingWebsocket from 'reconnecting-websocket';
import { InfoDialog } from 'vj/components/dialog';
import VjNotification from 'vj/components/notification/index';
import ReconnectingWebsocket from 'reconnecting-websocket';
import { FLAG_ALERT } from 'vj/constant/message';
import { AutoloadPage } from 'vj/misc/Page';
import i18n from 'vj/utils/i18n';
import tpl from 'vj/utils/tpl';
import { nanoid } from 'nanoid';
const onmessage = (msg) => {
console.log('Received message', msg);
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types';
import classNames from 'classnames';
import PropTypes from 'prop-types';
export default function DialogueListItemComponent(props) {
const {
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types';
import classNames from 'classnames';
import PropTypes from 'prop-types';
export default function MessageComponent(props) {
const {
@@ -1,9 +1,11 @@
import 'jquery-scroll-lock';
import 'jquery.easing';
import $ from 'jquery';
import moment from 'moment';
import React from 'react';
import { connect } from 'react-redux';
import TimeAgo from 'timeago-react';
import moment from 'moment';
import 'jquery-scroll-lock';
import 'jquery.easing';
import i18n from 'vj/utils/i18n';
import { parse as parseMongoId } from 'vj/utils/mongoId';
import Message from './MessageComponent';
@@ -1,8 +1,9 @@
import React from 'react';
import _ from 'lodash';
import { connect } from 'react-redux';
import 'jquery-scroll-lock';
import $ from 'jquery';
import _ from 'lodash';
import React from 'react';
import { connect } from 'react-redux';
import i18n from 'vj/utils/i18n';
import ListItem from './DialogueListItemComponent';
@@ -1,9 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import { connect } from 'react-redux';
import Icon from 'vj/components/react/IconComponent';
import request from 'vj/utils/request';
const mapStateToProps = (state) => ({
@@ -1,12 +1,11 @@
import React from 'react';
import PropTypes from 'prop-types';
import React from 'react';
import { connect } from 'react-redux';
import request from 'vj/utils/request';
import i18n from 'vj/utils/i18n';
import Icon from 'vj/components/react/IconComponent';
import MessagePadDialogueList from './MessagePadDialogueListContainer';
import i18n from 'vj/utils/i18n';
import request from 'vj/utils/request';
import MessagePadDialogueContent from './MessagePadDialogueContentContainer';
import MessagePadDialogueList from './MessagePadDialogueListContainer';
import MessagePadInput from './MessagePadInputContainer';
const mapDispatchToProps = (dispatch) => ({
@@ -1,5 +1,7 @@
import 'jquery.easing';
import $ from 'jquery';
function scrollToViewport() {
const BOUND_TOP = 60;
const BOUND_BOTTOM = 20;
@@ -1,11 +1,13 @@
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
import './monaco.styl';
import $ from 'jquery';
import { EditorAction, registerEditorAction } from 'monaco-editor/esm/vs/editor/browser/editorExtensions';
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
import { IQuickInputService } from 'monaco-editor/esm/vs/platform/quickinput/common/quickInput';
import list from 'monaco-themes/themes/themelist.json';
import { nanoid } from 'nanoid';
import i18n from 'vj/utils/i18n';
import request from 'vj/utils/request';
import './monaco.styl';
export default monaco;
export const customOptions: monaco.editor.IStandaloneDiffEditorConstructionOptions = JSON.parse(localStorage.getItem('editor.config') || '{}');
@@ -1,6 +1,6 @@
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
import list from 'emojis-list';
import keyword from 'emojis-keywords';
import list from 'emojis-list';
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
import api, { gql } from 'vj/utils/api';
const qqEmojies = [
@@ -1,6 +1,6 @@
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
const types = require.context('!!raw-loader!@types/node/', true, /\.d\.ts$/);
const types = require.context('@types/node/', true, /\.d\.ts$/, 'lazy-once');
const diagnosticsOptions: monaco.languages.typescript.DiagnosticsOptions = {
noSemanticValidation: false,
@@ -24,17 +24,21 @@ const libUri = 'ts:filename/basic.d.ts';
monaco.languages.typescript.javascriptDefaults.addExtraLib(libSource, libUri);
monaco.editor.createModel(libSource, 'typescript', monaco.Uri.parse(libUri));
const modules = [];
for (const key of types.keys()) {
const val = types(key).default.replace('declare var require: NodeRequire;', '');
if (val.includes('declare module ')) {
modules.push(val.toString().split('declare module \'')[1].split('\'')[0]);
(async () => {
for (const key of types.keys()) {
if (!key.startsWith('.')) continue;
const m = await types(key);
const val = m.replace('declare var require: NodeRequire;', '');
if (val.includes('declare module ')) {
modules.push(val.toString().split('declare module \'')[1].split('\'')[0]);
}
const uri = `ts:node/${key.split('./')[1]}`;
monaco.languages.typescript.javascriptDefaults.addExtraLib(val, uri);
monaco.editor.createModel(val, 'typescript', monaco.Uri.parse(uri));
}
const uri = `ts:node/${key.split('./')[1]}`;
monaco.languages.typescript.javascriptDefaults.addExtraLib(val, uri);
monaco.editor.createModel(val, 'typescript', monaco.Uri.parse(uri));
}
let val = 'declare var require:';
for (const m of modules) val += `((id:'${m}')=>(typeof import('${m}')))&`;
val += '((id:string)=>any)';
monaco.languages.typescript.javascriptDefaults.addExtraLib(val, 'ts:node/require.d.ts');
monaco.editor.createModel(val, 'typescript', monaco.Uri.parse('ts:node/require.d.ts'));
let val = 'declare var require:';
for (const m of modules) val += `((id:'${m}')=>(typeof import('${m}')))&`;
val += '((id:string)=>any)';
monaco.languages.typescript.javascriptDefaults.addExtraLib(val, 'ts:node/require.d.ts');
monaco.editor.createModel(val, 'typescript', monaco.Uri.parse('ts:node/require.d.ts'));
})();
@@ -1,12 +1,13 @@
import $ from 'jquery';
import Slideout from 'slideout';
import UserSelectAutoComplete from 'vj/components/autocomplete/UserSelectAutoComplete';
import { ActionDialog } from 'vj/components/dialog';
import createHint from 'vj/components/hint';
import tpl from 'vj/utils/tpl';
import Notification from 'vj/components/notification';
import { AutoloadPage } from 'vj/misc/Page';
import i18n from 'vj/utils/i18n';
import request from 'vj/utils/request';
import { ActionDialog } from 'vj/components/dialog';
import Notification from 'vj/components/notification';
import UserSelectAutoComplete from 'vj/components/autocomplete/UserSelectAutoComplete';
import { AutoloadPage } from 'vj/misc/Page';
import tpl from 'vj/utils/tpl';
function handleNavLogoutClick(ev) {
const $logoutLink = $(ev.currentTarget);
@@ -1,4 +1,5 @@
import { Position, Toaster, Intent } from '@blueprintjs/core';
import { Intent, Position, Toaster } from '@blueprintjs/core';
import $ from 'jquery';
import tpl from 'vj/utils/tpl';
import zIndexManager from 'vj/utils/zIndexManager';
@@ -1,5 +1,5 @@
import { AutoloadPage } from 'vj/misc/Page';
import Notification from 'vj/components/notification/index';
import { AutoloadPage } from 'vj/misc/Page';
import i18n from 'vj/utils/i18n';
export default new AutoloadPage('notificationPage', (pagename) => {
@@ -1,7 +1,8 @@
import { NamedPage } from 'vj/misc/Page';
import $ from 'jquery';
import { InfoDialog } from 'vj/components/dialog';
import tpl from 'vj/utils/tpl';
import { NamedPage } from 'vj/misc/Page';
import i18n from 'vj/utils/i18n';
import tpl from 'vj/utils/tpl';
export default new NamedPage(['problem_create', 'problem_edit'], () => {
$('input[name="pid"]').on('blur', () => {
@@ -1,3 +1,4 @@
import $ from 'jquery';
import { AutoloadPage } from 'vj/misc/Page';
export default new AutoloadPage('problemListPage', () => {
@@ -1,8 +1,8 @@
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import i18n from 'vj/utils/i18n';
import type { RootState } from './reducer/index';
import FileSelectAutoComplete from '../autocomplete/components/FileSelectAutoComplete';
import type { RootState } from './reducer/index';
export function FormItem({
columns, label, children, helpText = '', disableLabel = false, ...props
@@ -1,11 +1,12 @@
import React from 'react';
import type { editor } from 'monaco-editor';
import { connect } from 'react-redux';
import { load } from 'vj/components/monaco/loader';
import Editor from 'vj/components/editor';
import { diffLines } from 'diff';
import yaml from 'js-yaml';
import type { ProblemConfigFile, TestCaseConfig } from 'hydrooj/src/interface';
import $ from 'jquery';
import yaml from 'js-yaml';
import type { editor } from 'monaco-editor';
import React from 'react';
import { connect } from 'react-redux';
import Editor from 'vj/components/editor';
import { load } from 'vj/components/monaco/loader';
const mapStateToProps = (state) => ({
config: state.config,
@@ -1,14 +1,14 @@
import {
Card, InputGroup, Tab, Tabs, Tag,
} from '@blueprintjs/core';
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import i18n from 'vj/utils/i18n';
import {
Card, Tab, Tabs, InputGroup, Tag,
} from '@blueprintjs/core';
import type { RootState } from './reducer/index';
import CustomSelectAutoComplete from '../autocomplete/components/CustomSelectAutoComplete';
import FileSelectAutoComplete from '../autocomplete/components/FileSelectAutoComplete';
import { FormItem } from './BasicForm';
import ProblemType from './ProblemType';
import type { RootState } from './reducer/index';
import { TaskConfig } from './SubtaskTable';
function FileIOConfig() {
@@ -1,11 +1,11 @@
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import i18n from 'vj/utils/i18n';
import {
Card, Switch, Tab, Tabs,
} from '@blueprintjs/core';
import type { RootState } from './reducer/index';
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import i18n from 'vj/utils/i18n';
import { FormItem, ManagedSelect, SingleFileSelect } from './BasicForm';
import type { RootState } from './reducer/index';
export default function ProblemType() {
const Type = useSelector((state: RootState) => state.config.type);
@@ -1,9 +1,9 @@
import { Card, NumericInput, Tag } from '@blueprintjs/core';
import { pick, isEqual } from 'lodash';
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { parseMemoryMB, parseTimeMS } from '@hydrooj/utils/lib/common';
import { SubtaskConfig } from 'hydrooj/src/interface';
import { parseTimeMS, parseMemoryMB } from '@hydrooj/utils/lib/common';
import { isEqual, pick } from 'lodash';
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import i18n from 'vj/utils/i18n';
import CustomSelectAutoComplete from '../autocomplete/components/CustomSelectAutoComplete';
import { FormItem } from './BasicForm';
@@ -1,12 +1,12 @@
import { NumericInput, Tag } from '@blueprintjs/core';
import { parseMemoryMB, parseTimeMS } from '@hydrooj/utils/lib/common';
import type { SubtaskConfig } from 'hydrooj/src/interface';
import { isEqual } from 'lodash';
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import i18n from 'vj/utils/i18n';
import { isEqual } from 'lodash';
import { Tag, NumericInput } from '@blueprintjs/core';
import { parseTimeMS, parseMemoryMB } from '@hydrooj/utils/lib/common';
import type { SubtaskConfig } from 'hydrooj/src/interface';
import type { RootState } from './reducer/index';
import FileSelectAutoComplete from '../autocomplete/components/FileSelectAutoComplete';
import type { RootState } from './reducer/index';
const eq = (a: SubtaskConfig, b: SubtaskConfig) => isEqual(a, b);
const eqArr = (a: any[], b: any[]) => isEqual(a, b);
@@ -1,7 +1,7 @@
import yaml from 'js-yaml';
import type { ProblemConfigFile } from 'hydrooj/src/interface';
import { cloneDeep } from 'lodash';
import { parseMemoryMB, parseTimeMS } from '@hydrooj/utils/lib/common';
import type { ProblemConfigFile } from 'hydrooj/src/interface';
import yaml from 'js-yaml';
import { cloneDeep } from 'lodash';
type State = ProblemConfigFile & { __loaded: boolean };
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types';
import classNames from 'classnames';
import PropTypes from 'prop-types';
export default function SplitPaneFillOverlayComponent(props) {
const {
@@ -1,5 +1,6 @@
import React from 'react';
import $ from 'jquery';
import { omit } from 'lodash';
import React from 'react';
const tempDoms = {};
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types';
import classNames from 'classnames';
import PropTypes from 'prop-types';
export default function IconComponent(props) {
const {
@@ -1,3 +1,4 @@
import $ from 'jquery';
import _ from 'lodash';
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
import delay from 'vj/utils/delay';
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types';
import classNames from 'classnames';
import PropTypes from 'prop-types';
export default function DataInputComponent(props) {
const {
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types';
import classNames from 'classnames';
import PropTypes from 'prop-types';
export default function PanelButtonComponent(props) {
const {
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import SplitPaneFillOverlay from 'vj/components/react-splitpane/SplitPaneFillOverlayComponent';
export default function PanelComponent(props) {
@@ -1,11 +1,10 @@
import AnsiUp from 'ansi_up';
import React from 'react';
import { connect } from 'react-redux';
import AnsiUp from 'ansi_up';
import i18n from 'vj/utils/i18n';
import Icon from 'vj/components/react/IconComponent';
import Panel from './PanelComponent';
import i18n from 'vj/utils/i18n';
import DataInput from './DataInputComponent';
import Panel from './PanelComponent';
const AU = new AnsiUp();
@@ -1,8 +1,8 @@
import classNames from 'classnames';
import React from 'react';
import { connect } from 'react-redux';
import classNames from 'classnames';
import i18n from 'vj/utils/i18n';
import Icon from 'vj/components/react/IconComponent';
import i18n from 'vj/utils/i18n';
import Panel from './PanelComponent';
import ScratchpadRecordsRow from './ScratchpadRecordsRowContainer';
@@ -1,15 +1,14 @@
import React from 'react';
import classNames from 'classnames';
import _ from 'lodash';
import moment from 'moment';
import React from 'react';
import { connect } from 'react-redux';
import TimeAgo from 'timeago-react';
import moment from 'moment';
import _ from 'lodash';
import substitute from 'vj/utils/substitute';
import emulateAnchorClick from 'vj/utils/emulateAnchorClick';
import { parse as parseMongoId } from 'vj/utils/mongoId';
import i18n from 'vj/utils/i18n';
import * as recordEnum from 'vj/constant/record';
import emulateAnchorClick from 'vj/utils/emulateAnchorClick';
import i18n from 'vj/utils/i18n';
import { parse as parseMongoId } from 'vj/utils/mongoId';
import substitute from 'vj/utils/substitute';
const shouldShowDetail = (data) => recordEnum.STATUS_SCRATCHPAD_SHOW_DETAIL_FLAGS[data.status];
@@ -1,16 +1,15 @@
/* eslint-disable react/static-property-placement */
import _ from 'lodash';
import React from 'react';
import PropTypes from 'prop-types';
import React from 'react';
import { connect } from 'react-redux';
import i18n from 'vj/utils/i18n';
import request from 'vj/utils/request';
import Icon from 'vj/components/react/IconComponent';
import getAvailableLangs from 'vj/utils/availableLangs';
import i18n from 'vj/utils/i18n';
import request from 'vj/utils/request';
import Toolbar, {
ToolbarItemComponent as ToolbarItem,
ToolbarButtonComponent as ToolbarButton,
ToolbarItemComponent as ToolbarItem,
ToolbarSplitComponent as ToolbarSplit,
} from './ToolbarComponent';
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types';
import classNames from 'classnames';
import PropTypes from 'prop-types';
export default function ToolbarComponent(props) {
const {
@@ -1,14 +1,15 @@
import React from 'react';
import SplitPane from 'react-split-pane';
import { useDispatch, useSelector } from 'react-redux';
import _ from 'lodash';
import SplitPaneFillOverlay from 'vj/components/react-splitpane/SplitPaneFillOverlayComponent';
import ProblemIcon from '@vscode/codicons/src/icons/file.svg?react';
import $ from 'jquery';
import _ from 'lodash';
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import SplitPane from 'react-split-pane';
import Dom from 'vj/components/react/DomComponent';
import ScratchpadToolbar from './ScratchpadToolbarContainer';
import SplitPaneFillOverlay from 'vj/components/react-splitpane/SplitPaneFillOverlayComponent';
import ScratchpadEditor from './ScratchpadEditorContainer';
import ScratchpadPretest from './ScratchpadPretestContainer';
import ScratchpadRecords from './ScratchpadRecordsContainer';
import ScratchpadToolbar from './ScratchpadToolbarContainer';
function buildNestedPane([a, ...panes], mode = 'horizontal') {
const elements = [
@@ -1,9 +1,9 @@
import { combineReducers } from 'redux';
import ui from './ui';
import editor from './editor';
import pretest from './pretest';
import records from './records';
import state from './state';
import ui from './ui';
const reducer = combineReducers({
ui,
@@ -1,9 +1,10 @@
import { AutoloadPage } from 'vj/misc/Page';
import $ from 'jquery';
import responsiveCutoff from 'vj/breakpoints.json';
import DomDialog from 'vj/components/dialog/DomDialog';
import { InfoDialog } from 'vj/components/dialog/index';
import responsiveCutoff from 'vj/breakpoints.json';
import { isBelow } from 'vj/utils/mediaQuery';
import { AutoloadPage } from 'vj/misc/Page';
import i18n from 'vj/utils/i18n';
import { isBelow } from 'vj/utils/mediaQuery';
import tpl from 'vj/utils/tpl';
const signinDialogPage = new AutoloadPage('signinDialogPage', null, () => {
@@ -1,4 +1,6 @@
import 'jquery.easing';
import $ from 'jquery';
import { AutoloadPage } from 'vj/misc/Page';
const smoothScrollPage = new AutoloadPage('smoothScrollPage', null, () => {
@@ -1,3 +1,4 @@
import $ from 'jquery';
import { AutoloadPage } from 'vj/misc/Page';
import request from 'vj/utils/request';
@@ -1,8 +1,10 @@
import 'sticky-kit/dist/sticky-kit';
import $ from 'jquery';
import _ from 'lodash';
import { isBelow, isAbove } from 'vj/utils/mediaQuery';
import { AutoloadPage } from 'vj/misc/Page';
import responsiveCutoff from 'vj/breakpoints.json';
import { AutoloadPage } from 'vj/misc/Page';
import { isAbove, isBelow } from 'vj/utils/mediaQuery';
const navHeight = isBelow(responsiveCutoff.mobile)
? 0
@@ -1,3 +1,4 @@
import $ from 'jquery';
import _ from 'lodash';
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
@@ -1,8 +1,10 @@
import 'sticky-kit/dist/sticky-kit';
import $ from 'jquery';
import _ from 'lodash';
import responsiveCutoff from 'vj/breakpoints.json';
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
import { isBelow } from 'vj/utils/mediaQuery';
import responsiveCutoff from 'vj/breakpoints.json';
const navHeight = isBelow(responsiveCutoff.mobile)
? 0
@@ -1,3 +1,4 @@
import $ from 'jquery';
import * as timeago from 'timeago.js';
import { AutoloadPage } from 'vj/misc/Page';
import i18n from 'vj/utils/i18n';
@@ -1,5 +1,5 @@
import Drop from 'tether-drop';
import _ from 'lodash';
import Drop from 'tether-drop';
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
export default class Tooltip extends DOMAttachedObject {
@@ -1,3 +1,4 @@
import $ from 'jquery';
import { AutoloadPage } from 'vj/misc/Page';
import Tooltip from './Tooltip';
@@ -1,3 +1,4 @@
import $ from 'jquery';
import Rotator from 'vj/components/rotator';
import { AutoloadPage } from 'vj/misc/Page';
import request from 'vj/utils/request';
@@ -1,12 +1,12 @@
import { dump } from 'js-yaml';
import PQueue from 'p-queue';
import streamsaver from 'streamsaver';
import { createZipStream } from 'vj/utils/zip';
import pipeStream from 'vj/utils/pipeStream';
import i18n from 'vj/utils/i18n';
import request from 'vj/utils/request';
import PQueue from 'p-queue/dist/index';
import Notification from 'vj/components/notification';
import api, { gql } from 'vj/utils/api';
import i18n from 'vj/utils/i18n';
import pipeStream from 'vj/utils/pipeStream';
import request from 'vj/utils/request';
import { createZipStream } from 'vj/utils/zip';
let isBeforeUnloadTriggeredByLibrary = !window.isSecureContext;
function onBeforeUnload(e) {
+1
View File
@@ -1,3 +1,4 @@
import $ from 'jquery';
import * as bus from './bus';
window.Hydro = {
+8 -8
View File
@@ -1,19 +1,19 @@
/* eslint-disable no-return-await */
/* eslint-disable camelcase */
import crypto from 'crypto';
import { join } from 'path';
import { ObjectID } from 'mongodb';
import * as bus from 'hydrooj/src/service/bus';
import { Route, Handler } from 'hydrooj/src/service/server';
import esbuild from 'esbuild';
import { PERM, PRIV } from 'hydrooj/src/model/builtin';
import * as system from 'hydrooj/src/model/system';
import user from 'hydrooj/src/model/user';
import * as contest from 'hydrooj/src/model/contest';
import problem from 'hydrooj/src/model/problem';
import * as setting from 'hydrooj/src/model/setting';
import esbuild from 'esbuild';
import { tmpdir } from 'os';
import * as system from 'hydrooj/src/model/system';
import user from 'hydrooj/src/model/user';
import * as bus from 'hydrooj/src/service/bus';
import { UiContextBase } from 'hydrooj/src/service/layers/base';
import { Handler, Route } from 'hydrooj/src/service/server';
import { ObjectID } from 'mongodb';
import { tmpdir } from 'os';
import { join } from 'path';
import markdown from './backendlib/markdown';
declare module 'hydrooj/src/interface' {
+2
View File
@@ -1,5 +1,7 @@
import './modules';
import 'jquery.transit';
import $ from 'jquery';
import _ from 'lodash';
import Notification from 'vj/components/notification';
import PageLoader from 'vj/misc/PageLoader';
@@ -9,7 +9,7 @@
font-style: normal
.icon
font-family: $icon-font-name, $primary-font-family !important
font-family: $icon-font-name !important
speak: none
font-style: normal
font-weight: normal
+6 -7
View File
@@ -1,9 +1,3 @@
import $ from 'jquery';
import _ from 'lodash';
import React from 'react';
import ReactDOM from 'react-dom';
import * as redux from 'react-redux';
import './utils/delay';
import './utils/emulateAnchorClick';
import './utils/i18n';
@@ -19,13 +13,18 @@ import './utils/substitute';
import './utils/tpl';
import './utils/zIndexManager';
import './utils/zip';
import './components/autocomplete';
import './components/dialog';
import './components/notification';
import './components/nprogress';
import './components/monaco/loader';
import $ from 'jquery';
import _ from 'lodash';
import React from 'react';
import ReactDOM from 'react-dom';
import * as redux from 'react-redux';
const modules = {
_, $, React, redux, ReactDOM,
};
+12 -14
View File
@@ -1,6 +1,6 @@
{
"name": "@hydrooj/ui-default",
"version": "4.38.34",
"version": "4.39.0",
"author": "undefined <i@undefined.moe>",
"license": "AGPL-3.0",
"main": "hydro.js",
@@ -20,7 +20,7 @@
"@fontsource/source-code-pro": "^4.5.10",
"@fontsource/ubuntu-mono": "^4.5.10",
"@hydrooj/utils": "workspace:*",
"@svgr/webpack": "^5",
"@svgr/webpack": "^6.3.1",
"@types/gulp-if": "^0.0.34",
"@types/jquery": "^3.5.14",
"@types/json-schema": "^7.0.11",
@@ -30,15 +30,15 @@
"@types/qrcode": "^1.4.2",
"@types/react-dom": "^18.0.6",
"@types/redux-logger": "^3.0.9",
"autoprefixer": "^9.8.8",
"autoprefixer": "^10.4.8",
"browser-update": "^3.3.38",
"chalk": "^5.0.1",
"chunk-progress-webpack-plugin": "^2.0.1",
"classnames": "^2.3.1",
"clean-webpack-plugin": "^4.0.0",
"clipboard": "^2.0.11",
"copy-webpack-plugin": "^6.4.1",
"css-loader": "^4.3.0",
"copy-webpack-plugin": "^11.0.0",
"css-loader": "^6.7.1",
"diff": "^5.1.0",
"diff-dom": "^4.2.3",
"echarts": "^5.3.3",
@@ -46,7 +46,6 @@
"emojis-list": "2.1.0",
"esbuild-loader": "^2.19.0",
"fancy-log": "^2.0.0",
"file-loader": "^6.2.0",
"friendly-errors-webpack-plugin": "^1.7.0",
"graphiql": "1.8.9",
"gulp": "^4.0.2",
@@ -71,14 +70,13 @@
"normalize.css": "^8.0.1",
"nprogress": "^0.2.0",
"pickadate": "^3.6.4",
"plugin-error": "^1.0.1",
"postcss-loader": "^3.0.0",
"plugin-error": "^2.0.0",
"postcss-loader": "^7.0.1",
"prism-themes": "^1.9.0",
"prismjs": "^1.28.0",
"prop-types": "^15.8.1",
"qrcode": "^1.5.1",
"queue-microtask": "^1.2.3",
"raw-loader": "^4.0.2",
"react": "^18.2.0",
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
@@ -94,10 +92,10 @@
"slideout": "^1.0.1",
"speed-measure-webpack-plugin": "^1.5.0",
"sticky-kit": "^1.1.3",
"style-loader": "^2.0.0",
"style-loader": "^3.3.1",
"stylus": "^0.58.1",
"stylus-loader": "^3.0.2",
"tether": "^1.4.7",
"stylus-loader": "^7.0.0",
"tether": "1.4.7",
"tether-drop": "^1.4.2",
"thirty-two": "^1.0.2",
"through2": "^4.0.2",
@@ -106,9 +104,9 @@
"vditor": "^3.8.15",
"vinyl-buffer": "^1.0.1",
"web-streams-polyfill": "^3.2.1",
"webpack": "^4.46.0",
"webpack": "^5.74.0",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-dev-server": "^3.11.3",
"webpack-dev-server": "^4.9.3",
"webpackbar": "^5.0.2"
},
"dependencies": {
+4 -3
View File
@@ -1,9 +1,10 @@
/* eslint-disable react/function-component-definition */
import { NamedPage } from 'vj/misc/Page';
import request from 'vj/utils/request';
import 'graphiql/graphiql.css';
import React from 'react';
import ReactDOM from 'react-dom/client';
import 'graphiql/graphiql.css';
import { NamedPage } from 'vj/misc/Page';
import request from 'vj/utils/request';
const Logo = () => <span>Hydro API Console </span>;
const defaultQuery = `\
@@ -1,9 +1,10 @@
import { NamedPage } from 'vj/misc/Page';
import { ConfirmDialog } from 'vj/components/dialog';
import $ from 'jquery';
import ProblemSelectAutoComplete from 'vj/components/autocomplete/ProblemSelectAutoComplete';
import tpl from 'vj/utils/tpl';
import { ConfirmDialog } from 'vj/components/dialog';
import { NamedPage } from 'vj/misc/Page';
import i18n from 'vj/utils/i18n';
import request from 'vj/utils/request';
import tpl from 'vj/utils/tpl';
const page = new NamedPage(['contest_edit', 'contest_create', 'homework_create', 'homework_edit'], (pagename) => {
ProblemSelectAutoComplete.getOrConstruct($('[name="pids"]'), { multi: true, clearDefaultValue: false });
@@ -1,3 +1,4 @@
import $ from 'jquery';
import { NamedPage } from 'vj/misc/Page';
const page = new NamedPage('contest_main', () => {
Loaded 100 of 134 files, more files were not shown because too many files have changed in this diff. Show more