atcoder-gui 0.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.
@@ -0,0 +1,151 @@
1
+ import { writeFileSync, existsSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { homedir } from 'os';
4
+ import { execSync } from 'child_process';
5
+ import { formatLWPDate } from './utils.js';
6
+ export class CookieExporter {
7
+ browserManager;
8
+ constructor(browserManager) {
9
+ this.browserManager = browserManager;
10
+ }
11
+ /**
12
+ * Get the oj (online-judge-tools) cookie path by running oj command
13
+ */
14
+ static getOjCookiePath() {
15
+ try {
16
+ // Run oj command to get help output which includes the default cookie path
17
+ const output = execSync('oj --help', { encoding: 'utf-8', timeout: 5000 });
18
+ // Parse the output to find the cookie path line
19
+ const match = output.match(/path to cookie\.\s*\(default:\s*([^)]+)\)/);
20
+ if (match && match[1]) {
21
+ return match[1].trim();
22
+ }
23
+ throw new Error('Could not parse oj cookie path from command output');
24
+ }
25
+ catch (error) {
26
+ throw new Error(`Failed to get oj cookie path: ${error instanceof Error ? error.message : String(error)}`);
27
+ }
28
+ }
29
+ /**
30
+ * Get AtCoder cookies from current browser session
31
+ */
32
+ async getAtCoderCookies() {
33
+ // Ensure browser is running and we have current session
34
+ if (!this.browserManager.isRunning()) {
35
+ throw new Error('Browser is not running. Please open a browser session first.');
36
+ }
37
+ // Save current session to get latest cookies
38
+ await this.browserManager.saveSession();
39
+ // Get cookies from session manager
40
+ const sessionManager = this.browserManager.getSessionManager();
41
+ const sessionData = sessionManager.getStorageState();
42
+ if (!sessionData || !sessionData.cookies.length) {
43
+ throw new Error('No cookies found in current session');
44
+ }
45
+ // Filter AtCoder cookies (REVEL_FLASH and REVEL_SESSION)
46
+ const atcoderCookies = sessionData.cookies.filter(cookie => cookie.domain.includes('atcoder.jp') &&
47
+ (cookie.name === 'REVEL_FLASH' || cookie.name === 'REVEL_SESSION'));
48
+ if (atcoderCookies.length === 0) {
49
+ throw new Error('No AtCoder cookies (REVEL_FLASH or REVEL_SESSION) found. Make sure you are logged in to AtCoder in the browser');
50
+ }
51
+ return atcoderCookies;
52
+ }
53
+ /**
54
+ * Export cookies to atcoder-tools cookie.txt file
55
+ */
56
+ async exportCookiesForAtCoderTools() {
57
+ await this.exportCookies(CookieExporter.getAtCoderToolsCookiePath());
58
+ console.log('✓ Cookies exported successfully to atcoder-tools');
59
+ }
60
+ /**
61
+ * Export cookies to oj (online-judge-tools) cookie.jar file
62
+ */
63
+ async exportCookiesForOj() {
64
+ await this.exportCookies(CookieExporter.getOjCookiePath());
65
+ console.log('✓ Cookies exported successfully to oj (online-judge-tools)');
66
+ }
67
+ /**
68
+ * Export cookies to oj (online-judge-tools) cookie.jar file
69
+ */
70
+ async exportCookies(cookiePath) {
71
+ try {
72
+ const atcoderCookies = await this.getAtCoderCookies();
73
+ // Generate LWP-Cookies-2.0 format content
74
+ const cookieContent = this.generateLWPCookiesContent(atcoderCookies);
75
+ // Write to oj cookie.jar file
76
+ await this.writeCookieFile(cookiePath, cookieContent);
77
+ }
78
+ catch (error) {
79
+ console.error('Error during oj cookie export:', error);
80
+ }
81
+ }
82
+ /**
83
+ * Generate LWP-Cookies-2.0 format content from Playwright cookies
84
+ */
85
+ generateLWPCookiesContent(cookies) {
86
+ const lines = ['#LWP-Cookies-2.0'];
87
+ for (const cookie of cookies) {
88
+ // Convert Playwright cookie format to LWP format
89
+ const lwpCookie = this.convertToLWPFormat(cookie);
90
+ lines.push(lwpCookie);
91
+ }
92
+ return lines.join('\n') + '\n';
93
+ }
94
+ /**
95
+ * Convert Playwright cookie to LWP-Cookies-2.0 Set-Cookie3 format
96
+ */
97
+ convertToLWPFormat(cookie) {
98
+ const parts = [];
99
+ // Basic cookie value
100
+ parts.push(`Set-Cookie3: ${cookie.name}="${cookie.value}"`);
101
+ // Path
102
+ parts.push(`path="${cookie.path}"`);
103
+ // Domain
104
+ parts.push(`domain=${cookie.domain}`);
105
+ // Path specification (always include for AtCoder)
106
+ parts.push('path_spec');
107
+ // Secure flag
108
+ if (cookie.secure) {
109
+ parts.push('secure');
110
+ }
111
+ // Expires handling - if expires is -1 or in the past, mark as discard
112
+ if (cookie.expires === -1 || cookie.expires < Date.now() / 1000) {
113
+ parts.push('discard');
114
+ }
115
+ else {
116
+ // Convert Unix timestamp to Python LWPCookieJar format: "YYYY-MM-DD hh:mm:ssZ"
117
+ const expiresDate = new Date(cookie.expires * 1000);
118
+ parts.push(`expires="${formatLWPDate(expiresDate)}"`);
119
+ }
120
+ // HttpOnly
121
+ if (cookie.httpOnly) {
122
+ parts.push('HttpOnly=None');
123
+ }
124
+ // Version (always 0 for compatibility)
125
+ parts.push('version=0');
126
+ return parts.join('; ');
127
+ }
128
+ /**
129
+ * Write cookie content to atcoder-tools cookie.txt file
130
+ * Only overwrites existing cookie.txt files
131
+ */
132
+ async writeCookieFile(cookiePath, content) {
133
+ // Check if cookie.txt file exists
134
+ if (!existsSync(cookiePath)) {
135
+ throw new Error(`Cookie file does not exist: ${cookiePath}\nPlease ensure atcoder-tools is installed and has been used at least once to create the cookie.txt file.`);
136
+ }
137
+ // Write cookie file (overwrite existing)
138
+ writeFileSync(cookiePath, content, {
139
+ encoding: 'utf-8',
140
+ mode: 0o600 // Set file permissions (readable/writable by owner only)
141
+ });
142
+ console.log(`Cookie file updated: ${cookiePath}`);
143
+ }
144
+ /**
145
+ * Get the path to atcoder-tools cookie.txt file
146
+ */
147
+ static getAtCoderToolsCookiePath() {
148
+ return join(homedir(), '.local', 'share', 'atcoder-tools', 'cookie.txt');
149
+ }
150
+ }
151
+ //# sourceMappingURL=cookie-export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookie-export.js","sourceRoot":"","sources":["../src/cookie-export.ts"],"names":[],"mappings":"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"}
package/dist/main.d.ts ADDED
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+ import { AppConfig } from './config.js';
3
+ export declare class AtCoderGUI {
4
+ private browserManager;
5
+ private configManager;
6
+ private submitManager;
7
+ private cookieExporter;
8
+ private rl;
9
+ constructor();
10
+ /**
11
+ * Initialize the application
12
+ */
13
+ init(): Promise<void>;
14
+ /**
15
+ * Open a URL in the browser
16
+ */
17
+ openUrl(url: string): Promise<void>;
18
+ /**
19
+ * Close the application
20
+ */
21
+ close(): Promise<void>;
22
+ /**
23
+ * Get the current configuration
24
+ */
25
+ getConfig(): AppConfig;
26
+ /**
27
+ * Start interactive CLI
28
+ */
29
+ startInteractiveCLI(): Promise<void>;
30
+ /**
31
+ * Handle CLI commands
32
+ */
33
+ private handleCommand;
34
+ /**
35
+ * Show help message
36
+ */
37
+ private showHelp;
38
+ }
39
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAIA,OAAO,EAAiB,SAAS,EAAE,MAAM,aAAa,CAAC;AAKvD,qBAAa,UAAU;IACrB,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,EAAE,CAAmC;;IAS7C;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B;;OAEG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAazC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B;;OAEG;IACH,SAAS,IAAI,SAAS;IAItB;;OAEG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IA2C1C;;OAEG;YACW,aAAa;IA4E3B;;OAEG;IACH,OAAO,CAAC,QAAQ;CAuBjB"}
package/dist/main.js ADDED
@@ -0,0 +1,206 @@
1
+ #!/usr/bin/env node
2
+ import * as readline from 'readline';
3
+ import { BrowserManager } from './browser.js';
4
+ import { ConfigManager } from './config.js';
5
+ import { SubmitManager } from './submit.js';
6
+ import { CookieExporter } from './cookie-export.js';
7
+ import { execSync } from 'child_process';
8
+ export class AtCoderGUI {
9
+ browserManager;
10
+ configManager;
11
+ submitManager;
12
+ cookieExporter;
13
+ rl = null;
14
+ constructor() {
15
+ this.browserManager = new BrowserManager();
16
+ this.configManager = new ConfigManager();
17
+ this.submitManager = new SubmitManager(this.browserManager);
18
+ this.cookieExporter = new CookieExporter(this.browserManager);
19
+ }
20
+ /**
21
+ * Initialize the application
22
+ */
23
+ async init() {
24
+ await this.browserManager.launch();
25
+ const url = this.getConfig().defaultUrl || 'https://atcoder.jp';
26
+ await this.browserManager.openUrl(url);
27
+ }
28
+ /**
29
+ * Open a URL in the browser
30
+ */
31
+ async openUrl(url) {
32
+ if (!this.browserManager.isRunning()) {
33
+ await this.init();
34
+ }
35
+ try {
36
+ await this.browserManager.openUrl(url);
37
+ console.log(`Opened URL: ${url}`);
38
+ }
39
+ catch (error) {
40
+ console.error(`Failed to open URL ${url}:`, error);
41
+ }
42
+ }
43
+ /**
44
+ * Close the application
45
+ */
46
+ async close() {
47
+ if (this.rl) {
48
+ this.rl.close();
49
+ }
50
+ await this.browserManager.close();
51
+ }
52
+ /**
53
+ * Get the current configuration
54
+ */
55
+ getConfig() {
56
+ return this.configManager.getConfig();
57
+ }
58
+ /**
59
+ * Start interactive CLI
60
+ */
61
+ async startInteractiveCLI() {
62
+ // Launch browser automatically on startup
63
+ await this.init();
64
+ this.rl = readline.createInterface({
65
+ input: process.stdin,
66
+ output: process.stdout,
67
+ prompt: 'command> '
68
+ });
69
+ this.browserManager.setOnPageClose(() => {
70
+ this.rl?.close();
71
+ });
72
+ console.log('Type "help" for available commands or "exit" to quit');
73
+ this.rl.prompt();
74
+ this.rl.on('line', async (input) => {
75
+ const trimmedInput = input.trim();
76
+ if (trimmedInput === '') {
77
+ this.rl.prompt();
78
+ return;
79
+ }
80
+ await this.handleCommand(trimmedInput);
81
+ this.rl.prompt();
82
+ });
83
+ this.rl.on('close', async () => {
84
+ console.log('\nGoodbye!');
85
+ await this.close();
86
+ process.exit(0);
87
+ });
88
+ // Handle Ctrl+C
89
+ process.on('SIGINT', async () => {
90
+ console.log('\nShutting down...');
91
+ await this.close();
92
+ process.exit(0);
93
+ });
94
+ }
95
+ /**
96
+ * Handle CLI commands
97
+ */
98
+ async handleCommand(input) {
99
+ const args = input.split(' ').filter(arg => arg.length > 0);
100
+ const command = args[0].toLowerCase();
101
+ try {
102
+ switch (command) {
103
+ case 'open':
104
+ if (args.length < 2) {
105
+ console.log('Error: URL is required for open command');
106
+ console.log('Usage: open <URL>');
107
+ return;
108
+ }
109
+ await this.openUrl(args[1]);
110
+ break;
111
+ case 'config':
112
+ console.log('Current configuration:');
113
+ console.log(JSON.stringify(this.getConfig(), null, 2));
114
+ break;
115
+ case 'help':
116
+ this.showHelp();
117
+ break;
118
+ case 'exit':
119
+ case 'quit':
120
+ this.rl?.close();
121
+ break;
122
+ case 'acc':
123
+ {
124
+ const command_line = args.join(' ');
125
+ const output = execSync(command_line, { encoding: 'utf-8' });
126
+ console.log(`result: ${output}`);
127
+ }
128
+ break;
129
+ case 'submit':
130
+ await this.submitManager.submitSolution();
131
+ break;
132
+ case 'export':
133
+ if (args.length < 2) {
134
+ console.log('Error: Target is required for export command');
135
+ console.log('Usage: export <target>');
136
+ console.log('Available targets:');
137
+ console.log(' atcoder-tools Export cookies to atcoder-tools cookie.txt');
138
+ console.log(' oj Export cookies to online-judge-tools cookie.jar');
139
+ return;
140
+ }
141
+ {
142
+ const target = args[1].toLowerCase();
143
+ switch (target) {
144
+ case 'atcoder-tools':
145
+ await this.cookieExporter.exportCookiesForAtCoderTools();
146
+ break;
147
+ case 'oj':
148
+ await this.cookieExporter.exportCookiesForOj();
149
+ break;
150
+ default:
151
+ console.log(`Unknown export target: ${target}`);
152
+ console.log('Available targets: atcoder-tools, oj');
153
+ }
154
+ }
155
+ break;
156
+ default:
157
+ console.log(`Unknown command: ${command}`);
158
+ console.log('Type "help" for available commands');
159
+ }
160
+ }
161
+ catch (error) {
162
+ console.error('Error:', error);
163
+ }
164
+ }
165
+ /**
166
+ * Show help message
167
+ */
168
+ showHelp() {
169
+ console.log(`
170
+ Available commands:
171
+ open <URL> Open a URL in the browser
172
+ config Show current configuration
173
+ submit Submit solution to AtCoder (requires metadata.json and main.cpp)
174
+ export <target> Export data to external tools
175
+ close Close the browser (if running)
176
+ help Show this help message
177
+ exit Exit the application
178
+
179
+ Export targets:
180
+ atcoder-tools Export browser cookies to atcoder-tools cookie.txt
181
+ oj Export browser cookies to online-judge-tools cookie.jar
182
+
183
+ Examples:
184
+ open https://atcoder.jp
185
+ open https://atcoder.jp/contests/abc123
186
+ submit (run from atcoder-tools directory)
187
+ export atcoder-tools (export REVEL_FLASH and REVEL_SESSION cookies)
188
+ export oj (export cookies to online-judge-tools)
189
+ `);
190
+ }
191
+ }
192
+ /**
193
+ * Main function to start the interactive CLI
194
+ */
195
+ async function main() {
196
+ const app = new AtCoderGUI();
197
+ await app.startInteractiveCLI();
198
+ }
199
+ // Run the CLI if this file is executed directly
200
+ if (import.meta.url === `file://${process.argv[1]}`) {
201
+ main().catch((error) => {
202
+ console.error('Fatal error:', error);
203
+ process.exit(1);
204
+ });
205
+ }
206
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import { BrowserContext } from 'playwright';
2
+ export interface SessionData {
3
+ cookies: Array<{
4
+ name: string;
5
+ value: string;
6
+ domain: string;
7
+ path: string;
8
+ expires: number;
9
+ httpOnly: boolean;
10
+ secure: boolean;
11
+ sameSite: 'Strict' | 'Lax' | 'None';
12
+ }>;
13
+ origins: Array<{
14
+ origin: string;
15
+ localStorage: Array<{
16
+ name: string;
17
+ value: string;
18
+ }>;
19
+ }>;
20
+ }
21
+ export declare class SessionManager {
22
+ private conf;
23
+ constructor();
24
+ /**
25
+ * Get the stored browser state for restoration
26
+ */
27
+ getStorageState(): SessionData | undefined;
28
+ /**
29
+ * Save the current browser context state
30
+ */
31
+ saveStorageState(context: BrowserContext): Promise<void>;
32
+ /**
33
+ * Clear the stored session data
34
+ */
35
+ clearSession(): void;
36
+ /**
37
+ * Check if session data exists
38
+ */
39
+ hasSession(): boolean;
40
+ /**
41
+ * Get session information
42
+ */
43
+ getSessionInfo(): {
44
+ hasSession: boolean;
45
+ cookieCount: number;
46
+ originCount: number;
47
+ };
48
+ /**
49
+ * Get the path to the session file
50
+ */
51
+ getSessionPath(): string;
52
+ }
53
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,OAAO,CAAC;QAClB,MAAM,EAAE,OAAO,CAAC;QAChB,QAAQ,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;KACrC,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,KAAK,CAAC;YAClB,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;SACf,CAAC,CAAC;KACJ,CAAC,CAAC;CACJ;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,IAAI,CAAoB;;IAahC;;OAEG;IACH,eAAe,IAAI,WAAW,GAAG,SAAS;IAQ1C;;OAEG;IACG,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAc9D;;OAEG;IACH,YAAY,IAAI,IAAI;IAKpB;;OAEG;IACH,UAAU,IAAI,OAAO;IAMrB;;OAEG;IACH,cAAc,IAAI;QAAE,UAAU,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE;IAWnF;;OAEG;IACH,cAAc,IAAI,MAAM;CAGzB"}
@@ -0,0 +1,73 @@
1
+ import Conf from 'conf';
2
+ export class SessionManager {
3
+ conf;
4
+ constructor() {
5
+ this.conf = new Conf({
6
+ projectName: 'atcoder-gui',
7
+ configName: 'session',
8
+ defaults: {
9
+ cookies: [],
10
+ origins: []
11
+ }
12
+ });
13
+ }
14
+ /**
15
+ * Get the stored browser state for restoration
16
+ */
17
+ getStorageState() {
18
+ const sessionData = this.conf.store;
19
+ if (!sessionData || (!sessionData.cookies.length && !sessionData.origins.length)) {
20
+ return undefined;
21
+ }
22
+ return sessionData;
23
+ }
24
+ /**
25
+ * Save the current browser context state
26
+ */
27
+ async saveStorageState(context) {
28
+ try {
29
+ const storageState = await context.storageState();
30
+ // Save cookies and origins directly at top level
31
+ this.conf.set('cookies', storageState.cookies || []);
32
+ this.conf.set('origins', storageState.origins || []);
33
+ console.log('Browser state saved successfully');
34
+ }
35
+ catch (error) {
36
+ console.error('Failed to save browser state:', error);
37
+ }
38
+ }
39
+ /**
40
+ * Clear the stored session data
41
+ */
42
+ clearSession() {
43
+ this.conf.clear();
44
+ console.log('Session data cleared');
45
+ }
46
+ /**
47
+ * Check if session data exists
48
+ */
49
+ hasSession() {
50
+ const cookies = this.conf.get('cookies');
51
+ const origins = this.conf.get('origins');
52
+ return !!(cookies.length || origins.length);
53
+ }
54
+ /**
55
+ * Get session information
56
+ */
57
+ getSessionInfo() {
58
+ const cookies = this.conf.get('cookies');
59
+ const origins = this.conf.get('origins');
60
+ return {
61
+ hasSession: this.hasSession(),
62
+ cookieCount: cookies.length || 0,
63
+ originCount: origins.length || 0
64
+ };
65
+ }
66
+ /**
67
+ * Get the path to the session file
68
+ */
69
+ getSessionPath() {
70
+ return this.conf.path;
71
+ }
72
+ }
73
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAuBxB,MAAM,OAAO,cAAc;IACjB,IAAI,CAAoB;IAEhC;QACE,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,CAAc;YAChC,WAAW,EAAE,aAAa;YAC1B,UAAU,EAAE,SAAS;YACrB,QAAQ,EAAE;gBACR,OAAO,EAAE,EAAE;gBACX,OAAO,EAAE,EAAE;aACZ;SACF,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,eAAe;QACb,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;QACpC,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACjF,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB,CAAC,OAAuB;QAC5C,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;YAElD,iDAAiD;YACjD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,YAAY,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;YACrD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,YAAY,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;YAErD,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,YAAY;QACV,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,UAAU;QACR,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACzC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAEzC,OAAO;YACL,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE;YAC7B,WAAW,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC;YAChC,WAAW,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC;SACjC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACxB,CAAC;CACF"}
@@ -0,0 +1,22 @@
1
+ import { BrowserManager } from './browser.js';
2
+ export declare class SubmitManager {
3
+ private browserManager;
4
+ constructor(browserManager: BrowserManager);
5
+ /**
6
+ * Submit solution to AtCoder
7
+ */
8
+ submitSolution(): Promise<void>;
9
+ /**
10
+ * Parse metadata.json to extract contest_id and problem_id
11
+ */
12
+ private parseMetadata;
13
+ /**
14
+ * Read source code from main.cpp
15
+ */
16
+ private readSourceCode;
17
+ /**
18
+ * Fill the source code area on AtCoder submit page
19
+ */
20
+ private fillSourceCodeArea;
21
+ }
22
+ //# sourceMappingURL=submit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submit.d.ts","sourceRoot":"","sources":["../src/submit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAoB9C,qBAAa,aAAa;IACxB,OAAO,CAAC,cAAc,CAAiB;gBAE3B,cAAc,EAAE,cAAc;IAI1C;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IA2CrC;;OAEG;IACH,OAAO,CAAC,aAAa;IAkBrB;;OAEG;IACH,OAAO,CAAC,cAAc;IAQtB;;OAEG;YACW,kBAAkB;CAmBjC"}