atcoder-gui 0.1.7 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/README.md +7 -0
  2. package/dist/analyzer/analyzer.d.ts +16 -0
  3. package/dist/analyzer/analyzer.d.ts.map +1 -0
  4. package/dist/analyzer/analyzer.js +379 -0
  5. package/dist/analyzer/analyzer.js.map +1 -0
  6. package/dist/analyzer/html-parser.d.ts +24 -0
  7. package/dist/analyzer/html-parser.d.ts.map +1 -0
  8. package/dist/analyzer/html-parser.js +214 -0
  9. package/dist/analyzer/html-parser.js.map +1 -0
  10. package/dist/analyzer/index.d.ts +7 -0
  11. package/dist/analyzer/index.d.ts.map +1 -0
  12. package/dist/analyzer/index.js +7 -0
  13. package/dist/analyzer/index.js.map +1 -0
  14. package/dist/analyzer/lexer.d.ts +14 -0
  15. package/dist/analyzer/lexer.d.ts.map +1 -0
  16. package/dist/analyzer/lexer.js +133 -0
  17. package/dist/analyzer/lexer.js.map +1 -0
  18. package/dist/analyzer/match.d.ts +7 -0
  19. package/dist/analyzer/match.d.ts.map +1 -0
  20. package/dist/analyzer/match.js +133 -0
  21. package/dist/analyzer/match.js.map +1 -0
  22. package/dist/analyzer/parser.d.ts +20 -0
  23. package/dist/analyzer/parser.d.ts.map +1 -0
  24. package/dist/analyzer/parser.js +135 -0
  25. package/dist/analyzer/parser.js.map +1 -0
  26. package/dist/analyzer/types.d.ts +54 -0
  27. package/dist/analyzer/types.d.ts.map +1 -0
  28. package/dist/analyzer/types.js +10 -0
  29. package/dist/analyzer/types.js.map +1 -0
  30. package/dist/analyzer/typing.d.ts +10 -0
  31. package/dist/analyzer/typing.d.ts.map +1 -0
  32. package/dist/analyzer/typing.js +246 -0
  33. package/dist/analyzer/typing.js.map +1 -0
  34. package/dist/browser.d.ts +12 -0
  35. package/dist/browser.d.ts.map +1 -1
  36. package/dist/browser.js +26 -1
  37. package/dist/browser.js.map +1 -1
  38. package/dist/build.d.ts +7 -0
  39. package/dist/build.d.ts.map +1 -0
  40. package/dist/build.js +40 -0
  41. package/dist/build.js.map +1 -0
  42. package/dist/config.d.ts +10 -2
  43. package/dist/config.d.ts.map +1 -1
  44. package/dist/config.js +31 -18
  45. package/dist/config.js.map +1 -1
  46. package/dist/config.json5 +16 -1
  47. package/dist/gen.d.ts +6 -12
  48. package/dist/gen.d.ts.map +1 -1
  49. package/dist/gen.js +153 -66
  50. package/dist/gen.js.map +1 -1
  51. package/dist/generator/checker.d.ts +2 -0
  52. package/dist/generator/checker.d.ts.map +1 -0
  53. package/dist/generator/checker.js +64 -0
  54. package/dist/generator/checker.js.map +1 -0
  55. package/dist/generator/cplusplus.d.ts +14 -0
  56. package/dist/generator/cplusplus.d.ts.map +1 -0
  57. package/dist/generator/cplusplus.js +43 -0
  58. package/dist/generator/cplusplus.js.map +1 -0
  59. package/dist/generator/fetcher.d.ts +2 -0
  60. package/dist/generator/fetcher.d.ts.map +1 -0
  61. package/dist/generator/fetcher.js +39 -0
  62. package/dist/generator/fetcher.js.map +1 -0
  63. package/dist/generator/pipeline.d.ts +25 -0
  64. package/dist/generator/pipeline.d.ts.map +1 -0
  65. package/dist/generator/pipeline.js +85 -0
  66. package/dist/generator/pipeline.js.map +1 -0
  67. package/dist/generator/python.d.ts +14 -0
  68. package/dist/generator/python.d.ts.map +1 -0
  69. package/dist/generator/python.js +41 -0
  70. package/dist/generator/python.js.map +1 -0
  71. package/dist/generator/types.d.ts +79 -0
  72. package/dist/generator/types.d.ts.map +1 -0
  73. package/dist/generator/types.js +2 -0
  74. package/dist/generator/types.js.map +1 -0
  75. package/dist/generator/universal.d.ts +35 -0
  76. package/dist/generator/universal.d.ts.map +1 -0
  77. package/dist/generator/universal.js +524 -0
  78. package/dist/generator/universal.js.map +1 -0
  79. package/dist/generator/variable-extractor.d.ts +16 -0
  80. package/dist/generator/variable-extractor.d.ts.map +1 -0
  81. package/dist/generator/variable-extractor.js +103 -0
  82. package/dist/generator/variable-extractor.js.map +1 -0
  83. package/dist/main.d.ts +3 -1
  84. package/dist/main.d.ts.map +1 -1
  85. package/dist/main.js +103 -102
  86. package/dist/main.js.map +1 -1
  87. package/dist/submit.d.ts +3 -2
  88. package/dist/submit.d.ts.map +1 -1
  89. package/dist/submit.js +48 -33
  90. package/dist/submit.js.map +1 -1
  91. package/dist/test.d.ts +10 -0
  92. package/dist/test.d.ts.map +1 -0
  93. package/dist/test.js +127 -0
  94. package/dist/test.js.map +1 -0
  95. package/dist/tests/batch_check.d.ts +2 -0
  96. package/dist/tests/batch_check.d.ts.map +1 -0
  97. package/dist/tests/batch_check.js +46 -0
  98. package/dist/tests/batch_check.js.map +1 -0
  99. package/dist/types.d.ts +2 -0
  100. package/dist/types.d.ts.map +1 -1
  101. package/dist/utils.d.ts +12 -0
  102. package/dist/utils.d.ts.map +1 -1
  103. package/dist/utils.js +32 -0
  104. package/dist/utils.js.map +1 -1
  105. package/package.json +21 -4
