批量修改
This commit is contained in:
BIN
scratch-gui/competitio_login/assets/gongan-beian.png
Normal file
BIN
scratch-gui/competitio_login/assets/gongan-beian.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@@ -384,7 +384,7 @@
|
|||||||
<footer>
|
<footer>
|
||||||
<div class="footer-line" role="presentation"></div>
|
<div class="footer-line" role="presentation"></div>
|
||||||
<p class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
<p class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
||||||
<!-- 公安备案号:<a href="https://beian.mps.gov.cn/" target="_blank" style="color:#478ac9 ;">川公网安备51011202000980号</a> -->
|
公安备案号:<a href="https://beian.mps.gov.cn/#/query/webSearch?code=31011502407417" rel="noreferrer" target="_blank" style="color:#478ac9 ;"><img src="assets/gongan-beian.png" alt="" width="16" height="16" style="width:16px;height:16px;vertical-align:-3px;margin-right:4px;" />沪公网安备31011502407417号</a>
|
||||||
© 灵丌编程(001CODE.COM)</p>
|
© 灵丌编程(001CODE.COM)</p>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Regression tests for the editor's real interpreter and output callback.
|
// Regression tests for variable scopes in the editor interpreter.
|
||||||
// Run: node scripts/test-cpp-regressions.cjs
|
// Run: node scripts/test-cpp-regressions.cjs
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
@@ -32,19 +32,13 @@ int main() {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}`;
|
}`;
|
||||||
// The third screenshot reports cout without supplying a cout example.
|
|
||||||
// Add observable output to the supplied program to check both fixes together.
|
|
||||||
const customerEmailWithOutput = customerEmailCode.replace(' playerMove(i);',
|
|
||||||
' cout << "i=" << i << endl;\n playerMove(i);');
|
|
||||||
|
|
||||||
async function run(code, expected, configure) {
|
async function run(code, expected, configure) {
|
||||||
const moves = [];
|
const moves = [];
|
||||||
const turns = [];
|
const turns = [];
|
||||||
const output = [];
|
|
||||||
context.window = {isScriptRunOver: false, cppGameAPI: {
|
context.window = {isScriptRunOver: false, cppGameAPI: {
|
||||||
playerMove: async n => moves.push(n),
|
playerMove: async n => moves.push(n),
|
||||||
turnLeft: async n => turns.push(n),
|
turnLeft: async n => turns.push(n),
|
||||||
cmdPrint: text => output.push(text)
|
cmdPrint: () => {}
|
||||||
}};
|
}};
|
||||||
const executor = new CppCodeExecutor(code, null);
|
const executor = new CppCodeExecutor(code, null);
|
||||||
if (configure) configure(executor, context.window);
|
if (configure) configure(executor, context.window);
|
||||||
@@ -53,7 +47,6 @@ async function run(code, expected, configure) {
|
|||||||
await executor.run();
|
await executor.run();
|
||||||
if (expected.moves) assert.deepStrictEqual(moves, expected.moves);
|
if (expected.moves) assert.deepStrictEqual(moves, expected.moves);
|
||||||
if (expected.turns) assert.deepStrictEqual(turns, expected.turns);
|
if (expected.turns) assert.deepStrictEqual(turns, expected.turns);
|
||||||
if (expected.output) assert.deepStrictEqual(output, expected.output);
|
|
||||||
assert.strictEqual(executor.variables, executor.globalVariables, 'scope must unwind after execution');
|
assert.strictEqual(executor.variables, executor.globalVariables, 'scope must unwind after execution');
|
||||||
assert.strictEqual(executor.callStack.length, 0);
|
assert.strictEqual(executor.callStack.length, 0);
|
||||||
return executor;
|
return executor;
|
||||||
@@ -61,12 +54,10 @@ async function run(code, expected, configure) {
|
|||||||
|
|
||||||
const cases = [
|
const cases = [
|
||||||
['customer email complete program (screenshots 1 and 2)', customerEmailCode, {moves: [0], turns: [-1]}],
|
['customer email complete program (screenshots 1 and 2)', customerEmailCode, {moves: [0], turns: [-1]}],
|
||||||
['customer email with variable output (screenshot 3)', customerEmailWithOutput, {moves: [0], turns: [-1], output: ['i=0\n']}],
|
|
||||||
['nested loops', main('for (int i = 0; i < 2; i++) {\nfor (int i = 0; i < 2; i++) {\n}\nplayerMove(i);\n}'), {moves: [0, 1]}],
|
['nested loops', main('for (int i = 0; i < 2; i++) {\nfor (int i = 0; i < 2; i++) {\n}\nplayerMove(i);\n}'), {moves: [0, 1]}],
|
||||||
['loop initializer restores shadowed value', main('int i = 9;\nfor (int i = 0; i < 2; i++) {\n}\nplayerMove(i);'), {moves: [9]}],
|
['loop initializer restores shadowed value', main('int i = 9;\nfor (int i = 0; i < 2; i++) {\n}\nplayerMove(i);'), {moves: [9]}],
|
||||||
['loop assignment updates existing value', main('int i = 9;\nfor (i = 0; i < 2; i++) {\n}\nplayerMove(i);'), {moves: [2]}],
|
['loop assignment updates existing value', main('int i = 9;\nfor (i = 0; i < 2; i++) {\n}\nplayerMove(i);'), {moves: [2]}],
|
||||||
['block declaration versus assignment', main('int n = 1;\nif (true) {\nint n = 7;\nplayerMove(n);\n}\nif (true) {\nn = 3;\n}\nplayerMove(n);'), {moves: [7, 3]}],
|
['block declaration versus assignment', main('int n = 1;\nif (true) {\nint n = 7;\nplayerMove(n);\n}\nif (true) {\nn = 3;\n}\nplayerMove(n);'), {moves: [7, 3]}],
|
||||||
['string block shadowing', main('string msg = "outer";\nif (true) {\nstring msg = "C++";\ncout << msg;\n}\ncout << msg;'), {output: ['C++', 'outer']}],
|
|
||||||
['for body scope per iteration', main('int x = 9;\nfor (int i = 0; i < 2; i++) {\nplayerMove(x);\nint x = 2;\n}\nplayerMove(x);'), {moves: [9, 9, 9]}],
|
['for body scope per iteration', main('int x = 9;\nfor (int i = 0; i < 2; i++) {\nplayerMove(x);\nint x = 2;\n}\nplayerMove(x);'), {moves: [9, 9, 9]}],
|
||||||
['while body scope per iteration', main('int x = 9;\nint i = 0;\nwhile (i < 2) {\nplayerMove(x);\nint x = 2;\ni++;\n}\nplayerMove(x);'), {moves: [9, 9, 9]}],
|
['while body scope per iteration', main('int x = 9;\nint i = 0;\nwhile (i < 2) {\nplayerMove(x);\nint x = 2;\ni++;\n}\nplayerMove(x);'), {moves: [9, 9, 9]}],
|
||||||
['function locals', 'void f() {\nint n = 7;\nplayerMove(n);\n}\n' + main('int n = 2;\nf();\nplayerMove(n);'), {moves: [7, 2]}],
|
['function locals', 'void f() {\nint n = 7;\nplayerMove(n);\n}\n' + main('int n = 2;\nf();\nplayerMove(n);'), {moves: [7, 2]}],
|
||||||
@@ -75,14 +66,6 @@ const cases = [
|
|||||||
['early void return unwinds scope', 'void f() {\nint n = 8;\nreturn;\n}\n' + main('int n = 2;\nf();\nplayerMove(n);'), {moves: [2]}],
|
['early void return unwinds scope', 'void f() {\nint n = 8;\nreturn;\n}\n' + main('int n = 2;\nf();\nplayerMove(n);'), {moves: [2]}],
|
||||||
['continue unwinds body scope', main('int x = 9;\nfor (int i = 0; i < 2; i++) {\nint x = 2;\ncontinue;\n}\nplayerMove(x);'), {moves: [9]}],
|
['continue unwinds body scope', main('int x = 9;\nfor (int i = 0; i < 2; i++) {\nint x = 2;\ncontinue;\n}\nplayerMove(x);'), {moves: [9]}],
|
||||||
['break does not increment', main('int i = 0;\nfor (i = 0; i < 2; i++) {\nbreak;\n}\nplayerMove(i);'), {moves: [0]}],
|
['break does not increment', main('int i = 0;\nfor (i = 0; i < 2; i++) {\nbreak;\n}\nplayerMove(i);'), {moves: [0]}],
|
||||||
['cout with equals', main('int i = 7;\ncout << "i=" << i << endl;'), {output: ['i=7\n']}],
|
|
||||||
['cout with operator text', main('cout << "value=42 C++ -- +=" << endl;'), {output: ['value=42 C++ -- +=\n']}],
|
|
||||||
['cout with game API text', main('cout << "playerMove(2)" << endl;'), {moves: [], output: ['playerMove(2)\n']}],
|
|
||||||
['qualified cout', main('std::cout << "Hello" << std::endl;'), {output: ['Hello\n']}],
|
|
||||||
['cout postfix and prefix', main('int i = 0;\ncout << i++ << endl;\ncout << ++i << endl;\ncout << i-- << endl;\ncout << --i << endl;'), {output: ['0\n', '2\n', '2\n', '0\n']}],
|
|
||||||
['cout arithmetic', main('int i = 3;\ncout << "result=" << (i * 2 + 1) << endl;'), {output: ['result=7\n']}],
|
|
||||||
['escaped quotes and stream delimiters', main(String.raw`cout << "a\"<<b\nC++" << endl;`), {output: ['a"<<b\nC++\n']}],
|
|
||||||
['consecutive output fragments', main('cout << "A";\ncout << "B" << endl;'), {output: ['A', 'B\n']}]
|
|
||||||
];
|
];
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
@@ -90,6 +73,15 @@ const cases = [
|
|||||||
try { await run(code, expected); } catch (error) {error.message = `${name}: ${error.message}`; throw error;}
|
try { await run(code, expected); } catch (error) {error.message = `${name}: ${error.message}`; throw error;}
|
||||||
console.log(`PASS ${name}`);
|
console.log(`PASS ${name}`);
|
||||||
}
|
}
|
||||||
|
const strings = new CppCodeExecutor('', null);
|
||||||
|
await strings.executeSimpleStatement('string msg = "outer";');
|
||||||
|
await strings.withVariableScope(async () => {
|
||||||
|
await strings.executeSimpleStatement('string msg = "inner";');
|
||||||
|
assert.strictEqual(strings.variables.get('msg'), 'inner');
|
||||||
|
});
|
||||||
|
assert.strictEqual(strings.variables.get('msg'), 'outer');
|
||||||
|
console.log('PASS string block shadowing');
|
||||||
|
|
||||||
// Seed the interpreter's global environment to verify lexical lookup and writes.
|
// Seed the interpreter's global environment to verify lexical lookup and writes.
|
||||||
const globalExecutor = await run('void f() {\ng += 1;\nplayerMove(g);\n}\n' + main('int g = 9;\nf();\nplayerMove(g);'), {moves: [2, 9]}, executor => executor.variables.set('g', 1));
|
const globalExecutor = await run('void f() {\ng += 1;\nplayerMove(g);\n}\n' + main('int g = 9;\nf();\nplayerMove(g);'), {moves: [2, 9]}, executor => executor.variables.set('g', 1));
|
||||||
assert.strictEqual(globalExecutor.variables.get('g'), 2);
|
assert.strictEqual(globalExecutor.variables.get('g'), 2);
|
||||||
@@ -112,51 +104,5 @@ const cases = [
|
|||||||
console.log(`PASS scope cleanup on ${stop ? 'stop' : 'error'}`);
|
console.log(`PASS scope cleanup on ${stop ? 'stop' : 'error'}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract the actual React component callback, avoiding a game-engine dependency.
|
console.log(`${cases.length + 4} regression checks passed`);
|
||||||
const uiPath = path.resolve(__dirname, '../src/components/stage-cpp/stage-cpp-clang.jsx');
|
|
||||||
const uiSource = fs.readFileSync(uiPath, 'utf8');
|
|
||||||
const ast = babel.parseSync(uiSource, {configFile: false, babelrc: false, parserOpts: {plugins: ['jsx']}});
|
|
||||||
let callback;
|
|
||||||
function visit(node) {
|
|
||||||
if (!node || typeof node !== 'object') return;
|
|
||||||
if (node.type === 'ObjectProperty' && node.key.name === 'cmdPrint') callback = node.value;
|
|
||||||
for (const value of Object.values(node)) {
|
|
||||||
if (Array.isArray(value)) value.forEach(visit);
|
|
||||||
else if (value && typeof value === 'object') visit(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
visit(ast);
|
|
||||||
assert(callback, 'cmdPrint callback exists');
|
|
||||||
for (const engineState of ['absent', 'ready', 'throwing']) {
|
|
||||||
let displayed = '';
|
|
||||||
const sent = [];
|
|
||||||
const window = {};
|
|
||||||
if (engineState !== 'absent') window.unityInstance = {SendMessage: (...args) => {
|
|
||||||
if (engineState === 'throwing') throw new Error('engine unavailable');
|
|
||||||
sent.push(args);
|
|
||||||
}};
|
|
||||||
const cmdPrint = vm.runInNewContext(`(${uiSource.slice(callback.start, callback.end)})`, {
|
|
||||||
window, console: silentConsole, setCompilationOutput: update => {displayed = update(displayed);}
|
|
||||||
});
|
|
||||||
cmdPrint('A');
|
|
||||||
cmdPrint('B\n');
|
|
||||||
assert.strictEqual(displayed, 'AB\n');
|
|
||||||
assert.strictEqual(window.cmd_print_text, 'AB\n');
|
|
||||||
if (engineState === 'ready') assert.deepStrictEqual(sent[1], ['UIMain', 'SetText', 'AB\n']);
|
|
||||||
console.log(`PASS output callback with ${engineState} engine`);
|
|
||||||
|
|
||||||
// Connect the real interpreter to the real UI callback, including repeated runs.
|
|
||||||
for (let attempt = 0; attempt < 2; attempt++) {
|
|
||||||
displayed = '';
|
|
||||||
window.cmd_print_text = '';
|
|
||||||
await run(customerEmailWithOutput, {moves: [0], turns: [-1]}, (executor, runtimeWindow) => {
|
|
||||||
runtimeWindow.cppGameAPI.cmdPrint = cmdPrint;
|
|
||||||
});
|
|
||||||
assert.strictEqual(displayed, 'i=0\n');
|
|
||||||
assert.strictEqual(window.cmd_print_text, 'i=0\n');
|
|
||||||
if (engineState === 'ready') assert.deepStrictEqual(sent[sent.length - 1], ['UIMain', 'SetText', 'i=0\n']);
|
|
||||||
}
|
|
||||||
console.log(`PASS customer program through output callback with ${engineState} engine`);
|
|
||||||
}
|
|
||||||
console.log(`${cases.length + 9} regression checks passed`);
|
|
||||||
})().catch(error => {console.error(error); process.exitCode = 1;});
|
})().catch(error => {console.error(error); process.exitCode = 1;});
|
||||||
|
|||||||
@@ -1373,12 +1373,6 @@ export class CppCodeExecutor {
|
|||||||
async executeSimpleStatement(content) {
|
async executeSimpleStatement(content) {
|
||||||
debugLog(`🔍 执行简单语句: ${content}`);
|
debugLog(`🔍 执行简单语句: ${content}`);
|
||||||
|
|
||||||
// 先识别输出语句,避免把字符串里的 =、++、游戏函数名当作代码执行。
|
|
||||||
if (/^\s*(?:std\s*::\s*)?cout\s*<</.test(content)) {
|
|
||||||
this.executeCoutStatement(content);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 声明必须留在当前作用域,不能按普通赋值覆盖外层同名变量。
|
// 声明必须留在当前作用域,不能按普通赋值覆盖外层同名变量。
|
||||||
const declaration = content.match(/^\s*(int|bool|Position|string)\s+(\w+)\s*=\s*(.+);\s*$/);
|
const declaration = content.match(/^\s*(int|bool|Position|string)\s+(\w+)\s*=\s*(.+);\s*$/);
|
||||||
if (declaration) {
|
if (declaration) {
|
||||||
@@ -1542,6 +1536,9 @@ export class CppCodeExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else if (content.includes('cout')) {
|
||||||
|
// 解析复杂的cout输出语句
|
||||||
|
this.executeCoutStatement(content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2226,7 +2223,7 @@ export class CppCodeExecutor {
|
|||||||
// 处理复杂的cout语句
|
// 处理复杂的cout语句
|
||||||
executeCoutStatement(content) {
|
executeCoutStatement(content) {
|
||||||
// 移除cout和分号,获取输出内容
|
// 移除cout和分号,获取输出内容
|
||||||
const coutContent = content.replace(/^\s*(?:std\s*::\s*)?cout\s*/, '').replace(/;\s*$/, '');
|
let coutContent = content.replace(/^\s*cout\s*/, '').replace(/;\s*$/, '');
|
||||||
|
|
||||||
// 按 << 分割
|
// 按 << 分割
|
||||||
const parts = this.splitCoutParts(coutContent);
|
const parts = this.splitCoutParts(coutContent);
|
||||||
@@ -2236,14 +2233,14 @@ export class CppCodeExecutor {
|
|||||||
for (const part of parts) {
|
for (const part of parts) {
|
||||||
const trimmedPart = part.trim();
|
const trimmedPart = part.trim();
|
||||||
|
|
||||||
if (/^(?:std\s*::\s*)?endl$/.test(trimmedPart)) {
|
if (trimmedPart === 'endl') {
|
||||||
output += '\n';
|
output += '\n';
|
||||||
} else if (trimmedPart.startsWith('"') && trimmedPart.endsWith('"')) {
|
} else if (trimmedPart.startsWith('"') && trimmedPart.endsWith('"')) {
|
||||||
// 字符串字面量
|
// 字符串字面量
|
||||||
output += this.decodeStringLiteral(trimmedPart);
|
output += trimmedPart.slice(1, -1);
|
||||||
} else if (trimmedPart.startsWith("'") && trimmedPart.endsWith("'")) {
|
} else if (trimmedPart.startsWith("'") && trimmedPart.endsWith("'")) {
|
||||||
// 字符字面量
|
// 字符字面量
|
||||||
output += this.decodeStringLiteral(trimmedPart);
|
output += trimmedPart.slice(1, -1);
|
||||||
} else if (trimmedPart.startsWith('(') && trimmedPart.endsWith(')')) {
|
} else if (trimmedPart.startsWith('(') && trimmedPart.endsWith(')')) {
|
||||||
// 括号表达式
|
// 括号表达式
|
||||||
const expr = trimmedPart.slice(1, -1);
|
const expr = trimmedPart.slice(1, -1);
|
||||||
@@ -2258,13 +2255,7 @@ export class CppCodeExecutor {
|
|||||||
window.cppGameAPI.cmdPrint(output);
|
window.cppGameAPI.cmdPrint(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解码输出中的常用 C++ 转义字符。
|
// 智能分割cout的各个部分
|
||||||
decodeStringLiteral(literal) {
|
|
||||||
const escapes = {n: '\n', r: '\r', t: '\t', '0': '\0', '\\': '\\', '"': '"', "'": "'"};
|
|
||||||
return literal.slice(1, -1).replace(/\\([nrt0\\"'])/g, (match, char) => escapes[char]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 按字符串和括号边界分割输出流。
|
|
||||||
splitCoutParts(content) {
|
splitCoutParts(content) {
|
||||||
const parts = [];
|
const parts = [];
|
||||||
let current = '';
|
let current = '';
|
||||||
@@ -2275,12 +2266,6 @@ export class CppCodeExecutor {
|
|||||||
for (let i = 0; i < content.length; i++) {
|
for (let i = 0; i < content.length; i++) {
|
||||||
const char = content[i];
|
const char = content[i];
|
||||||
const nextChar = content[i + 1];
|
const nextChar = content[i + 1];
|
||||||
|
|
||||||
if (inString && char === '\\' && nextChar !== undefined) {
|
|
||||||
current += char + nextChar;
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!inString && inParens === 0 && char === '<' && nextChar === '<') {
|
if (!inString && inParens === 0 && char === '<' && nextChar === '<') {
|
||||||
// 遇到 << 分隔符
|
// 遇到 << 分隔符
|
||||||
@@ -2321,11 +2306,6 @@ export class CppCodeExecutor {
|
|||||||
expr = expr.trim().replace(/;$/, '');
|
expr = expr.trim().replace(/;$/, '');
|
||||||
debugLog(`🔍 计算表达式: ${expr}`);
|
debugLog(`🔍 计算表达式: ${expr}`);
|
||||||
|
|
||||||
// 字符串中的 ++、-- 和函数名都是文本,不参与表达式运算。
|
|
||||||
if (/^("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')$/.test(expr)) {
|
|
||||||
return this.decodeStringLiteral(expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 布尔常量
|
// 布尔常量
|
||||||
if (expr === 'true') {
|
if (expr === 'true') {
|
||||||
debugLog(`🔍 布尔常量: true = 1`);
|
debugLog(`🔍 布尔常量: true = 1`);
|
||||||
@@ -2380,7 +2360,7 @@ export class CppCodeExecutor {
|
|||||||
const newValue = currentValue + 1;
|
const newValue = currentValue + 1;
|
||||||
this.variables.set(varName, newValue);
|
this.variables.set(varName, newValue);
|
||||||
console.log(`🔄 自增操作: ${expr} (${currentValue} -> ${newValue})`);
|
console.log(`🔄 自增操作: ${expr} (${currentValue} -> ${newValue})`);
|
||||||
return expr.startsWith('++') ? newValue : currentValue;
|
return newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expr.includes('--')) {
|
if (expr.includes('--')) {
|
||||||
@@ -2398,7 +2378,7 @@ export class CppCodeExecutor {
|
|||||||
const newValue = currentValue - 1;
|
const newValue = currentValue - 1;
|
||||||
this.variables.set(varName, newValue);
|
this.variables.set(varName, newValue);
|
||||||
console.log(`🔄 自减操作: ${expr} (${currentValue} -> ${newValue})`);
|
console.log(`🔄 自减操作: ${expr} (${currentValue} -> ${newValue})`);
|
||||||
return expr.startsWith('--') ? newValue : currentValue;
|
return newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 游戏API函数调用
|
// 游戏API函数调用
|
||||||
@@ -2428,6 +2408,12 @@ export class CppCodeExecutor {
|
|||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 整个表达式是字符串字面量时才当字符串;含引号的 API 调用走后面的算术解析
|
||||||
|
if ((expr.startsWith('"') && expr.endsWith('"')) ||
|
||||||
|
(expr.startsWith("'") && expr.endsWith("'"))) {
|
||||||
|
return expr.slice(1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
return this.parseComplexExpression(expr);
|
return this.parseComplexExpression(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -645,21 +645,17 @@ const StageWrapperCppClang = () => {
|
|||||||
textStr = String(text);
|
textStr = String(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// cout 自己决定何时换行,连续输出应保持在同一行。
|
window.cmd_print_text += textStr + '\n';
|
||||||
window.cmd_print_text += textStr;
|
|
||||||
const lines = window.cmd_print_text.split('\n');
|
const lines = window.cmd_print_text.split('\n');
|
||||||
if (lines.length > 20) {
|
if (lines.length > 20) {
|
||||||
window.cmd_print_text = lines.slice(lines.length - 20).join('\n');
|
window.cmd_print_text = lines.slice(lines.length - 20).join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
setCompilationOutput(prev => prev + textStr);
|
|
||||||
if (window.unityInstance) {
|
if (window.unityInstance) {
|
||||||
try {
|
window.unityInstance.SendMessage("UIMain", "SetText", window.cmd_print_text);
|
||||||
window.unityInstance.SendMessage("UIMain", "SetText", window.cmd_print_text);
|
|
||||||
} catch (error) {
|
|
||||||
console.warn('游戏画面输出失败,文本仍可在运行输出中查看', error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setCompilationOutput(prev => prev + textStr + "\n");
|
||||||
},
|
},
|
||||||
|
|
||||||
player_data: (direction) => {
|
player_data: (direction) => {
|
||||||
@@ -799,7 +795,6 @@ const StageWrapperCppClang = () => {
|
|||||||
setCompilationOutput(prev => prev + "语法检查通过!\n");
|
setCompilationOutput(prev => prev + "语法检查通过!\n");
|
||||||
|
|
||||||
// 重置停止标志
|
// 重置停止标志
|
||||||
window.cmd_print_text = '';
|
|
||||||
window.isScriptRunOver = false;
|
window.isScriptRunOver = false;
|
||||||
setIsRunning(true);
|
setIsRunning(true);
|
||||||
setOverlayActive(true);
|
setOverlayActive(true);
|
||||||
@@ -974,7 +969,7 @@ const StageWrapperCppClang = () => {
|
|||||||
<div className={styles.errorModalOverlay}>
|
<div className={styles.errorModalOverlay}>
|
||||||
<div className={styles.errorModal}>
|
<div className={styles.errorModal}>
|
||||||
<div className={styles.errorModalHeader}>
|
<div className={styles.errorModalHeader}>
|
||||||
<h3>运行输出</h3>
|
<h3>编译信息</h3>
|
||||||
<div style={{ display: 'flex', gap: '10px' }}>
|
<div style={{ display: 'flex', gap: '10px' }}>
|
||||||
<button
|
<button
|
||||||
onClick={() => setCompilationOutput('')}
|
onClick={() => setCompilationOutput('')}
|
||||||
@@ -1126,13 +1121,6 @@ const StageWrapperCppClang = () => {
|
|||||||
<div className={styles.apiDrawer}>
|
<div className={styles.apiDrawer}>
|
||||||
<div className={styles.apiDrawerHeader}>
|
<div className={styles.apiDrawerHeader}>
|
||||||
<h3>🔧 C++ API参考</h3>
|
<h3>🔧 C++ API参考</h3>
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={styles.apiDrawerInsertButton}
|
|
||||||
onClick={() => setCompilationModalVisible(true)}
|
|
||||||
>
|
|
||||||
查看输出
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.apiDrawerContent}>
|
<div className={styles.apiDrawerContent}>
|
||||||
|
|||||||
@@ -1358,7 +1358,7 @@
|
|||||||
<footer class="footer" aria-label="页脚">
|
<footer class="footer" aria-label="页脚">
|
||||||
<div class="footer-line"></div>
|
<div class="footer-line"></div>
|
||||||
<div class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
<div class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
||||||
<!-- 公安备案号:<a href="https://beian.mps.gov.cn/" target="_blank" style="color:#478ac9 ;">川公网安备51011202000980号</a> -->
|
公安备案号:<a href="https://beian.mps.gov.cn/#/query/webSearch?code=31011502407417" rel="noreferrer" target="_blank" style="color:#478ac9 ;"><img src="../images/gongan-beian.png" alt="" width="16" height="16" style="width:16px;height:16px;vertical-align:-3px;margin-right:4px;" />沪公网安备31011502407417号</a>
|
||||||
© 灵丌编程(001CODE.COM)
|
© 灵丌编程(001CODE.COM)
|
||||||
<span class="qr" tabindex="0">
|
<span class="qr" tabindex="0">
|
||||||
<img class="qr-icon" src="../images/qrcode_gery.svg" alt="公众号小图标" />
|
<img class="qr-icon" src="../images/qrcode_gery.svg" alt="公众号小图标" />
|
||||||
|
|||||||
@@ -1537,7 +1537,7 @@
|
|||||||
|
|
||||||
<footer class="footer" aria-label="页脚">
|
<footer class="footer" aria-label="页脚">
|
||||||
<div class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
<div class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
||||||
<!-- 公安备案号:<a href="https://beian.mps.gov.cn/" target="_blank" style="color:#478ac9 ;">川公网安备51011202000980号</a> -->
|
公安备案号:<a href="https://beian.mps.gov.cn/#/query/webSearch?code=31011502407417" rel="noreferrer" target="_blank" style="color:#478ac9 ;"><img src="../images/gongan-beian.png" alt="" width="16" height="16" style="width:16px;height:16px;vertical-align:-3px;margin-right:4px;" />沪公网安备31011502407417号</a>
|
||||||
© 灵丌编程(001CODE.COM)
|
© 灵丌编程(001CODE.COM)
|
||||||
<span class="qr" tabindex="0">
|
<span class="qr" tabindex="0">
|
||||||
<img class="qr-icon" src="../images/qrcode_gery.svg" alt="公众号小图标" />
|
<img class="qr-icon" src="../images/qrcode_gery.svg" alt="公众号小图标" />
|
||||||
|
|||||||
@@ -88,7 +88,7 @@
|
|||||||
<footer>
|
<footer>
|
||||||
<div class="footer-line"></div>
|
<div class="footer-line"></div>
|
||||||
<p class="footer-text">ICP备案号:<a style="color:#478ac9 ;" href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">沪ICP备2026042325号</a>
|
<p class="footer-text">ICP备案号:<a style="color:#478ac9 ;" href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">沪ICP备2026042325号</a>
|
||||||
<!-- 公安备案号:<a style="color:#478ac9 ;" href="https://beian.mps.gov.cn/" target="_blank">川公网安备51011202000980号</a> -->
|
公安备案号:<a href="https://beian.mps.gov.cn/#/query/webSearch?code=31011502407417" rel="noreferrer" target="_blank" style="color:#478ac9 ;"><img src="../images/gongan-beian.png" alt="" width="16" height="16" style="width:16px;height:16px;vertical-align:-3px;margin-right:4px;" />沪公网安备31011502407417号</a>
|
||||||
© 灵丌编程(001CODE.COM)</p>
|
© 灵丌编程(001CODE.COM)</p>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -917,7 +917,7 @@
|
|||||||
<footer class="footer" aria-label="页脚">
|
<footer class="footer" aria-label="页脚">
|
||||||
<div class="footer-line"></div>
|
<div class="footer-line"></div>
|
||||||
<div class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
<div class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
||||||
<!-- 公安备案号:<a href="https://beian.mps.gov.cn/" target="_blank" style="color:#478ac9 ;">川公网安备51011202000980号</a> -->
|
公安备案号:<a href="https://beian.mps.gov.cn/#/query/webSearch?code=31011502407417" rel="noreferrer" target="_blank" style="color:#478ac9 ;"><img src="../images/gongan-beian.png" alt="" width="16" height="16" style="width:16px;height:16px;vertical-align:-3px;margin-right:4px;" />沪公网安备31011502407417号</a>
|
||||||
© 灵丌编程(001CODE.COM)
|
© 灵丌编程(001CODE.COM)
|
||||||
<span class="qr" tabindex="0">
|
<span class="qr" tabindex="0">
|
||||||
<img class="qr-icon" src="../images/qrcode_gery.svg" alt="公众号小图标" />
|
<img class="qr-icon" src="../images/qrcode_gery.svg" alt="公众号小图标" />
|
||||||
|
|||||||
@@ -160,7 +160,7 @@
|
|||||||
<footer>
|
<footer>
|
||||||
<div class="footer-line"></div>
|
<div class="footer-line"></div>
|
||||||
<p class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
<p class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
||||||
<!-- 公安备案号:<a href="https://beian.mps.gov.cn/" target="_blank" style="color:#478ac9 ;">川公网安备51011202000980号</a> -->
|
公安备案号:<a href="https://beian.mps.gov.cn/#/query/webSearch?code=31011502407417" rel="noreferrer" target="_blank" style="color:#478ac9 ;"><img src="../images/gongan-beian.png" alt="" width="16" height="16" style="width:16px;height:16px;vertical-align:-3px;margin-right:4px;" />沪公网安备31011502407417号</a>
|
||||||
© 灵丌编程(001CODE.COM)</p>
|
© 灵丌编程(001CODE.COM)</p>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
// config.js
|
// config.js
|
||||||
|
|
||||||
// const CONFIG = {
|
// const CONFIG = {
|
||||||
// DataServerBaseUrl: "https://test-service.001code.cn", // 在这里定义服务器地址
|
// DataServerBaseUrl: "https://service.001code.cn", // 在这里定义服务器地址
|
||||||
// // DataServerBaseUrl: "https://test-service.001code.cn", // 在这里定义服务器地址
|
// // DataServerBaseUrl: "https://service.001code.cn", // 在这里定义服务器地址
|
||||||
// // DataServerBaseUrl: "https://test-service.001code.cn",
|
// // DataServerBaseUrl: "https://service.001code.cn",
|
||||||
// // DataServerBaseUrl: "https://test-service.001code.cn",
|
// // DataServerBaseUrl: "https://service.001code.cn",
|
||||||
// // DataServerBaseUrl: "https://test-service.001code.cn",
|
// // DataServerBaseUrl: "https://service.001code.cn",
|
||||||
// // DataServerBaseUrl: "https://test-service.001code.cn",
|
// // DataServerBaseUrl: "https://service.001code.cn",
|
||||||
// version : "2025010301",
|
// version : "2025010301",
|
||||||
// unitycdndir : 'https://oss-rpwqy.jjwlcdn.com/001_code_unity_res_20250826',
|
// unitycdndir : 'https://oss-rpwqy.jjwlcdn.com/001_code_unity_res_20250826',
|
||||||
// unitycdnbuilddir : 'https://oss-rpwqy.jjwlcdn.com/001_code_unity_res_20250826/Build',
|
// unitycdnbuilddir : 'https://oss-rpwqy.jjwlcdn.com/001_code_unity_res_20250826/Build',
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
// // 可以根据需要添加其他配置
|
// // 可以根据需要添加其他配置
|
||||||
|
|
||||||
// disabledev: false,
|
// disabledev: true,
|
||||||
// usecdn :true, //资源走CDN
|
// usecdn :true, //资源走CDN
|
||||||
// lvlock :false, //关卡5关解锁,下一关加锁
|
// lvlock :false, //关卡5关解锁,下一关加锁
|
||||||
// lvlock_normal_learn :true, //常规关起锁
|
// lvlock_normal_learn :true, //常规关起锁
|
||||||
@@ -78,12 +78,12 @@
|
|||||||
|
|
||||||
|
|
||||||
// const CONFIG = {
|
// const CONFIG = {
|
||||||
// // DataServerBaseUrl: "https://test-service.001code.cn", // 在这里定义服务器地址
|
// // DataServerBaseUrl: "https://service.001code.cn", // 在这里定义服务器地址
|
||||||
// // DataServerBaseUrl: "https://test-service.001code.cn", // 在这里定义服务器地址
|
// // DataServerBaseUrl: "https://service.001code.cn", // 在这里定义服务器地址
|
||||||
// // DataServerBaseUrl: "https://test-service.001code.cn",
|
// // DataServerBaseUrl: "https://service.001code.cn",
|
||||||
// DataServerBaseUrl: "https://test-service.001code.cn",
|
// DataServerBaseUrl: "https://service.001code.cn",
|
||||||
// // DataServerBaseUrl: "https://test-service.001code.cn",
|
// // DataServerBaseUrl: "https://service.001code.cn",
|
||||||
// // DataServerBaseUrl: "https://test-service.001code.cn",
|
// // DataServerBaseUrl: "https://service.001code.cn",
|
||||||
// version : "2025011001",
|
// version : "2025011001",
|
||||||
// unitycdndir : 'https://oss-rpwqy.jjwlcdn.com/001_code_unity_res_20250826',
|
// unitycdndir : 'https://oss-rpwqy.jjwlcdn.com/001_code_unity_res_20250826',
|
||||||
// unitycdnbuilddir : 'https://oss-rpwqy.jjwlcdn.com/001_code_unity_res_20250826/Build',
|
// unitycdnbuilddir : 'https://oss-rpwqy.jjwlcdn.com/001_code_unity_res_20250826/Build',
|
||||||
@@ -91,8 +91,8 @@
|
|||||||
|
|
||||||
// // 可以根据需要添加其他配置
|
// // 可以根据需要添加其他配置
|
||||||
|
|
||||||
// // disabledev: false,
|
// // disabledev: true,
|
||||||
// disabledev: false,
|
// disabledev: true,
|
||||||
// usecdn :true, //资源走CDN
|
// usecdn :true, //资源走CDN
|
||||||
// lvlock :false, //关卡5关解锁,下一关加锁
|
// lvlock :false, //关卡5关解锁,下一关加锁
|
||||||
// lvlock_normal_learn : !(typeof localStorage !== 'undefined' &&
|
// lvlock_normal_learn : !(typeof localStorage !== 'undefined' &&
|
||||||
@@ -157,12 +157,12 @@
|
|||||||
|
|
||||||
|
|
||||||
const CONFIG = {
|
const CONFIG = {
|
||||||
// DataServerBaseUrl: "https://test-service.001code.cn", // 在这里定义服务器地址
|
// DataServerBaseUrl: "https://service.001code.cn", // 在这里定义服务器地址
|
||||||
// DataServerBaseUrl: "https://test-service.001code.cn", // 在这里定义服务器地址
|
// DataServerBaseUrl: "https://service.001code.cn", // 在这里定义服务器地址
|
||||||
// DataServerBaseUrl: "https://test-service.001code.cn",
|
// DataServerBaseUrl: "https://service.001code.cn",
|
||||||
DataServerBaseUrl: "https://service.001code.cn",
|
DataServerBaseUrl: "https://service.001code.cn",
|
||||||
// DataServerBaseUrl: "https://test-service.001code.cn",
|
// DataServerBaseUrl: "https://service.001code.cn",
|
||||||
// DataServerBaseUrl: "https://test-service.001code.cn",
|
// DataServerBaseUrl: "https://service.001code.cn",
|
||||||
|
|
||||||
version: "2026071701",
|
version: "2026071701",
|
||||||
/** OSS 真实地址(生产环境浏览器直连) */
|
/** OSS 真实地址(生产环境浏览器直连) */
|
||||||
|
|||||||
@@ -1759,7 +1759,7 @@ top: 2032px; */
|
|||||||
<footer class="footer" aria-label="页脚">
|
<footer class="footer" aria-label="页脚">
|
||||||
<div class="footer-line"></div>
|
<div class="footer-line"></div>
|
||||||
<div class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
<div class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
||||||
<!-- 公安备案号:<a href="https://beian.mps.gov.cn/" target="_blank" style="color:#478ac9 ;">川公网安备51011202000980号</a> -->
|
公安备案号:<a href="https://beian.mps.gov.cn/#/query/webSearch?code=31011502407417" rel="noreferrer" target="_blank" style="color:#478ac9 ;"><img src="../images/gongan-beian.png" alt="" width="16" height="16" style="width:16px;height:16px;vertical-align:-3px;margin-right:4px;" />沪公网安备31011502407417号</a>
|
||||||
© 灵丌编程(001CODE.COM)
|
© 灵丌编程(001CODE.COM)
|
||||||
<span class="qr" tabindex="0">
|
<span class="qr" tabindex="0">
|
||||||
<img class="qr-icon" src="../images/qrcode_gery.svg" alt="公众号小图标" />
|
<img class="qr-icon" src="../images/qrcode_gery.svg" alt="公众号小图标" />
|
||||||
|
|||||||
@@ -347,7 +347,7 @@
|
|||||||
<footer class="footer" aria-label="页脚">
|
<footer class="footer" aria-label="页脚">
|
||||||
<div class="footer-line"></div>
|
<div class="footer-line"></div>
|
||||||
<div class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
<div class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
||||||
<!-- 公安备案号:<a href="https://beian.mps.gov.cn/" target="_blank" style="color:#478ac9 ;">川公网安备51011202000980号</a> -->
|
公安备案号:<a href="https://beian.mps.gov.cn/#/query/webSearch?code=31011502407417" rel="noreferrer" target="_blank" style="color:#478ac9 ;"><img src="../images/gongan-beian.png" alt="" width="16" height="16" style="width:16px;height:16px;vertical-align:-3px;margin-right:4px;" />沪公网安备31011502407417号</a>
|
||||||
© 灵丌编程(001CODE.COM)
|
© 灵丌编程(001CODE.COM)
|
||||||
<span class="qr" tabindex="0">
|
<span class="qr" tabindex="0">
|
||||||
<img class="qr-icon" src="../images/qrcode_gery.svg" alt="公众号小图标" />
|
<img class="qr-icon" src="../images/qrcode_gery.svg" alt="公众号小图标" />
|
||||||
|
|||||||
@@ -96,7 +96,7 @@
|
|||||||
<footer class="site-footer">
|
<footer class="site-footer">
|
||||||
<div class="footer-divider"></div>
|
<div class="footer-divider"></div>
|
||||||
<p class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
<p class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
||||||
<!-- 公安备案号:<a href="https://beian.mps.gov.cn/" target="_blank" style="color:#478ac9 ;">川公网安备51011202000980号</a> -->
|
公安备案号:<a href="https://beian.mps.gov.cn/#/query/webSearch?code=31011502407417" rel="noreferrer" target="_blank" style="color:#478ac9 ;"><img src="../images/gongan-beian.png" alt="" width="16" height="16" style="width:16px;height:16px;vertical-align:-3px;margin-right:4px;" />沪公网安备31011502407417号</a>
|
||||||
© 灵丌编程(001CODE.COM)</p></p>
|
© 灵丌编程(001CODE.COM)</p></p>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|||||||
@@ -94,8 +94,7 @@
|
|||||||
<div class="footer-inner">
|
<div class="footer-inner">
|
||||||
<div class="footer-text" ">
|
<div class="footer-text" ">
|
||||||
ICP备案号:<a style=" color: #387cbd;" href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">沪ICP备2026042325号</a>
|
ICP备案号:<a style=" color: #387cbd;" href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">沪ICP备2026042325号</a>
|
||||||
<!-- <span> 公安备案号:<a style=" color: #387cbd;" href="https://beian.mps.gov.cn/"
|
<span>公安备案号:<a style="color:#387cbd;" href="https://beian.mps.gov.cn/#/query/webSearch?code=31011502407417" rel="noreferrer" target="_blank"><img src="../images/gongan-beian.png" alt="" width="16" height="16" style="width:16px;height:16px;vertical-align:-3px;margin-right:4px;" />沪公网安备31011502407417号</a></span>
|
||||||
target="_blank">川公网安备51011202000980号</a></span> -->
|
|
||||||
<span>© 灵丌编程(001CODE.COM)</span>
|
<span>© 灵丌编程(001CODE.COM)</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -361,7 +361,7 @@
|
|||||||
<footer class="footer" aria-label="页脚">
|
<footer class="footer" aria-label="页脚">
|
||||||
<div class="footer-line"></div>
|
<div class="footer-line"></div>
|
||||||
<div class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
<div class="footer-text">ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener" style="color:#478ac9 ;">沪ICP备2026042325号</a>
|
||||||
<!-- 公安备案号:<a href="https://beian.mps.gov.cn/" target="_blank" style="color:#478ac9 ;">川公网安备51011202000980号</a> -->
|
公安备案号:<a href="https://beian.mps.gov.cn/#/query/webSearch?code=31011502407417" rel="noreferrer" target="_blank" style="color:#478ac9 ;"><img src="../images/gongan-beian.png" alt="" width="16" height="16" style="width:16px;height:16px;vertical-align:-3px;margin-right:4px;" />沪公网安备31011502407417号</a>
|
||||||
© 灵丌编程(001CODE.COM)
|
© 灵丌编程(001CODE.COM)
|
||||||
<span class="qr" tabindex="0">
|
<span class="qr" tabindex="0">
|
||||||
<img class="qr-icon" src="../images/qrcode_gery.svg" alt="公众号小图标" />
|
<img class="qr-icon" src="../images/qrcode_gery.svg" alt="公众号小图标" />
|
||||||
|
|||||||
@@ -332,7 +332,7 @@
|
|||||||
<div class="footer-inner">
|
<div class="footer-inner">
|
||||||
<div class="footer-text">
|
<div class="footer-text">
|
||||||
ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">沪ICP备2026042325号</a>
|
ICP备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">沪ICP备2026042325号</a>
|
||||||
<!-- 公安备案号:<a href="https://beian.mps.gov.cn/" target="_blank">川公网安备51011202000980号</a> --> © 灵丌编程(001CODE.COM)
|
公安备案号:<a href="https://beian.mps.gov.cn/#/query/webSearch?code=31011502407417" rel="noreferrer" target="_blank"><img src="../images/gongan-beian.png" alt="" width="16" height="16" style="width:16px;height:16px;vertical-align:-3px;margin-right:4px;" />沪公网安备31011502407417号</a> © 灵丌编程(001CODE.COM)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
BIN
scratch-gui/static/images/gongan-beian.png
Normal file
BIN
scratch-gui/static/images/gongan-beian.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Reference in New Issue
Block a user