package/dist/submit.js CHANGED
@@ -1,4 +1,5 @@
1
- import { readFileSync, existsSync } from 'fs';
1
+ import { readFileSync, existsSync } from "fs";
2
+ import * as path from "path";
2
3
  export class SubmitManager {
3
4
  browserManager;
4
5
  constructor(browserManager) {
@@ -7,48 +8,62 @@ export class SubmitManager {
7
8
  /**
8
9
  * Submit solution to AtCoder
9
10
  */
10
- async submitSolution() {
11
+ async submitSolution(filename) {
11
12
  try {
12
- // Check if required files exist in current directory
13
- const metadataPath = './metadata.json';
14
- const mainCppPath = './main.cpp';
15
- if (!existsSync(metadataPath)) {
16
- console.error('Error: metadata.json not found in current directory');
17
- console.log('Make sure you are in a directory created by atcoder-tools');
18
- return;
13
+ const atcoderToolsMetadataPath = "./metadata.json";
14
+ const atcoderCliMetadataPath = "../contest.acc.json";
15
+ if (existsSync(atcoderToolsMetadataPath)) {
16
+ const metadata = JSON.parse(readFileSync(atcoderToolsMetadataPath, "utf-8"));
17
+ this.pasteToBrowser(metadata.problem.contest.contest_id, metadata.problem.problem_id, filename || metadata.code_filename);
18
+ return true;
19
19
  }
20
- if (!existsSync(mainCppPath)) {
21
- console.error('Error: main.cpp not found in current directory');
22
- return;
20
+ else if (existsSync(atcoderCliMetadataPath)) {
21
+ if (!filename) {
22
+ console.error("Error: filename is required");
23
+ return false;
24
+ }
25
+ const metadata = JSON.parse(readFileSync(atcoderCliMetadataPath, "utf-8"));
26
+ const problem_id = path.basename(process.cwd());
27
+ for (const task of metadata.tasks) {
28
+ if (task.directory?.path == problem_id) {
29
+ this.pasteToBrowser(metadata.contest.id, task.id, filename);
30
+ return true;
31
+ }
32
+ }
33
+ }
34
+ else {
35
+ console.error("Error: metadata not found in current directory");
23
36
  }
24
- // Parse metadata.json to get contest_id and problem_id
25
- const { contestId, problemId } = this.parseMetadata(metadataPath);
26
- console.log(`Contest ID: ${contestId}, Problem ID: ${problemId}`);
27
- // Read main.cpp content
28
- const sourceCode = this.readSourceCode(mainCppPath);
29
- console.log(`Source code loaded (${sourceCode.length} characters)`);
30
- // Open AtCoder submit URL
31
- const submitUrl = `https://atcoder.jp/contests/${contestId}/submit?taskScreenName=${problemId}`;
32
- console.log(`Opening submit page: ${submitUrl}`);
33
- await this.browserManager.openUrl(submitUrl);
34
- // Copy source code to clipboard and fill the textarea
35
- await this.fillSourceCodeArea(sourceCode);
36
37
  }
37
38
  catch (error) {
38
- console.error('Error during submission:', error);
39
+ console.error("Error during submission:", error);
40
+ }
41
+ return false;
42
+ }
43
+ async pasteToBrowser(contestId, problemId, sourceCodePath) {
44
+ if (!existsSync(sourceCodePath)) {
45
+ console.error(`Error: ${sourceCodePath} not found in current directory`);
46
+ return;
39
47
  }
48
+ const sourceCode = this.readSourceCode(sourceCodePath);
49
+ console.log(`Contest ID: ${contestId}, Problem ID: ${problemId}`);
50
+ // Open AtCoder submit URL
51
+ const submitUrl = `https://atcoder.jp/contests/${contestId}/submit?taskScreenName=${problemId}`;
52
+ await this.browserManager.openUrl(submitUrl);
53
+ // Copy source code to clipboard and fill the textarea
54
+ await this.fillSourceCodeArea(sourceCode);
40
55
  }
41
56
  /**
42
57
  * Parse metadata.json to extract contest_id and problem_id
43
58
  */
44
59
  parseMetadata(metadataPath) {
45
60
  try {
46
- const metadataContent = readFileSync(metadataPath, 'utf-8');
61
+ const metadataContent = readFileSync(metadataPath, "utf-8");
47
62
  const metadata = JSON.parse(metadataContent);
48
63
  const contestId = metadata.problem.contest.contest_id;
49
64
  const problemId = metadata.problem.problem_id;
50
65
  if (!contestId || !problemId) {
51
- throw new Error('contest_id or problem_id not found in metadata.json');
66
+ throw new Error("contest_id or problem_id not found in metadata.json");
52
67
  }
53
68
  return { contestId, problemId };
54
69
  }
@@ -61,7 +76,7 @@ export class SubmitManager {
61
76
  */
62
77
  readSourceCode(mainCppPath) {
63
78
  try {
64
- return readFileSync(mainCppPath, 'utf-8');
79
+ return readFileSync(mainCppPath, "utf-8");
65
80
  }
66
81
  catch (error) {
67
82
  throw new Error(`Failed to read main.cpp: ${error}`);
@@ -74,21 +89,21 @@ export class SubmitManager {
74
89
  try {
75
90
  const page = this.browserManager.getCurrentPage();
76
91
  if (!page) {
77
- throw new Error('No active page found');
92
+ throw new Error("No active page found");
78
93
  }
79
94
  // Wait for the page to load
80
- await page.waitForLoadState('domcontentloaded');
95
+ await page.waitForLoadState("domcontentloaded");
81
96
  // Find the source code textarea (common selectors for AtCoder)
82
- const textareaSelector = '#editor .ace_text-input';
97
+ const textareaSelector = "#editor .ace_text-input";
83
98
  await page.waitForSelector(textareaSelector, { timeout: 10000 });
84
99
  // Set min-height for the editor textarea
85
100
  await page.addStyleTag({ content: `div#editor { min-height: 200px !important; }` });
86
101
  // Clear existing content and paste source code
87
102
  await page.fill(textareaSelector, sourceCode);
88
- console.log('✓ Copied!');
103
+ console.log("✓ Copied!");
89
104
  }
90
105
  catch (error) {
91
- console.error('Failed to fill source code area:', error);
106
+ console.error("Failed to fill source code area:", error);
92
107
  }
93
108
  }
94
109
  }
@@ -1 +1 @@
1
- {"version":3,"file":"submit.js","sourceRoot":"","sources":["../src/submit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"submit.js","sourceRoot":"","sources":["../src/submit.ts"],"names":[],"mappings":"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"}
package/dist/test.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { ConfigManager } from "./config.js";
2
+ import { BuildManager } from "./build.js";
3
+ export declare class TestManager {
4
+ private configManager;
5
+ private buildManager;
6
+ constructor(configManager: ConfigManager, buildManager: BuildManager);
7
+ private compareOutputs;
8
+ run(args: string[]): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C,qBAAa,WAAW;IACtB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,YAAY,CAAe;gBAEvB,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY;IAKpE,OAAO,CAAC,cAAc;IAkChB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA+FzC"}
package/dist/test.js ADDED
@@ -0,0 +1,127 @@
1
+ import * as fs from "fs";
2
+ import { execSync } from "child_process";
3
+ export class TestManager {
4
+ configManager;
5
+ buildManager;
6
+ constructor(configManager, buildManager) {
7
+ this.configManager = configManager;
8
+ this.buildManager = buildManager;
9
+ }
10
+ compareOutputs(actual, expected, judgeType, errorTolerance = 1e-6) {
11
+ const actualTokens = actual.split(/\s+/).filter((t) => t.length > 0);
12
+ const expectedTokens = expected.split(/\s+/).filter((t) => t.length > 0);
13
+ if (actualTokens.length !== expectedTokens.length) {
14
+ return false;
15
+ }
16
+ for (let i = 0; i < actualTokens.length; i++) {
17
+ const actualToken = actualTokens[i];
18
+ const expectedToken = expectedTokens[i];
19
+ if (judgeType === "decimal") {
20
+ const actualNum = parseFloat(actualToken);
21
+ const expectedNum = parseFloat(expectedToken);
22
+ if (!isNaN(actualNum) && !isNaN(expectedNum)) {
23
+ const diff = Math.abs(actualNum - expectedNum);
24
+ const relativeDiff = expectedNum === 0 ? diff : diff / Math.abs(expectedNum);
25
+ if (diff > errorTolerance && relativeDiff > errorTolerance) {
26
+ return false;
27
+ }
28
+ continue;
29
+ }
30
+ }
31
+ if (actualToken !== expectedToken) {
32
+ return false;
33
+ }
34
+ }
35
+ return true;
36
+ }
37
+ async run(args) {
38
+ if (!fs.existsSync("metadata.json")) {
39
+ console.error("Error: metadata.json not found in the current directory.");
40
+ return;
41
+ }
42
+ // Run build before testing
43
+ await this.buildManager.run(args);
44
+ try {
45
+ const metadata = JSON.parse(fs.readFileSync("metadata.json", "utf-8"));
46
+ const codeFilename = metadata.code_filename;
47
+ const timeoutMs = metadata.timeout_ms;
48
+ if (!codeFilename) {
49
+ console.error("Error: code_filename not found in metadata.json");
50
+ return;
51
+ }
52
+ let execCommand = "";
53
+ if (codeFilename.endsWith(".py")) {
54
+ execCommand = `python ${codeFilename}`;
55
+ }
56
+ else if (codeFilename.endsWith(".cpp")) {
57
+ execCommand = process.platform === "win32" ? "main" : "./main";
58
+ }
59
+ else {
60
+ console.log(`Testing not supported for ${codeFilename}`);
61
+ return;
62
+ }
63
+ const files = fs.readdirSync(".");
64
+ const inputFiles = files.filter((f) => /^in_.+\.txt$/.test(f)).sort();
65
+ if (inputFiles.length === 0) {
66
+ console.log("No test cases (in_?.txt) found.");
67
+ return;
68
+ }
69
+ let passedCount = 0;
70
+ let totalCount = 0;
71
+ for (const inFile of inputFiles) {
72
+ const testId = inFile.match(/^in_(.+)\.txt$/)?.[1];
73
+ const outFile = `out_${testId}.txt`;
74
+ if (!fs.existsSync(outFile)) {
75
+ console.warn(`Warning: Output file ${outFile} not found for ${inFile}. Skipping.`);
76
+ continue;
77
+ }
78
+ totalCount++;
79
+ const input = fs.readFileSync(inFile, "utf-8");
80
+ const expectedOutput = fs.readFileSync(outFile, "utf-8").trim();
81
+ try {
82
+ const stdout = execSync(execCommand, {
83
+ input: input,
84
+ encoding: "utf-8",
85
+ stdio: ["pipe", "pipe", "inherit"],
86
+ timeout: timeoutMs,
87
+ }).trim();
88
+ if (this.compareOutputs(stdout, expectedOutput, metadata.judge?.judge_type, metadata.judge?.diff)) {
89
+ console.log(`# ${inFile} ... \x1b[32mPASSED\x1b[0m`);
90
+ passedCount++;
91
+ }
92
+ else {
93
+ console.log(`# ${inFile} ... \x1b[31mWA\x1b[0m`);
94
+ console.log("\x1b[95m[Input]\x1b[0m");
95
+ console.log(input.trim());
96
+ console.log("\x1b[95m[Expected]\x1b[0m");
97
+ console.log(expectedOutput);
98
+ console.log("\x1b[95m[Received]\x1b[0m");
99
+ console.log(stdout);
100
+ console.log("");
101
+ }
102
+ }
103
+ catch (error) {
104
+ if (error.code === "ETIMEDOUT" || error.signal === "SIGTERM") {
105
+ console.log(`# ${inFile} ... \x1b[33mTLE\x1b[0m`);
106
+ }
107
+ else {
108
+ console.log(`# ${inFile} ... \x1b[33mRE\x1b[0m`);
109
+ if (error.stderr) {
110
+ console.error(error.stderr);
111
+ }
112
+ }
113
+ }
114
+ }
115
+ if (passedCount === totalCount) {
116
+ console.log("\x1b[32mPassed all test cases!!!\x1b[0m");
117
+ }
118
+ else {
119
+ console.log(`\x1b[31mSome cases FAILED\x1b[0m (passed ${passedCount} of ${totalCount})`);
120
+ }
121
+ }
122
+ catch (error) {
123
+ console.error("Error reading or parsing metadata.json:", error);
124
+ }
125
+ }
126
+ }
127
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=batch_check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch_check.d.ts","sourceRoot":"","sources":["../../src/tests/batch_check.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ import { spawn } from 'child_process';
2
+ const failed = [];
3
+ const args = process.argv.slice(2);
4
+ const contestStart = parseInt(args[0]) || 400;
5
+ const contestEnd = parseInt(args[1]) || 400; // Default to single contest if not provided
6
+ const problems = ['a', 'b', 'c', 'd', 'e', 'f'];
7
+ function runCommand(taskId) {
8
+ return new Promise((resolve) => {
9
+ const child = spawn('pnpm', ['run', 'check', taskId], {
10
+ stdio: ['ignore', 'ignore', 'ignore'],
11
+ });
12
+ child.on('close', (code) => {
13
+ resolve(code ?? 1);
14
+ });
15
+ child.on('error', () => {
16
+ resolve(1);
17
+ });
18
+ });
19
+ }
20
+ (async () => {
21
+ console.log(`Starting check from abc${contestStart} to abc${contestEnd}...`);
22
+ for (let i = contestStart; i <= contestEnd; i++) {
23
+ const contestId = `abc${i}`;
24
+ for (const p of problems) {
25
+ const taskId = `${contestId}_${p}`;
26
+ process.stdout.write(`Checking ${taskId}... `);
27
+ await new Promise((r) => setTimeout(r, 1000));
28
+ const code = await runCommand(taskId);
29
+ if (code !== 0) {
30
+ console.log('FAILED');
31
+ failed.push(taskId);
32
+ }
33
+ else {
34
+ console.log('OK');
35
+ }
36
+ }
37
+ }
38
+ console.log('\nSummary of failures:');
39
+ if (failed.length > 0) {
40
+ console.log(failed.join('\n'));
41
+ }
42
+ else {
43
+ console.log('No errors found.');
44
+ }
45
+ })();
46
+ //# sourceMappingURL=batch_check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch_check.js","sourceRoot":"","sources":["../../src/tests/batch_check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC,MAAM,MAAM,GAAa,EAAE,CAAC;AAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;AAC9C,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,4CAA4C;AACzF,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAEhD,SAAS,UAAU,CAAC,MAAc;IAChC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE;YACpD,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;SACtC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACrB,OAAO,CAAC,CAAC,CAAC,CAAC;QACb,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,CAAC,KAAK,IAAI,EAAE;IACV,OAAO,CAAC,GAAG,CAAC,0BAA0B,YAAY,UAAU,UAAU,KAAK,CAAC,CAAC;IAE7E,KAAK,IAAI,CAAC,GAAG,YAAY,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QAChD,MAAM,SAAS,GAAG,MAAM,CAAC,EAAE,CAAC;QAC5B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,GAAG,SAAS,IAAI,CAAC,EAAE,CAAC;YACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,MAAM,MAAM,CAAC,CAAC;YAE/C,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;YAE9C,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;YAEtC,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBACtB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACjC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAClC,CAAC;AACH,CAAC,CAAC,EAAE,CAAC"}
package/dist/types.d.ts CHANGED
@@ -24,6 +24,8 @@ export interface AtCoderToolsMetadata {
24
24
  code_filename: string;
25
25
  judge: {
26
26
  judge_type: string;
27
+ error_type?: string;
28
+ diff?: number;
27
29
  };
28
30
  lang: string;
29
31
  problem: {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE;QACV,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAGD,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE;YACP,UAAU,EAAE,MAAM,CAAC;SACpB,CAAC;QACF,UAAU,EAAE,MAAM,CAAC;QACnB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE;QACV,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAGD,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE;YACP,UAAU,EAAE,MAAM,CAAC;SACpB,CAAC;QACF,UAAU,EAAE,MAAM,CAAC;QACnB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB"}
package/dist/utils.d.ts CHANGED
@@ -1,6 +1,18 @@
1
1
  /**
2
2
  * Utility functions for atcoder-gui
3
3
  */
4
+ /**
5
+ * Expand home directory (~) in a path
6
+ * @param filepath Path to expand
7
+ * @returns Path with ~ replaced by home directory
8
+ */
9
+ export declare function expandHomeDir(filepath: string): string;
10
+ /**
11
+ * Compact home directory in a path to ~
12
+ * @param filepath Path to compact
13
+ * @returns Path with home directory replaced by ~ if it is a prefix
14
+ */
15
+ export declare function compactHomeDir(filepath: string): string;
4
16
  /**
5
17
  * Format date for Python LWPCookieJar format: "2026-05-22 13:20:38Z"
6
18
  * @param date Date object to format
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAShD"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAevD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAShD"}
package/dist/utils.js CHANGED
@@ -1,6 +1,38 @@
1
1
  /**
2
2
  * Utility functions for atcoder-gui
3
3
  */
4
+ import os from 'os';
5
+ import path from 'path';
6
+ /**
7
+ * Expand home directory (~) in a path
8
+ * @param filepath Path to expand
9
+ * @returns Path with ~ replaced by home directory
10
+ */
11
+ export function expandHomeDir(filepath) {
12
+ if (filepath === '~' || filepath.startsWith('~/')) {
13
+ const home = os.homedir();
14
+ return filepath === '~' ? home : path.join(home, filepath.slice(2));
15
+ }
16
+ return filepath;
17
+ }
18
+ /**
19
+ * Compact home directory in a path to ~
20
+ * @param filepath Path to compact
21
+ * @returns Path with home directory replaced by ~ if it is a prefix
22
+ */
23
+ export function compactHomeDir(filepath) {
24
+ const home = os.homedir();
25
+ const absolutePath = path.resolve(filepath);
26
+ const absoluteHome = path.resolve(home);
27
+ if (absolutePath === absoluteHome) {
28
+ return '~';
29
+ }
30
+ const prefix = absoluteHome + path.sep;
31
+ if (absolutePath.startsWith(prefix)) {
32
+ return '~' + path.sep + absolutePath.slice(prefix.length);
33
+ }
34
+ return filepath;
35
+ }
4
36
  /**
5
37
  * Format date for Python LWPCookieJar format: "2026-05-22 13:20:38Z"
6
38
  * @param date Date object to format
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAU;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAE9D,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,OAAO,IAAI,OAAO,GAAG,CAAC;AACnE,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,IAAI,QAAQ,KAAK,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAC1B,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC,IAAI,YAAY,KAAK,YAAY,EAAE,CAAC;QAClC,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC;IACvC,IAAI,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,OAAO,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAU;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAE9D,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,OAAO,IAAI,OAAO,GAAG,CAAC;AACnE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atcoder-gui",
3
- "version": "0.1.7",
3
+ "version": "1.1.0",
4
4
  "description": "Browser automation tool for AtCoder with CLI interface",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",
@@ -19,14 +19,16 @@
19
19
  "scripts": {
20
20
  "build": "tsc && cp src/config.json5 dist/",
21
21
  "dev": "tsc --watch",
22
- "test": "vitest",
23
- "test:run": "vitest run",
22
+ "test": "vitest run",
23
+ "test:scenario": "vitest run src/tests/scenario.test.ts",
24
24
  "lint": "eslint src/**/*.ts",
25
25
  "lint:fix": "eslint src/**/*.ts --fix",
26
+ "check": "tsx src/generator/checker.ts",
26
27
  "start": "tsx src/main.ts",
27
28
  "start:built": "node dist/main.js",
28
29
  "clean": "rm -rf dist",
29
- "prepublishOnly": "pnpm run clean && pnpm run build && pnpm run test:run && pnpm run lint"
30
+ "prepublishOnly": "pnpm run clean && pnpm run build && pnpm run test && pnpm run lint",
31
+ "prepare": "husky"
30
32
  },
31
33
  "repository": {
32
34
  "type": "git",
@@ -47,19 +49,34 @@
47
49
  },
48
50
  "homepage": "https://github.com/firewood/atcoder-gui#readme",
49
51
  "dependencies": {
52
+ "cheerio": "^1.1.2",
50
53
  "conf": "^15.0.2",
51
54
  "globals": "^16.5.0",
52
55
  "json5": "^2.2.3",
56
+ "nunjucks": "^3.2.4",
53
57
  "playwright": "^1.56.1"
54
58
  },
55
59
  "devDependencies": {
60
+ "@eslint/js": "^9.39.2",
56
61
  "@playwright/test": "^1.56.1",
62
+ "@types/json5": "^2.2.0",
57
63
  "@types/node": "^24.10.1",
64
+ "@types/nunjucks": "^3.2.6",
58
65
  "@typescript-eslint/eslint-plugin": "^8.47.0",
59
66
  "@typescript-eslint/parser": "^8.47.0",
60
67
  "eslint": "^9.39.1",
68
+ "eslint-config-prettier": "^10.1.8",
69
+ "husky": "^9.1.7",
70
+ "lint-staged": "^16.2.7",
71
+ "prettier": "^3.7.4",
61
72
  "tsx": "^4.20.6",
62
73
  "typescript": "^5.9.3",
63
74
  "vitest": "^4.0.13"
75
+ },
76
+ "lint-staged": {
77
+ "*.{js,jsx,ts,tsx}": [
78
+ "prettier --write",
79
+ "eslint --fix"
80
+ ]
64
81
  }
65
82
  }