@exercode/problem-utils 1.16.6 → 1.16.7

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 (126) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +1 -0
  2. package/dist/helpers/checkProblemDirIsolation.cjs +2 -2
  3. package/dist/helpers/checkProblemDirIsolation.cjs.map +1 -1
  4. package/dist/helpers/checkProblemDirIsolation.js +2 -2
  5. package/dist/helpers/checkProblemDirIsolation.js.map +1 -1
  6. package/dist/helpers/cleanWorkingDirectory.cjs +2 -2
  7. package/dist/helpers/cleanWorkingDirectory.cjs.map +1 -1
  8. package/dist/helpers/cleanWorkingDirectory.js +2 -2
  9. package/dist/helpers/cleanWorkingDirectory.js.map +1 -1
  10. package/dist/helpers/compareStdoutAsSpaceSeparatedTokens.cjs +2 -2
  11. package/dist/helpers/compareStdoutAsSpaceSeparatedTokens.cjs.map +1 -1
  12. package/dist/helpers/compareStdoutAsSpaceSeparatedTokens.js +2 -2
  13. package/dist/helpers/compareStdoutAsSpaceSeparatedTokens.js.map +1 -1
  14. package/dist/helpers/copyTestCaseFileInput.cjs +2 -2
  15. package/dist/helpers/copyTestCaseFileInput.cjs.map +1 -1
  16. package/dist/helpers/copyTestCaseFileInput.js +2 -2
  17. package/dist/helpers/copyTestCaseFileInput.js.map +1 -1
  18. package/dist/helpers/findEntryPointFile.cjs +2 -2
  19. package/dist/helpers/findEntryPointFile.cjs.map +1 -1
  20. package/dist/helpers/findEntryPointFile.js +2 -2
  21. package/dist/helpers/findEntryPointFile.js.map +1 -1
  22. package/dist/helpers/findLanguageDefinitionByPath.cjs +2 -2
  23. package/dist/helpers/findLanguageDefinitionByPath.cjs.map +1 -1
  24. package/dist/helpers/findLanguageDefinitionByPath.js +2 -2
  25. package/dist/helpers/findLanguageDefinitionByPath.js.map +1 -1
  26. package/dist/helpers/findModelAnswerDirs.cjs +2 -2
  27. package/dist/helpers/findModelAnswerDirs.cjs.map +1 -1
  28. package/dist/helpers/findModelAnswerDirs.js +2 -2
  29. package/dist/helpers/findModelAnswerDirs.js.map +1 -1
  30. package/dist/helpers/judgeByStaticAnalysis.cjs +19 -2
  31. package/dist/helpers/judgeByStaticAnalysis.cjs.map +1 -1
  32. package/dist/helpers/judgeByStaticAnalysis.js +19 -2
  33. package/dist/helpers/judgeByStaticAnalysis.js.map +1 -1
  34. package/dist/helpers/parseArgs.cjs +2 -2
  35. package/dist/helpers/parseArgs.cjs.map +1 -1
  36. package/dist/helpers/parseArgs.js +2 -2
  37. package/dist/helpers/parseArgs.js.map +1 -1
  38. package/dist/helpers/printDebugBanner.cjs +3 -2
  39. package/dist/helpers/printDebugBanner.cjs.map +1 -1
  40. package/dist/helpers/printDebugBanner.js +3 -2
  41. package/dist/helpers/printDebugBanner.js.map +1 -1
  42. package/dist/helpers/printTestCaseResult.cjs +2 -2
  43. package/dist/helpers/printTestCaseResult.cjs.map +1 -1
  44. package/dist/helpers/printTestCaseResult.js +2 -2
  45. package/dist/helpers/printTestCaseResult.js.map +1 -1
  46. package/dist/helpers/readOutputFiles.cjs +2 -2
  47. package/dist/helpers/readOutputFiles.cjs.map +1 -1
  48. package/dist/helpers/readOutputFiles.js +2 -2
  49. package/dist/helpers/readOutputFiles.js.map +1 -1
  50. package/dist/helpers/readProblemMarkdownFrontMatter.cjs +2 -2
  51. package/dist/helpers/readProblemMarkdownFrontMatter.cjs.map +1 -1
  52. package/dist/helpers/readProblemMarkdownFrontMatter.js +2 -2
  53. package/dist/helpers/readProblemMarkdownFrontMatter.js.map +1 -1
  54. package/dist/helpers/readTestCases.cjs +2 -2
  55. package/dist/helpers/readTestCases.cjs.map +1 -1
  56. package/dist/helpers/readTestCases.js +2 -2
  57. package/dist/helpers/readTestCases.js.map +1 -1
  58. package/dist/helpers/removeCommentsInSourceCode.cjs +6 -2
  59. package/dist/helpers/removeCommentsInSourceCode.cjs.map +1 -1
  60. package/dist/helpers/removeCommentsInSourceCode.js +6 -2
  61. package/dist/helpers/removeCommentsInSourceCode.js.map +1 -1
  62. package/dist/helpers/resolveCwds.cjs +2 -2
  63. package/dist/helpers/resolveCwds.cjs.map +1 -1
  64. package/dist/helpers/resolveCwds.js +2 -2
  65. package/dist/helpers/resolveCwds.js.map +1 -1
  66. package/dist/helpers/runCommandInTemporaryPackageManagerProject.cjs +2 -2
  67. package/dist/helpers/runCommandInTemporaryPackageManagerProject.cjs.map +1 -1
  68. package/dist/helpers/runCommandInTemporaryPackageManagerProject.js +2 -2
  69. package/dist/helpers/runCommandInTemporaryPackageManagerProject.js.map +1 -1
  70. package/dist/helpers/runPythonInTemporaryUvProject.cjs +2 -2
  71. package/dist/helpers/runPythonInTemporaryUvProject.cjs.map +1 -1
  72. package/dist/helpers/runPythonInTemporaryUvProject.js +2 -2
  73. package/dist/helpers/runPythonInTemporaryUvProject.js.map +1 -1
  74. package/dist/helpers/sourceCodeGrammars.cjs +2 -2
  75. package/dist/helpers/sourceCodeGrammars.cjs.map +1 -1
  76. package/dist/helpers/sourceCodeGrammars.js +2 -2
  77. package/dist/helpers/sourceCodeGrammars.js.map +1 -1
  78. package/dist/helpers/spawnSyncWithTimeout.cjs +2 -2
  79. package/dist/helpers/spawnSyncWithTimeout.cjs.map +1 -1
  80. package/dist/helpers/spawnSyncWithTimeout.js +2 -2
  81. package/dist/helpers/spawnSyncWithTimeout.js.map +1 -1
  82. package/dist/helpers/startHttpServer.cjs +2 -2
  83. package/dist/helpers/startHttpServer.cjs.map +1 -1
  84. package/dist/helpers/startHttpServer.js +2 -2
  85. package/dist/helpers/startHttpServer.js.map +1 -1
  86. package/dist/index.cjs +1 -2
  87. package/dist/index.js +1 -2
  88. package/dist/presets/command.cjs +2 -2
  89. package/dist/presets/command.cjs.map +1 -1
  90. package/dist/presets/command.js +2 -2
  91. package/dist/presets/command.js.map +1 -1
  92. package/dist/presets/guiCommand.cjs +4 -2
  93. package/dist/presets/guiCommand.cjs.map +1 -1
  94. package/dist/presets/guiCommand.js +4 -2
  95. package/dist/presets/guiCommand.js.map +1 -1
  96. package/dist/presets/llm.cjs +2 -2
  97. package/dist/presets/llm.cjs.map +1 -1
  98. package/dist/presets/llm.js +2 -2
  99. package/dist/presets/llm.js.map +1 -1
  100. package/dist/presets/stdio.cjs +2 -2
  101. package/dist/presets/stdio.cjs.map +1 -1
  102. package/dist/presets/stdio.js +2 -2
  103. package/dist/presets/stdio.js.map +1 -1
  104. package/dist/types/decisionCode.cjs +2 -2
  105. package/dist/types/decisionCode.cjs.map +1 -1
  106. package/dist/types/decisionCode.js +2 -2
  107. package/dist/types/decisionCode.js.map +1 -1
  108. package/dist/types/language.cjs +11 -2
  109. package/dist/types/language.cjs.map +1 -1
  110. package/dist/types/language.js +11 -2
  111. package/dist/types/language.js.map +1 -1
  112. package/dist/types/problem.cjs +2 -2
  113. package/dist/types/problem.cjs.map +1 -1
  114. package/dist/types/problem.js +2 -2
  115. package/dist/types/problem.js.map +1 -1
  116. package/dist/types/testCaseResult.cjs +2 -2
  117. package/dist/types/testCaseResult.cjs.map +1 -1
  118. package/dist/types/testCaseResult.js +2 -2
  119. package/dist/types/testCaseResult.js.map +1 -1
  120. package/package.json +14 -14
  121. package/dist/_virtual/_rollupPluginBabelHelpers.cjs +0 -4
  122. package/dist/_virtual/_rollupPluginBabelHelpers.cjs.map +0 -1
  123. package/dist/_virtual/_rollupPluginBabelHelpers.js +0 -4
  124. package/dist/_virtual/_rollupPluginBabelHelpers.js.map +0 -1
  125. package/dist/index.cjs.map +0 -1
  126. package/dist/index.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"guiCommand.cjs","sources":["../../src/presets/guiCommand.ts"],"sourcesContent":["import childProcess from 'node:child_process';\nimport fs from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { setTimeout as wait } from 'node:timers/promises';\n\nimport { z } from 'zod';\n\nimport { cleanWorkingDirectory, snapshotWorkingDirectory } from '../helpers/cleanWorkingDirectory.js';\nimport { copyTestCaseFileInput } from '../helpers/copyTestCaseFileInput.js';\nimport { findEntryPointFile } from '../helpers/findEntryPointFile.js';\nimport { findLanguageDefinitionByPath } from '../helpers/findLanguageDefinitionByPath.js';\nimport { judgeByStaticAnalysis } from '../helpers/judgeByStaticAnalysis.js';\nimport { parseArgs } from '../helpers/parseArgs.js';\nimport { printTestCaseResult } from '../helpers/printTestCaseResult.js';\nimport { readOutputFiles } from '../helpers/readOutputFiles.js';\nimport { readProblemMarkdownFrontMatter } from '../helpers/readProblemMarkdownFrontMatter.js';\nimport { readTestCases as readFileTestCases } from '../helpers/readTestCases.js';\nimport { spawnSyncWithTimeout } from '../helpers/spawnSyncWithTimeout.js';\nimport { DecisionCode } from '../types/decisionCode.js';\nimport { languageIdToDefinition } from '../types/language.js';\nimport type { ProblemMarkdownFrontMatter } from '../types/problem.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\nconst BUILD_TIMEOUT_SECONDS = 10;\nconst JUDGE_DEFAULT_TIMEOUT_SECONDS = 5;\nconst SCREENSHOT_WAIT_SECONDS = 0.3;\nconst XVFB_STARTUP_WAIT_SECONDS = 0.3;\nconst XVFB_SHUTDOWN_WAIT_SECONDS = 0.1;\nconst PROCESS_SHUTDOWN_WAIT_SECONDS = 0.2;\nconst STOP_DETECTION_THRESHOLD = 5;\nconst TIME_COMMAND = [os.platform() === 'darwin' ? 'gtime' : '/usr/bin/time', '--format', '%e %M'] as const;\n\nconst judgeParamsSchema = z.object({\n language: z.union([z.string(), z.array(z.string())]).optional(),\n});\n\ninterface BaseGuiTestCase {\n id: string;\n input?: string;\n fileInputPath?: string;\n}\n\nexport interface GuiScreenshotFile {\n path: string;\n data: string;\n encoding: 'base64';\n}\n\nexport interface GuiCommandRunResult {\n stdin: string;\n stdout: string;\n stderr: string;\n status: number | undefined;\n timeSeconds: number;\n memoryBytes: number;\n screenshots: GuiScreenshotFile[];\n stopReason: 'process_exit' | 'stable_screenshot' | 'timeout';\n}\n\ninterface GuiJudgeContext {\n timeLimitSeconds: number;\n problemMarkdownFrontMatter: Pick<ProblemMarkdownFrontMatter, 'memoryLimitByte' | 'requiredOutputFilePaths'>;\n}\n\ntype GuiJudgeCaseResult = Pick<\n TestCaseResult,\n 'decisionCode' | 'feedbackMarkdown' | 'stderr' | 'stdout' | 'outputFiles'\n>;\n\nexport interface GuiCommandJudgePresetOptions<TTestCase extends BaseGuiTestCase = BaseGuiTestCase> {\n mainFilePath?: string;\n runTimeoutSeconds?: number;\n screenshotWaitSeconds?: number;\n stopDetectionThreshold?: number;\n readTestCases?: (problemDir: string) => Promise<readonly TTestCase[]>;\n prepare?: (context: {\n cwd: string;\n env: NodeJS.ProcessEnv;\n mainFilePath: string;\n problemMarkdownFrontMatter: ProblemMarkdownFrontMatter;\n }) => Promise<Partial<GuiJudgeCaseResult> | undefined> | Partial<GuiJudgeCaseResult> | undefined;\n resolveInput?: (context: { testCase: TTestCase; cwd: string; env: NodeJS.ProcessEnv }) => Promise<string> | string;\n command?: (context: {\n testCase: TTestCase;\n cwd: string;\n env: NodeJS.ProcessEnv;\n mainFilePath: string;\n }) => Promise<readonly [string, ...string[]]> | readonly [string, ...string[]];\n runCommand?: (context: {\n testCase: TTestCase;\n command: readonly [string, ...string[]];\n stdin: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeLimitSeconds: number;\n screenshotWaitSeconds: number;\n stopDetectionThreshold: number;\n }) => Promise<GuiCommandRunResult> | GuiCommandRunResult;\n test: (context: {\n testCase: TTestCase;\n runResult: GuiCommandRunResult;\n outputFiles: NonNullable<TestCaseResult['outputFiles']>;\n context: GuiJudgeContext;\n }) => Promise<Partial<GuiJudgeCaseResult>> | Partial<GuiJudgeCaseResult>;\n}\n\n/**\n * A preset function for judging GUI programs by collecting screenshots while the program runs.\n *\n * Keep problem-specific logic in `prepare`, `command`, and `test`.\n *\n * @example\n * Create `judge.ts`:\n * ```ts\n * import { DecisionCode } from '@exercode/problem-utils';\n * import { guiCommandJudgePreset } from '@exercode/problem-utils/presets/guiCommand';\n *\n * await guiCommandJudgePreset(import.meta.dirname, {\n * mainFilePath: 'Main.java',\n * readTestCases: async () => [{ id: 'default' }],\n * test: ({ runResult }) => {\n * return runResult.screenshots.length > 0\n * ? { decisionCode: DecisionCode.ACCEPTED }\n * : { decisionCode: DecisionCode.WRONG_ANSWER };\n * },\n * });\n * ```\n */\nexport async function guiCommandJudgePreset<TTestCase extends BaseGuiTestCase = BaseGuiTestCase>(\n problemDir: string,\n options: GuiCommandJudgePresetOptions<TTestCase>\n): Promise<void> {\n const args = parseArgs(process.argv);\n if (!args.cwd) throw new Error('cwd argument required');\n const params = judgeParamsSchema.parse(args.params);\n\n const problemMarkdownFrontMatter = await readProblemMarkdownFrontMatter(problemDir);\n const configuredTestCases = await (options.readTestCases ?? readGuiTestCases<TTestCase>)(problemDir);\n const testCases =\n configuredTestCases.length > 0 ? configuredTestCases : ([{ id: 'default' }] as unknown as readonly TTestCase[]);\n const prebuildTestCaseId = testCases[0]?.id ?? 'prebuild';\n\n const staticAnalysisResult = await judgeByStaticAnalysis(args.cwd, problemMarkdownFrontMatter);\n if (staticAnalysisResult) {\n printTestCaseResult({ testCaseId: prebuildTestCaseId, ...staticAnalysisResult });\n return;\n }\n\n const initialMainFilePath = options.mainFilePath ?? (await findEntryPointFile(args.cwd, params.language));\n if (!initialMainFilePath) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,\n stderr: options.mainFilePath\n ? `required main file not found: ${options.mainFilePath}`\n : `main file not found${params.language ? `: language: ${params.language}` : ''}`,\n });\n return;\n }\n\n const languageDefinition = findLanguageDefinitionByPath(initialMainFilePath);\n if (!languageDefinition) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.WRONG_ANSWER,\n stderr: 'unsupported language',\n });\n return;\n }\n\n const env = { ...process.env, CI: '', FORCE_COLOR: '0' };\n\n let resolvedMainFilePath = await resolveMainFilePath({\n cwd: args.cwd,\n language: params.language,\n configuredMainFilePath: options.mainFilePath,\n });\n if (languageDefinition.prebuild) {\n try {\n await languageDefinition.prebuild(args.cwd);\n const prebuiltMainFilePath = await resolveMainFilePath({\n cwd: args.cwd,\n language: params.language ?? inferLanguageIdsByPath(initialMainFilePath),\n configuredMainFilePath: options.mainFilePath,\n allowConfiguredPathFallback: true,\n });\n if (prebuiltMainFilePath) resolvedMainFilePath = prebuiltMainFilePath;\n } catch (error) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.BUILD_ERROR,\n stderr: errorToMessage(error),\n });\n return;\n }\n }\n if (!resolvedMainFilePath) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,\n stderr: options.mainFilePath\n ? `required main file not found: ${options.mainFilePath}`\n : `main file not found${params.language ? `: language: ${params.language}` : ''}`,\n });\n return;\n }\n\n const prepareResult =\n (await options.prepare?.({\n cwd: args.cwd,\n env,\n mainFilePath: resolvedMainFilePath,\n problemMarkdownFrontMatter,\n })) ??\n runDefaultPrepare({\n cwd: args.cwd,\n env,\n mainFilePath: resolvedMainFilePath,\n languageDefinition,\n });\n if (prepareResult) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: prepareResult.decisionCode ?? DecisionCode.BUILD_ERROR,\n feedbackMarkdown: prepareResult.feedbackMarkdown,\n stderr: prepareResult.stderr,\n stdout: prepareResult.stdout,\n outputFiles: prepareResult.outputFiles,\n });\n return;\n }\n\n const cwdSnapshot = await snapshotWorkingDirectory(args.cwd);\n let displayServer: Awaited<ReturnType<typeof ensureDisplayServer>> | undefined;\n let currentTestCaseId = prebuildTestCaseId;\n let currentStdin: string | undefined;\n try {\n displayServer = options.runCommand ? undefined : await ensureDisplayServer();\n const sharedFileInputPath = (configuredTestCases as { shared?: { fileInputPath?: string } }).shared?.fileInputPath;\n for (const testCase of testCases) {\n currentTestCaseId = testCase.id;\n if (sharedFileInputPath) await copyTestCaseFileInput(sharedFileInputPath, args.cwd);\n if (testCase.fileInputPath) await copyTestCaseFileInput(testCase.fileInputPath, args.cwd);\n\n const timeLimitSeconds =\n typeof problemMarkdownFrontMatter.timeLimitMs === 'number'\n ? problemMarkdownFrontMatter.timeLimitMs / 1000\n : (options.runTimeoutSeconds ?? JUDGE_DEFAULT_TIMEOUT_SECONDS);\n\n const runEnv = displayServer ? { ...env, DISPLAY: displayServer.display } : env;\n const stdin = (await options.resolveInput?.({ testCase, cwd: args.cwd, env: runEnv })) ?? testCase.input ?? '';\n currentStdin = stdin;\n const command =\n (await options.command?.({ testCase, cwd: args.cwd, env: runEnv, mainFilePath: resolvedMainFilePath })) ??\n languageDefinition.command(resolvedMainFilePath);\n\n let runResult: GuiCommandRunResult;\n try {\n runResult = options.runCommand\n ? await options.runCommand({\n testCase,\n command,\n stdin,\n cwd: args.cwd,\n env: runEnv,\n timeLimitSeconds,\n screenshotWaitSeconds: options.screenshotWaitSeconds ?? SCREENSHOT_WAIT_SECONDS,\n stopDetectionThreshold: options.stopDetectionThreshold ?? STOP_DETECTION_THRESHOLD,\n })\n : await spawnGuiProgram({\n command,\n stdin,\n cwd: args.cwd,\n env: runEnv,\n timeLimitSeconds,\n screenshotWaitSeconds: options.screenshotWaitSeconds ?? SCREENSHOT_WAIT_SECONDS,\n stopDetectionThreshold: options.stopDetectionThreshold ?? STOP_DETECTION_THRESHOLD,\n });\n } catch (error) {\n printTestCaseResult({\n testCaseId: testCase.id,\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stdin,\n stderr: errorToMessage(error),\n });\n await cleanWorkingDirectory(args.cwd, cwdSnapshot);\n return;\n }\n\n const outputFiles = await readOutputFiles(args.cwd, problemMarkdownFrontMatter.requiredOutputFilePaths ?? []);\n const judgeContext: GuiJudgeContext = {\n timeLimitSeconds,\n problemMarkdownFrontMatter: {\n memoryLimitByte: problemMarkdownFrontMatter.memoryLimitByte,\n requiredOutputFilePaths: problemMarkdownFrontMatter.requiredOutputFilePaths,\n },\n };\n const baseJudgeResult = evaluateGuiRunResult({ runResult, outputFiles, context: judgeContext });\n let judgeResult = baseJudgeResult;\n if (baseJudgeResult.decisionCode === DecisionCode.ACCEPTED) {\n try {\n const extendedJudgeResult = await options.test({\n testCase,\n runResult,\n outputFiles,\n context: judgeContext,\n });\n judgeResult = {\n decisionCode: extendedJudgeResult.decisionCode ?? baseJudgeResult.decisionCode,\n feedbackMarkdown: extendedJudgeResult.feedbackMarkdown,\n stderr: extendedJudgeResult.stderr,\n stdout: extendedJudgeResult.stdout,\n outputFiles: extendedJudgeResult.outputFiles,\n };\n } catch (error) {\n judgeResult = {\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stderr: errorToMessage(error),\n };\n }\n }\n\n const decisionCode = judgeResult.decisionCode ?? DecisionCode.ACCEPTED;\n const stdout = judgeResult.stdout ?? runResult.stdout;\n const stderr = judgeResult.stderr ?? runResult.stderr;\n printTestCaseResult({\n testCaseId: testCase.id,\n decisionCode,\n exitStatus: runResult.status,\n stdin: runResult.stdin || undefined,\n stdout: stdout || undefined,\n stderr: stderr || undefined,\n timeSeconds: runResult.timeSeconds,\n memoryBytes: runResult.memoryBytes,\n feedbackMarkdown: judgeResult.feedbackMarkdown,\n outputFiles: judgeResult.outputFiles ?? (outputFiles.length > 0 ? outputFiles : undefined),\n });\n\n await cleanWorkingDirectory(args.cwd, cwdSnapshot);\n if (decisionCode !== DecisionCode.ACCEPTED) break;\n }\n } catch (error) {\n printTestCaseResult({\n testCaseId: currentTestCaseId,\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stdin: currentStdin,\n stderr: errorToMessage(error),\n });\n await cleanWorkingDirectory(args.cwd, cwdSnapshot);\n } finally {\n await displayServer?.dispose();\n }\n}\n\nasync function resolveMainFilePath(context: {\n cwd: string;\n language?: string | string[];\n configuredMainFilePath?: string;\n allowConfiguredPathFallback?: boolean;\n}): Promise<string | undefined> {\n if (context.configuredMainFilePath) {\n const resolvedPath = path.join(context.cwd, context.configuredMainFilePath);\n if (await pathExists(resolvedPath)) return context.configuredMainFilePath;\n if (!context.allowConfiguredPathFallback) return undefined;\n }\n\n return await findEntryPointFile(context.cwd, context.language);\n}\n\nfunction inferLanguageIdsByPath(filePath: string): string[] | undefined {\n const languageIds = Object.entries(languageIdToDefinition)\n .filter(([, definition]) => definition.fileExtensions.some((ext) => filePath.endsWith(ext)))\n .map(([languageId]) => languageId);\n return languageIds.length > 0 ? languageIds : undefined;\n}\n\nfunction runDefaultPrepare(context: {\n cwd: string;\n env: NodeJS.ProcessEnv;\n mainFilePath: string;\n languageDefinition: NonNullable<ReturnType<typeof findLanguageDefinitionByPath>>;\n}): Partial<GuiJudgeCaseResult> | undefined {\n const buildCommand = context.languageDefinition.buildCommand?.(context.mainFilePath);\n if (!buildCommand) return undefined;\n\n const buildResult = spawnSyncWithTimeout(\n buildCommand[0],\n buildCommand.slice(1),\n { cwd: context.cwd, encoding: 'utf8', env: context.env },\n BUILD_TIMEOUT_SECONDS\n );\n\n if (buildResult.timeSeconds > BUILD_TIMEOUT_SECONDS) {\n return {\n decisionCode: DecisionCode.BUILD_TIME_LIMIT_EXCEEDED,\n stderr: buildResult.stderr || undefined,\n };\n }\n\n if (buildResult.status !== 0) {\n return {\n decisionCode: DecisionCode.BUILD_ERROR,\n stderr: buildResult.stderr || buildResult.stdout || undefined,\n };\n }\n\n return undefined;\n}\n\nfunction evaluateGuiRunResult(context: {\n runResult: GuiCommandRunResult;\n outputFiles: NonNullable<TestCaseResult['outputFiles']>;\n context: GuiJudgeContext;\n}): Partial<GuiJudgeCaseResult> {\n if (context.runResult.stopReason === 'timeout') {\n return {\n decisionCode: DecisionCode.TIME_LIMIT_EXCEEDED,\n stderr: context.runResult.stderr,\n };\n }\n\n if (context.runResult.status !== 0) {\n return {\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stderr: context.runResult.stderr,\n };\n }\n\n if (\n context.runResult.memoryBytes >\n (context.context.problemMarkdownFrontMatter.memoryLimitByte ?? Number.POSITIVE_INFINITY)\n ) {\n return {\n decisionCode: DecisionCode.MEMORY_LIMIT_EXCEEDED,\n stderr: context.runResult.stderr,\n };\n }\n\n const requiredOutputFilesCount = context.context.problemMarkdownFrontMatter.requiredOutputFilePaths?.length ?? 0;\n if (context.outputFiles.length < requiredOutputFilesCount) {\n return {\n decisionCode: DecisionCode.MISSING_REQUIRED_OUTPUT_FILE_ERROR,\n };\n }\n\n return { decisionCode: DecisionCode.ACCEPTED };\n}\n\nasync function readGuiTestCases<TTestCase extends BaseGuiTestCase>(problemDir: string): Promise<readonly TTestCase[]> {\n return (await readFileTestCases(path.join(problemDir, 'test_cases'))) as unknown as readonly TTestCase[];\n}\n\nasync function spawnGuiProgram(context: {\n command: readonly [string, ...string[]];\n stdin: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeLimitSeconds: number;\n screenshotWaitSeconds: number;\n stopDetectionThreshold: number;\n}): Promise<GuiCommandRunResult> {\n const wrappedCommand = ['timeout', context.timeLimitSeconds.toFixed(3), ...TIME_COMMAND, ...context.command] as const;\n const child = childProcess.spawn(wrappedCommand[0], wrappedCommand.slice(1), {\n cwd: context.cwd,\n env: context.env,\n detached: process.platform !== 'win32',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n child.stdout.setEncoding('utf8');\n child.stderr.setEncoding('utf8');\n\n let stdout = '';\n let stderr = '';\n let exitCode: number | undefined;\n let spawnError: Error | undefined;\n let stopReason: GuiCommandRunResult['stopReason'] = 'process_exit';\n const screenshotSignaturesHistory: string[][] = [];\n let screenshots: GuiScreenshotFile[] = [];\n const startTimeSeconds = Date.now() / 1000;\n let sampledMemoryBytes = 0;\n\n child.stdout.on('data', (chunk: string) => {\n stdout += chunk;\n });\n child.stderr.on('data', (chunk: string) => {\n stderr += chunk;\n });\n child.on('error', (error) => {\n spawnError = error;\n exitCode = 1;\n });\n child.on('close', (code, signal) => {\n if (code === 124) {\n stopReason = 'timeout';\n exitCode = 0;\n return;\n }\n if (signal) {\n exitCode = 1;\n stderr = stderr\n ? `${stderr}\\nprocess terminated by signal: ${signal}`\n : `process terminated by signal: ${signal}`;\n return;\n }\n exitCode = code ?? 1;\n });\n\n if (context.stdin) child.stdin.write(context.stdin);\n child.stdin.end();\n\n while (exitCode === undefined) {\n await wait(context.screenshotWaitSeconds * 1000);\n sampledMemoryBytes = Math.max(sampledMemoryBytes, readProcessGroupMemoryBytes(child.pid));\n const currentScreenshots = takeScreenshots(context.env.DISPLAY);\n screenshots = currentScreenshots.toSorted((a, b) => a.data.length - b.data.length);\n\n if (screenshots.length > 0) {\n const screenshotSignatures = screenshots.map((file) => file.data).toSorted();\n screenshotSignaturesHistory.unshift(screenshotSignatures);\n screenshotSignaturesHistory.length = Math.min(screenshotSignaturesHistory.length, context.stopDetectionThreshold);\n if (\n screenshotSignaturesHistory.length === context.stopDetectionThreshold &&\n screenshotSignaturesHistory.every(\n (files) =>\n files.length === screenshotSignatures.length &&\n files.every((file, index) => file === screenshotSignatures[index])\n )\n ) {\n stopReason = 'stable_screenshot';\n exitCode = 0;\n break;\n }\n }\n\n if (Date.now() / 1000 - startTimeSeconds > context.timeLimitSeconds) {\n stopReason = 'timeout';\n exitCode = 0;\n break;\n }\n }\n\n if (stopReason !== 'process_exit' && child.exitCode === null) {\n child.removeAllListeners('close');\n child.removeAllListeners('error');\n }\n await stopProcess(child);\n if (spawnError) throw spawnError;\n const {\n memoryBytes,\n stderr: normalizedStderr,\n timeSeconds,\n } = parseTimedStderr(stderr, startTimeSeconds, sampledMemoryBytes);\n\n return {\n stdin: context.stdin,\n stdout: stdout.trimEnd(),\n stderr: normalizedStderr,\n status: exitCode,\n timeSeconds,\n memoryBytes,\n screenshots,\n stopReason,\n };\n}\n\nfunction takeScreenshots(display: string | undefined): GuiScreenshotFile[] {\n const env = display ? { ...process.env, DISPLAY: display } : process.env;\n const xwininfo = childProcess.spawnSync('xwininfo', ['-root', '-tree'], { encoding: 'utf8', env });\n if (xwininfo.error) throw xwininfo.error;\n if (xwininfo.status !== 0 || !xwininfo.stdout) return [];\n\n const screenshots: GuiScreenshotFile[] = [];\n for (const windowId of extractTopLevelWindowIds(xwininfo.stdout)) {\n const screenshot = childProcess.spawnSync('maim', ['-i', windowId], { env });\n if (screenshot.error) throw screenshot.error;\n if (screenshot.status !== 0 || screenshot.stdout.length === 0) continue;\n\n const windowNameResult = childProcess.spawnSync('xdotool', ['getwindowname', windowId], { encoding: 'utf8', env });\n if (windowNameResult.error) throw windowNameResult.error;\n const windowName = windowNameResult.stdout.trim().replaceAll(/[\\s/]/g, '_');\n\n screenshots.push({\n path: `${windowName || 'window'}_${windowId}.png`,\n data: screenshot.stdout.toString('base64'),\n encoding: 'base64',\n });\n }\n\n return screenshots;\n}\n\nfunction extractTopLevelWindowIds(stdout: string): string[] {\n const windowIds: string[] = [];\n const lines = stdout.split('\\n');\n for (const line of lines) {\n if (line.includes('Root window id:') || line.includes('Parent window id:') || line.includes('()')) continue;\n\n const match = /^\\s{5}(0x[\\da-f]+) /.exec(line);\n if (!match?.[1]) continue;\n windowIds.push(Number.parseInt(match[1], 16).toString());\n }\n return windowIds;\n}\n\nfunction parseTimedStderr(\n stderr: string,\n startTimeSeconds: number,\n sampledMemoryBytes: number\n): Pick<GuiCommandRunResult, 'stderr' | 'timeSeconds' | 'memoryBytes'> {\n const match = /(?:^|\\n)(\\d+\\.\\d+) (\\d+)\\s*$/.exec(stderr);\n const normalizedStderr = match ? stderr.slice(0, match.index).trimEnd() : stderr.trimEnd();\n const parsedMemoryBytes = Number(match?.[2]) * 1024 || 0;\n return {\n stderr: normalizedStderr,\n timeSeconds: Number(match?.[1]) || Date.now() / 1000 - startTimeSeconds,\n memoryBytes: Math.max(parsedMemoryBytes, sampledMemoryBytes),\n };\n}\n\nasync function ensureDisplayServer(): Promise<{ display: string; dispose: () => Promise<void> }> {\n if (process.platform !== 'linux') {\n throw new Error('GUI screenshot capture is supported only on Linux.');\n }\n\n for (let displayNumber = 90; displayNumber < 100; displayNumber++) {\n const display = `:${displayNumber}`;\n let spawnError: Error | undefined;\n const xvfb = childProcess.spawn('Xvfb', [display, '-screen', '0', '1280x1024x24', '-ac'], {\n stdio: 'ignore',\n });\n xvfb.on('error', (error) => {\n spawnError = error;\n });\n\n await wait(XVFB_STARTUP_WAIT_SECONDS * 1000);\n if (spawnError) throw spawnError;\n if (xvfb.exitCode !== null) continue;\n\n return {\n display,\n dispose: async () => {\n if (!xvfb.killed) {\n xvfb.kill('SIGTERM');\n await wait(XVFB_SHUTDOWN_WAIT_SECONDS * 1000);\n if (xvfb.exitCode === null) xvfb.kill('SIGKILL');\n }\n },\n };\n }\n\n throw new Error('Xvfb could not be started.');\n}\n\nasync function stopProcess(child: childProcess.ChildProcess): Promise<void> {\n if (!child.pid) return;\n killProcessGroup(child.pid, 'SIGTERM');\n await wait(PROCESS_SHUTDOWN_WAIT_SECONDS * 1000);\n if (child.exitCode === null) killProcessGroup(child.pid, 'SIGKILL');\n}\n\nfunction readProcessGroupMemoryBytes(processGroupId: number | undefined): number {\n if (!processGroupId || process.platform !== 'linux') return 0;\n\n const result = childProcess.spawnSync('ps', ['-o', 'rss=', '--no-headers', '--pgroup', String(processGroupId)], {\n encoding: 'utf8',\n });\n if (result.error || result.status !== 0 || !result.stdout) return 0;\n\n return result.stdout\n .split('\\n')\n .map((line) => Number(line.trim()))\n .filter((value) => Number.isFinite(value) && value > 0)\n .reduce((sum, value) => sum + value * 1024, 0);\n}\n\nfunction killProcessGroup(processGroupId: number, signal: NodeJS.Signals): void {\n try {\n if (process.platform !== 'win32') {\n process.kill(-processGroupId, signal);\n return;\n }\n } catch {\n // The process group may already be gone. Fall back to the direct PID below.\n }\n\n try {\n process.kill(processGroupId, signal);\n } catch {\n // The direct child may also already be gone.\n }\n}\n\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction errorToMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"names":["TIME_COMMAND","os","platform","judgeParamsSchema","z","object","language","union","string","array","optional","_guiCommandJudgePreset","_asyncToGenerator","_regenerator","m","_callee","problemDir","options","_options$readTestCase","_testCases$0$id","_testCases$","_options$mainFilePath","_yield$options$prepar","_options$prepare","args","params","problemMarkdownFrontMatter","configuredTestCases","testCases","prebuildTestCaseId","staticAnalysisResult","initialMainFilePath","languageDefinition","env","resolvedMainFilePath","_params$language","prebuiltMainFilePath","prepareResult","_prepareResult$decisi","cwdSnapshot","displayServer","currentTestCaseId","currentStdin","_shared","sharedFileInputPath","_iterator2","_step2","_options$runTimeoutSe","_ref5","_yield$options$resolv","_options$resolveInput","_yield$options$comman","_options$command","_problemMarkdownFront","_judgeResult$decision","_judgeResult$stdout","_judgeResult$stderr","_judgeResult$outputFi","testCase","timeLimitSeconds","runEnv","stdin","command","runResult","_options$screenshotWa","_options$stopDetectio","_options$screenshotWa2","_options$stopDetectio2","outputFiles","judgeContext","baseJudgeResult","judgeResult","_extendedJudgeResult$","extendedJudgeResult","decisionCode","stdout","stderr","_displayServer","_t","_t2","_t4","_t5","_t7","_t9","_t1","_t10","_t11","_t12","_t13","_t14","w","_context","p","n","parseArgs","process","argv","cwd","Error","parse","readProblemMarkdownFrontMatter","v","readTestCases","readGuiTestCases","length","id","judgeByStaticAnalysis","printTestCaseResult","_objectSpread","testCaseId","a","mainFilePath","findEntryPointFile","DecisionCode","MISSING_REQUIRED_SUBMISSION_FILE_ERROR","concat","findLanguageDefinitionByPath","WRONG_ANSWER","CI","FORCE_COLOR","resolveMainFilePath","configuredMainFilePath","prebuild","inferLanguageIdsByPath","allowConfiguredPathFallback","BUILD_ERROR","errorToMessage","prepare","call","runDefaultPrepare","feedbackMarkdown","snapshotWorkingDirectory","runCommand","undefined","ensureDisplayServer","shared","fileInputPath","_createForOfIteratorHelper","s","done","value","copyTestCaseFileInput","timeLimitMs","runTimeoutSeconds","DISPLAY","display","resolveInput","input","screenshotWaitSeconds","stopDetectionThreshold","spawnGuiProgram","RUNTIME_ERROR","cleanWorkingDirectory","readOutputFiles","requiredOutputFilePaths","memoryLimitByte","evaluateGuiRunResult","context","ACCEPTED","test","exitStatus","status","timeSeconds","memoryBytes","e","f","dispose","apply","this","arguments","_x3","_resolveMainFilePath","_callee2","resolvedPath","_context2","path","join","pathExists","filePath","languageIds","Object","entries","languageIdToDefinition","filter","_ref","_slicedToArray","fileExtensions","some","ext","endsWith","map","_ref3","_context$languageDefi","_context$languageDefi2","buildCommand","buildResult","spawnSyncWithTimeout","slice","encoding","BUILD_TIME_LIMIT_EXCEEDED","_context$context$prob","_context$context$prob2","_context$context$prob3","stopReason","TIME_LIMIT_EXCEEDED","Number","POSITIVE_INFINITY","MEMORY_LIMIT_EXCEEDED","requiredOutputFilesCount","MISSING_REQUIRED_OUTPUT_FILE_ERROR","_x4","_readGuiTestCases","_callee3","_context3","readFileTestCases","_x5","_spawnGuiProgram","_callee4","wrappedCommand","child","exitCode","spawnError","screenshotSignaturesHistory","screenshots","startTimeSeconds","sampledMemoryBytes","_loop","_parseTimedStderr","normalizedStderr","_context5","toFixed","_toConsumableArray","childProcess","spawn","detached","stdio","setEncoding","Date","now","on","chunk","error","code","signal","write","end","currentScreenshots","screenshotSignatures","_context4","wait","Math","max","readProcessGroupMemoryBytes","pid","takeScreenshots","toSorted","b","data","file","unshift","min","every","files","index","d","_regeneratorValues","removeAllListeners","stopProcess","parseTimedStderr","trimEnd","xwininfo","spawnSync","_i","_extractTopLevelWindo","_step","windowIds","lines","split","_iterator","line","includes","match","exec","push","parseInt","toString","err","extractTopLevelWindowIds","windowId","screenshot","windowNameResult","windowName","trim","replaceAll","parsedMemoryBytes","_ensureDisplayServer","_callee6","_loop2","_ret2","displayNumber","_context8","xvfb","_context7","XVFB_STARTUP_WAIT_SECONDS","_dispose","_callee5","_context6","killed","kill","XVFB_SHUTDOWN_WAIT_SECONDS","_x6","_stopProcess","_callee7","_context9","killProcessGroup","PROCESS_SHUTDOWN_WAIT_SECONDS","processGroupId","result","String","isFinite","reduce","sum","_unused","_unused2","_x7","_pathExists","_callee8","_context0","fs","access","message","_x","_x2"],"mappings":"q0BA+BMA,EAAe,CAAmB,WAAlBC,EAAGC,WAA0B,QAAU,gBAAiB,WAAY,SAEpFC,EAAoBC,EAAAA,EAAEC,OAAO,CACjCC,SAAUF,EAAAA,EAAEG,MAAM,CAACH,EAAAA,EAAEI,SAAUJ,IAAEK,MAAML,EAAAA,EAAEI,YAAYE,aA+TtD,SAAAC,IAAA,OAAAA,EAAAC,EAAAA,iBAAAC,gBAAAC,EAhOM,SAAAC,EACLC,EACAC,GAAgD,IAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAA,OAAA5E,gBAAA6E,EAAA,SAAAC,GAAA,cAAAA,EAAAC,EAAAD,EAAAE,GAAA,KAAA,EAEZ,IAA9BrE,EAAOsE,EAAAA,UAAUC,QAAQC,OACrBC,IAAG,CAAAN,EAAAE,EAAA,EAAA,KAAA,CAAA,MAAQ,IAAIK,MAAM,yBAAwB,KAAA,EACJ,OAA7CzE,EAAStB,EAAkBgG,MAAM3E,EAAKC,QAAOkE,EAAAE,EAAA,EAEVO,EAAAA,+BAA+BpF,GAAW,KAAA,EAAnD,OAA1BU,EAA0BiE,EAAAU,EAAAV,EAAAE,EAAA,GACwB,OAAtB3E,EAACD,EAAQqF,eAAapF,EAAIqF,GAA6BvF,GAAW,KAAA,EAG3C,OAHnDW,EAAmBgE,EAAAU,EACnBzE,EACJD,EAAoB6E,OAAS,EAAI7E,EAAuB,CAAC,CAAE8E,GAAI,YAC3D5E,EAAqC,OAAnBV,EAAe,OAAfC,EAAGQ,EAAU,SAAE,EAAZR,EAAcqF,IAAEtF,EAAI,WAAUwE,EAAAE,EAAA,EAEtBa,wBAAsBlF,EAAKyE,IAAKvE,GAA2B,KAAA,EAApE,KAApBI,EAAoB6D,EAAAU,GACF,CAAAV,EAAAE,EAAA,EAAA,KAAA,CAC2D,OAAjFc,EAAAA,oBAAmBC,EAAAA,cAAA,CAAGC,WAAYhF,GAAuBC,IAAwB6D,EAAAmB,EAAA,GAAA,KAAA,EAAA,GAInC,OAJmCzF,EAIvDJ,EAAQ8F,cAAY,CAAApB,EAAAE,EAAA,EAAA,KAAA,CAAAf,GAAAzD,EAAAsE,EAAAE,EAAA,EAAA,MAAA,KAAA,EAAA,OAAAF,EAAAE,EAAA,EAAWmB,EAAAA,mBAAmBxF,EAAKyE,IAAKxE,EAAOnB,UAAS,KAAA,EAAAwE,GAAAa,EAAAU,EAAA,KAAA,EAA/E,GAAnBtE,EAAmB+C,GACD,CAAAa,EAAAE,EAAA,EAAA,KAAA,CAOnB,OANHc,sBAAoB,CAClBE,WAAYhF,EACZ6C,aAAcuC,EAAAA,aAAaC,uCAC3BtC,OAAQ3D,EAAQ8F,8CAAYI,OACSlG,EAAQ8F,cAAY,sBAAAI,OAC/B1F,EAAOnB,SAAQ,eAAA6G,OAAkB1F,EAAOnB,UAAa,MAC9EqF,EAAAmB,EAAA,GAAA,KAAA,EAIuE,GAAtE9E,EAAqBoF,EAAAA,6BAA6BrF,GACjC,CAAA4D,EAAAE,EAAA,GAAA,KAAA,CAKlB,OAJHc,sBAAoB,CAClBE,WAAYhF,EACZ6C,aAAcuC,EAAAA,aAAaI,aAC3BzC,OAAQ,yBACPe,EAAAmB,EAAA,GAAA,KAAA,GAIiD,OAAhD7E,EAAG2E,EAAAA,cAAAA,gBAAA,CAAA,EAAQb,QAAQ9D,KAAG,GAAA,CAAEqF,GAAI,GAAIC,YAAa,MAAG5B,EAAAE,EAAA,GAErB2B,EAAoB,CACnDvB,IAAKzE,EAAKyE,IACV3F,SAAUmB,EAAOnB,SACjBmH,uBAAwBxG,EAAQ8F,eAChC,KAAA,GAJsB,GAApB7E,EAAoByD,EAAAU,GAKpBrE,EAAmB0F,SAAQ,CAAA/B,EAAAE,EAAA,GAAA,KAAA,CAAA,OAAAF,EAAAC,EAAA,GAAAD,EAAAE,EAAA,GAErB7D,EAAmB0F,SAASlG,EAAKyE,KAAI,KAAA,GAAA,OAAAN,EAAAE,EAAA,GACR2B,EAAoB,CACrDvB,IAAKzE,EAAKyE,IACV3F,SAAyB,OAAjB6B,EAAEV,EAAOnB,UAAQ6B,EAAIwF,EAAuB5F,GACpD0F,uBAAwBxG,EAAQ8F,aAChCa,6BAA6B,IAC7B,KAAA,IALIxF,EAAoBuD,EAAAU,KAMAnE,EAAuBE,GAAqBuD,EAAAE,EAAA,GAAA,MAAA,KAAA,GAMnE,OANmEF,EAAAC,EAAA,GAAAb,GAAAY,EAAAU,EAEtEM,sBAAoB,CAClBE,WAAYhF,EACZ6C,aAAcuC,EAAAA,aAAaY,YAC3BjD,OAAQkD,EAAc/C,MACrBY,EAAAmB,EAAA,GAAA,KAAA,GAAA,GAIF5E,EAAoB,CAAAyD,EAAAE,EAAA,GAAA,KAAA,CAOpB,OANHc,sBAAoB,CAClBE,WAAYhF,EACZ6C,aAAcuC,EAAAA,aAAaC,uCAC3BtC,OAAQ3D,EAAQ8F,8CAAYI,OACSlG,EAAQ8F,cAAY,sBAAAI,OAC/B1F,EAAOnB,SAAQ,eAAA6G,OAAkB1F,EAAOnB,UAAa,MAC9EqF,EAAAmB,EAAA,GAAA,KAAA,GAAA,OAAAnB,EAAAE,EAAA,GAKmB,OALnBtE,EAKIN,EAAQ8G,gBAARxG,EAAAyG,KAAA/G,EAAkB,CACvBgF,IAAKzE,EAAKyE,IACVhE,IAAAA,EACA8E,aAAc7E,EACdR,2BAAAA,IACA,KAAA,GAAA,GAAA,OAAAJ,EAAAqE,EAAAU,GAAA,CAAAV,EAAAE,EAAA,GAAA,KAAA,CAAAb,GAAA1D,EAAAqE,EAAAE,EAAA,GAAA,MAAA,KAAA,GAAAb,GACFiD,EAAkB,CAChBhC,IAAKzE,EAAKyE,IACVhE,IAAAA,EACA8E,aAAc7E,EACdF,mBAAAA,IACA,KAAA,GAZe,KAAbK,EAAa2C,IAaF,CAAAW,EAAAE,EAAA,GAAA,KAAA,CAQZ,OAPHc,sBAAoB,CAClBE,WAAYhF,EACZ6C,aAAwC,OAA5BpC,EAAED,EAAcqC,cAAYpC,EAAI2E,EAAAA,aAAaY,YACzDK,iBAAkB7F,EAAc6F,iBAChCtD,OAAQvC,EAAcuC,OACtBD,OAAQtC,EAAcsC,OACtBP,YAAa/B,EAAc+B,cAC1BuB,EAAAmB,EAAA,GAAA,KAAA,GAAA,OAAAnB,EAAAE,EAAA,GAIqBsC,EAAAA,yBAAyB3G,EAAKyE,KAAI,KAAA,GAElB,GAFpC1D,EAAWoD,EAAAU,EAEb5D,EAAoBZ,EAAkB8D,EAAAC,EAAA,IAGxB3E,EAAQmH,WAAU,CAAAzC,EAAAE,EAAA,GAAA,KAAA,CAAAZ,QAAGoD,EAAS1C,EAAAE,EAAA,GAAA,MAAA,KAAA,GAAA,OAAAF,EAAAE,EAAA,GAASyC,IAAqB,KAAA,GAAArD,GAAAU,EAAAU,EAAA,KAAA,GAA5E7D,EAAayC,GACPrC,EAA6F,OAA1ED,EAAIhB,EAAgE4G,aAAM,EAAvE5F,EAAyE6F,cAAa3F,EAAA4F,EAAAA,0BAC3F7G,GAAS+D,EAAAC,EAAA,GAAA/C,EAAA6F,IAAA,KAAA,GAAA,IAAA5F,EAAAD,EAAAgD,KAAA8C,KAAA,CAAAhD,EAAAE,EAAA,GAAA,KAAA,CACE,GADvBnC,GAAQZ,EAAA8F,MACjBnG,EAAoBiB,GAAS+C,IACzB7D,EAAmB,CAAA+C,EAAAE,EAAA,GAAA,KAAA,CAAA,OAAAF,EAAAE,EAAA,GAAQgD,wBAAsBjG,EAAqBpB,EAAKyE,KAAI,KAAA,GAAA,IAC/EvC,GAAS8E,cAAa,CAAA7C,EAAAE,EAAA,GAAA,KAAA,CAAA,OAAAF,EAAAE,EAAA,GAAQgD,EAAAA,sBAAsBnF,GAAS8E,cAAehH,EAAKyE,KAAI,KAAA,GAOV,OALzEtC,GAC8C,iBAA3CjC,EAA2BoH,YAC9BpH,EAA2BoH,YAAc,IACf,OADmB/F,EAC5C9B,EAAQ8H,mBAAiBhG,EA/NA,EAiO1Ba,GAASpB,EAAaoE,gBAAAA,EAAAA,iBAAQ3E,GAAG,GAAA,CAAE+G,QAASxG,EAAcyG,UAAYhH,EAAG0D,EAAAE,EAAA,GACtC,OADsC3C,GAC1DjC,EAAQiI,qBAARhG,GAAA8E,KAAA/G,EAAuB,CAAEyC,SAAAA,GAAUuC,IAAKzE,EAAKyE,IAAKhE,IAAK2B,KAAS,KAAA,GAAA,GAAA,OAAAX,GAAA0C,EAAAU,GAAA,CAAAV,EAAAE,EAAA,GAAA,KAAA,CAAAX,GAAAjC,GAAA0C,EAAAE,EAAA,GAAA,MAAA,KAAA,GAAAX,GAAKxB,GAASyF,MAAK,KAAA,GAAA,GAAA,OAAAnG,EAAAkC,IAAA,CAAAS,EAAAE,EAAA,GAAA,KAAA,CAAAV,GAAAnC,EAAA2C,EAAAE,EAAA,GAAA,MAAA,KAAA,GAAAV,GAAI,GAAE,KAAA,GACzF,OAArBzC,EADMmB,GAAKsB,GACUQ,EAAAE,EAAA,GAEG,OAFHzC,GAEZnC,EAAQ6C,gBAARV,GAAA4E,KAAA/G,EAAkB,CAAEyC,SAAAA,GAAUuC,IAAKzE,EAAKyE,IAAKhE,IAAK2B,GAAQmD,aAAc7E,IAAuB,KAAA,GAAA,GAAA,OAAAiB,GAAAwC,EAAAU,GAAA,CAAAV,EAAAE,EAAA,GAAA,KAAA,CAAAT,GAAAjC,GAAAwC,EAAAE,EAAA,GAAA,MAAA,KAAA,GAAAT,GACtGpD,EAAmB8B,QAAQ5B,GAAqB,KAAA,GAEhB,GAJ5B4B,GAAOsB,GAITrB,QAA8B,EAAA4B,EAAAC,EAAA,IAEpB3E,EAAQmH,WAAU,CAAAzC,EAAAE,EAAA,GAAA,KAAA,CAAA,OAAAF,EAAAE,EAAA,GACpB5E,EAAQmH,WAAW,CACvB1E,SAAAA,GACAI,QAAAA,GACAD,MAAAA,GACAoC,IAAKzE,EAAKyE,IACVhE,IAAK2B,GACLD,iBAAAA,GACAyF,sBAAoD,OAA/BpF,GAAE/C,EAAQmI,uBAAqBpF,GAjPlC,GAkPlBqF,uBAAsD,OAAhCpF,GAAEhD,EAAQoI,wBAAsBpF,GA9OnC,IA+OnB,KAAA,GAAAoB,GAAAM,EAAAU,EAAAV,EAAAE,EAAA,GAAA,MAAA,KAAA,GAAA,OAAAF,EAAAE,EAAA,GACIyD,EAAgB,CACpBxF,QAAAA,GACAD,MAAAA,GACAoC,IAAKzE,EAAKyE,IACVhE,IAAK2B,GACLD,iBAAAA,GACAyF,sBAAoD,OAA/BlF,GAAEjD,EAAQmI,uBAAqBlF,GA1PlC,GA2PlBmF,uBAAsD,OAAhClF,GAAElD,EAAQoI,wBAAsBlF,GAvPnC,IAwPnB,KAAA,GAAAkB,GAAAM,EAAAU,EAAA,KAAA,GAnBNtC,GAASsB,GAAAM,EAAAE,EAAA,GAAA,MAAA,KAAA,GA0BN,OA1BMF,EAAAC,EAAA,GAAAN,GAAAK,EAAAU,EAqBTM,sBAAoB,CAClBE,WAAYnD,GAAS+C,GACrB/B,aAAcuC,EAAAA,aAAasC,cAC3B1F,MAAAA,GACAe,OAAQkD,EAAcxC,MACrBK,EAAAE,EAAA,GACG2D,wBAAsBhI,EAAKyE,IAAK1D,GAAY,KAAA,GAAA,OAAAoD,EAAAmB,EAAA,GAAA,KAAA,GAAA,OAAAnB,EAAAE,EAAA,GAI1B4D,EAAAA,gBAAgBjI,EAAKyE,IAAuD,OAApD5C,GAAE3B,EAA2BgI,yBAAuBrG,GAAI,IAAG,KAAA,GAS5E,GAT3Be,GAAWuB,EAAAU,EACXhC,GAAgC,CACpCV,iBAAAA,GACAjC,2BAA4B,CAC1BiI,gBAAiBjI,EAA2BiI,gBAC5CD,wBAAyBhI,EAA2BgI,0BAGlDpF,GAAkBsF,EAAqB,CAAE7F,UAAAA,GAAWK,YAAAA,GAAayF,QAASxF,KAC5EE,GAAcD,GACdA,GAAgBI,eAAiBuC,EAAAA,aAAa6C,SAAQ,CAAAnE,EAAAE,EAAA,GAAA,KAAA,CAAA,OAAAF,EAAAC,EAAA,GAAAD,EAAAE,EAAA,GAEpB5E,EAAQ8I,KAAK,CAC7CrG,SAAAA,GACAK,UAAAA,GACAK,YAAAA,GACAyF,QAASxF,KACT,KAAA,GALII,GAAmBkB,EAAAU,EAMzB9B,GAAc,CACZG,aAA8C,OAAlCF,GAAEC,GAAoBC,cAAYF,GAAIF,GAAgBI,aAClEwD,iBAAkBzD,GAAoByD,iBACtCtD,OAAQH,GAAoBG,OAC5BD,OAAQF,GAAoBE,OAC5BP,YAAaK,GAAoBL,aACjCuB,EAAAE,EAAA,GAAA,MAAA,KAAA,GAAAF,EAAAC,EAAA,GAAAL,GAAAI,EAAAU,EAEF9B,GAAc,CACZG,aAAcuC,EAAAA,aAAasC,cAC3B3E,OAAQkD,EAAcvC,KACtB,KAAA,GAkBH,OAdGb,GAAuC,OAA3BpB,GAAGiB,GAAYG,cAAYpB,GAAI2D,EAAAA,aAAa6C,SACxDnF,GAA2B,OAArBpB,GAAGgB,GAAYI,QAAMpB,GAAIQ,GAAUY,OACzCC,GAA2B,OAArBpB,GAAGe,GAAYK,QAAMpB,GAAIO,GAAUa,OAC/C+B,sBAAoB,CAClBE,WAAYnD,GAAS+C,GACrB/B,aAAAA,GACAsF,WAAYjG,GAAUkG,OACtBpG,MAAOE,GAAUF,YAASwE,EAC1B1D,OAAQA,SAAU0D,EAClBzD,OAAQA,SAAUyD,EAClB6B,YAAanG,GAAUmG,YACvBC,YAAapG,GAAUoG,YACvBjC,iBAAkB3D,GAAY2D,iBAC9B9D,YAAoC,OAAzBX,GAAEc,GAAYH,aAAWX,GAAKW,GAAYoC,OAAS,EAAIpC,QAAciE,IAC/E1C,EAAAE,EAAA,GAEG2D,wBAAsBhI,EAAKyE,IAAK1D,GAAY,KAAA,GAAA,GAC9CmC,KAAiBuC,eAAa6C,SAAQ,CAAAnE,EAAAE,EAAA,GAAA,KAAA,CAAA,OAAAF,EAAAmB,EAAA,EAAA,IAAA,KAAA,GAAAnB,EAAAE,EAAA,GAAA,MAAA,KAAA,GAAAF,EAAAE,EAAA,GAAA,MAAA,KAAA,GAAAF,EAAAC,EAAA,GAAAJ,GAAAG,EAAAU,EAAAxD,EAAAuH,EAAA5E,IAAA,KAAA,GAAA,OAAAG,EAAAC,EAAA,GAAA/C,EAAAwH,IAAA1E,EAAA0E,EAAA,IAAA,KAAA,GAAA1E,EAAAE,EAAA,GAAA,MAAA,KAAA,GAQzC,OARyCF,EAAAC,EAAA,GAAAH,GAAAE,EAAAU,EAG5CM,sBAAoB,CAClBE,WAAYpE,EACZiC,aAAcuC,EAAAA,aAAasC,cAC3B1F,MAAOnB,EACPkC,OAAQkD,EAAcrC,MACrBE,EAAAE,EAAA,GACG2D,wBAAsBhI,EAAKyE,IAAK1D,GAAY,KAAA,GAAA,OAAAoD,EAAAC,EAAA,GAAAD,EAAAE,EAAA,GAE/B,OAF+BhB,GAE5CrC,QAAa,EAAbqC,GAAeyF,UAAS,KAAA,GAAA,OAAA3E,EAAA0E,EAAA,IAAA,KAAA,GAAA,OAAA1E,EAAAmB,EAAA,GAAA,EAAA/F,EAAA,KAAA,CAAA,CAAA,GAAA,IAAA,CAAA,GAAA,IAAA,CAAA,GAAA,GAAA,GAAA,IAAA,CAAA,GAAA,GAAA,GAAA,IAAA,CAAA,GAAA,KAAA,KAEjCwJ,MAAAC,KAAAC,UAAA,CAAA,SAEcjD,EAAmBkD,GAAA,OAAAC,EAAAJ,MAAAC,KAAAC,UAAA,CAAA,SAAAE,IAajC,OAbiCA,EAAA/J,EAAAA,iBAAAC,EAAAA,cAAAC,EAAlC,SAAA8J,EAAmCf,GAKlC,IAAAgB,EAAA,OAAAhK,gBAAA6E,EAAA,SAAAoF,GAAA,cAAAA,EAAAjF,GAAA,KAAA,EAAA,IACKgE,EAAQpC,uBAAsB,CAAAqD,EAAAjF,EAAA,EAAA,KAAA,CAC2C,OAArEgF,EAAeE,EAAKC,KAAKnB,EAAQ5D,IAAK4D,EAAQpC,wBAAuBqD,EAAAjF,EAAA,EACjEoF,EAAWJ,GAAa,KAAA,EAAA,IAAAC,EAAAzE,EAAA,CAAAyE,EAAAjF,EAAA,EAAA,KAAA,CAAA,OAAAiF,EAAAhE,EAAA,EAAS+C,EAAQpC,wBAAsB,KAAA,EAAA,GACpEoC,EAAQjC,4BAA2B,CAAAkD,EAAAjF,EAAA,EAAA,KAAA,CAAA,OAAAiF,EAAAhE,EAAA,OAASuB,GAAS,KAAA,EAAA,OAAAyC,EAAAjF,EAAA,EAG/CmB,EAAAA,mBAAmB6C,EAAQ5D,IAAK4D,EAAQvJ,UAAS,KAAA,EAAA,OAAAwK,EAAAhE,EAAA,EAAAgE,EAAAzE,GAAA,EAAAuE,EAAA,KAC/DL,MAAAC,KAAAC,UAAA,CAED,SAAS9C,EAAuBuD,GAC9B,IAAMC,EAAcC,OAAOC,QAAQC,EAAAA,wBAChCC,OAAO,SAAAC,GAAc,OAAdC,EAAAA,cAAAD,EAAA,GAAc,GAAiBE,eAAeC,KAAK,SAACC,GAAG,OAAKV,EAASW,SAASD,EAAI,EAAC,GAC1FE,IAAI,SAAAC,GAAY,OAAZN,EAAAA,cAAAM,EAAA,GAAY,EAAgB,GACnC,OAAOZ,EAAY3E,OAAS,EAAI2E,OAAc9C,CAChD,CAEA,SAASJ,EAAkB4B,GAKiB,IAAAmC,EAAAC,EACpCC,EAAsD,OAA1CF,GAAGC,EAAApC,EAAQ7H,oBAAmBkK,mBAAY,EAAvCF,EAAAhE,KAAAiE,EAA0CpC,EAAQ9C,cACvE,GAAKmF,EAAL,CAEA,IAAMC,EAAcC,EAAAA,qBAClBF,EAAa,GACbA,EAAaG,MAAM,GACnB,CAAEpG,IAAK4D,EAAQ5D,IAAKqG,SAAU,OAAQrK,IAAK4H,EAAQ5H,KA7WzB,IAiX5B,OAAIkK,EAAYjC,YAjXY,GAkXnB,CACLxF,aAAcuC,EAAAA,aAAasF,0BAC3B3H,OAAQuH,EAAYvH,aAAUyD,GAIP,IAAvB8D,EAAYlC,OACP,CACLvF,aAAcuC,EAAAA,aAAaY,YAC3BjD,OAAQuH,EAAYvH,QAAUuH,EAAYxH,aAAU0D,QAHxD,CAhBmC,CAwBrC,CAEA,SAASuB,EAAqBC,GAIE,IAAA2C,EAAAC,EAAAC,EAC9B,GAAqC,YAAjC7C,EAAQ9F,UAAU4I,WACpB,MAAO,CACLjI,aAAcuC,EAAAA,aAAa2F,oBAC3BhI,OAAQiF,EAAQ9F,UAAUa,QAI9B,GAAiC,IAA7BiF,EAAQ9F,UAAUkG,OACpB,MAAO,CACLvF,aAAcuC,EAAAA,aAAasC,cAC3B3E,OAAQiF,EAAQ9F,UAAUa,QAI9B,GACEiF,EAAQ9F,UAAUoG,aACyC,OAD9BqC,EAC5B3C,EAAQA,QAAQnI,2BAA2BiI,iBAAe6C,EAAIK,OAAOC,mBAEtE,MAAO,CACLpI,aAAcuC,EAAAA,aAAa8F,sBAC3BnI,OAAQiF,EAAQ9F,UAAUa,QAI9B,IAAMoI,EAAqG,OAA7EP,SAAAC,EAAG7C,EAAQA,QAAQnI,2BAA2BgI,gCAA3CgD,EAAoElG,QAAMiG,EAAI,EAC/G,OAAI5C,EAAQzF,YAAYoC,OAASwG,EACxB,CACLtI,aAAcuC,EAAAA,aAAagG,oCAIxB,CAAEvI,aAAcuC,EAAAA,aAAa6C,SACtC,CAAC,SAEcvD,EAAgB2G,GAAA,OAAAC,EAAA5C,MAAAC,KAAAC,UAAA,CAAA,SAAA0C,IAE9B,OAF8BA,EAAAvM,EAAAA,iBAAAC,EAAAA,cAAAC,EAA/B,SAAAsM,EAAmEpM,GAAkB,OAAAH,gBAAA6E,EAAA,SAAA2H,GAAA,cAAAA,EAAAxH,GAAA,KAAA,EAAA,OAAAwH,EAAAxH,EAAA,EACrEyH,EAAAA,cAAkBvC,EAAKC,KAAKhK,EAAY,eAAc,KAAA,EAAA,OAAAqM,EAAAvG,EAAA,EAAAuG,EAAAhH,GAAA,EAAA+G,EAAA,KACrE7C,MAAAC,KAAAC,UAAA,CAAA,SAEcnB,EAAeiE,GAAA,OAAAC,EAAAjD,MAAAC,KAAAC,UAAA,CAAA,SAAA+C,IAgH7B,OAhH6BA,EAAA5M,EAAAA,iBAAAC,EAAAA,cAAAC,EAA9B,SAAA2M,EAA+B5D,GAQ9B,IAAA6D,EAAAC,EAAAhJ,EAAAC,EAAAgJ,EAAAC,EAAAlB,EAAAmB,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAhE,EAAAiE,EAAAlE,EAAA,OAAArJ,gBAAA6E,EAAA,SAAA2I,GAAA,cAAAA,EAAAxI,GAAA,KAAA,EACO6H,EAAc,CAAI,UAAW7D,EAAQlG,iBAAiB2K,QAAQ,IAAEnH,OAAKnH,EAAYuO,EAAAA,kBAAK1E,EAAQ/F,WAC9F6J,EAAQa,EAAaC,MAAMf,EAAe,GAAIA,EAAerB,MAAM,GAAI,CAC3EpG,IAAK4D,EAAQ5D,IACbhE,IAAK4H,EAAQ5H,IACbyM,SAA+B,UAArB3I,QAAQ7F,SAClByO,MAAO,CAAC,OAAQ,OAAQ,WAGpBhK,OAAOiK,YAAY,QACzBjB,EAAM/I,OAAOgK,YAAY,QAErBjK,EAAS,GACTC,EAAS,GAGT+H,EAAgD,eAC9CmB,EAA0C,GAC5CC,EAAmC,GACjCC,EAAmBa,KAAKC,MAAQ,IAClCb,EAAqB,EAEzBN,EAAMhJ,OAAOoK,GAAG,OAAQ,SAACC,GACvBrK,GAAUqK,CACZ,GACArB,EAAM/I,OAAOmK,GAAG,OAAQ,SAACC,GACvBpK,GAAUoK,CACZ,GACArB,EAAMoB,GAAG,QAAS,SAACE,GACjBpB,EAAaoB,EACbrB,EAAW,CACb,GACAD,EAAMoB,GAAG,QAAS,SAACG,EAAMC,GACvB,OAAa,MAATD,GACFvC,EAAa,eACbiB,EAAW,IAGTuB,GACFvB,EAAW,OACXhJ,EAASA,EAAM,GAAAuC,OACRvC,EAAM,oCAAAuC,OAAmCgI,GAAM,iCAAAhI,OACjBgI,UAGvCvB,EAAe,MAAJsB,EAAAA,EAAQ,EACrB,GAEIrF,EAAQhG,OAAO8J,EAAM9J,MAAMuL,MAAMvF,EAAQhG,OAC7C8J,EAAM9J,MAAMwL,MAAMnB,EAAArN,EAAAA,cAAAC,WAAAoN,IAAA,IAAAoB,EAAAC,EAAA,OAAA1O,gBAAA6E,EAAA,SAAA8J,GAAA,cAAAA,EAAA3J,GAAA,KAAA,EAAA,OAAA2J,EAAA3J,EAAA,EAGV4J,aAAqC,IAAhC5F,EAAQT,uBAA6B,KAAA,EAGmC,GAFnF6E,EAAqByB,KAAKC,IAAI1B,EAAoB2B,EAA4BjC,EAAMkC,MAC9EP,EAAqBQ,EAAgBjG,EAAQ5H,IAAI+G,YACvD+E,EAAcuB,EAAmBS,SAAS,SAACjJ,EAAGkJ,GAAC,OAAKlJ,EAAEmJ,KAAKzJ,OAASwJ,EAAEC,KAAKzJ,MAAM,IAEjEA,OAAS,GAAC,CAAAgJ,EAAA3J,EAAA,EAAA,KAAA,CAG0F,GAF5G0J,EAAuBxB,EAAYjC,IAAI,SAACoE,GAAI,OAAKA,EAAKD,IAAI,GAAEF,WAClEjC,EAA4BqC,QAAQZ,GACpCzB,EAA4BtH,OAASkJ,KAAKU,IAAItC,EAA4BtH,OAAQqD,EAAQR,wBAExFyE,EAA4BtH,SAAWqD,EAAQR,yBAC/CyE,EAA4BuC,MAC1B,SAACC,GAAK,OACJA,EAAM9J,SAAW+I,EAAqB/I,QACtC8J,EAAMD,MAAM,SAACH,EAAMK,GAAK,OAAKL,IAASX,EAAqBgB,EAAM,EAAC,GACrE,CAAAf,EAAA3J,EAAA,EAAA,KAAA,CAGY,OADb8G,EAAa,oBACbiB,EAAW,EAAE4B,EAAA1I,EAAA,EAAA,GAAA,KAAA,EAAA,KAKb+H,KAAKC,MAAQ,IAAOd,EAAmBnE,EAAQlG,kBAAgB,CAAA6L,EAAA3J,EAAA,EAAA,KAAA,CAEpD,OADb8G,EAAa,UACbiB,EAAW,EAAE4B,EAAA1I,EAAA,EAAA,GAAA,KAAA,EAAA,OAAA0I,EAAA1I,EAAA,GAAA,EAAAoH,EAAA,GAAA,KAAA,EAAA,QA1BG7F,IAAbuF,EAAsB,CAAAS,EAAAxI,EAAA,EAAA,KAAA,CAAA,OAAAwI,EAAAmC,EAAAC,EAAAA,kBAAAvC,KAAA,GAAA,KAAA,EAAA,GAAA,IAAAG,EAAAhI,EAAA,CAAAgI,EAAAxI,EAAA,EAAA,KAAA,CAAA,OAAAwI,EAAAvH,EAAA,EAAA,GAAA,KAAA,EAAAuH,EAAAxI,EAAA,EAAA,MAAA,KAAA,EAkC5B,MAHkB,iBAAf8G,GAAoD,OAAnBgB,EAAMC,WACzCD,EAAM+C,mBAAmB,SACzB/C,EAAM+C,mBAAmB,UAC1BrC,EAAAxI,EAAA,EACK8K,EAAYhD,GAAM,KAAA,EAAA,IACpBE,EAAU,CAAAQ,EAAAxI,EAAA,EAAA,KAAA,CAAA,MAAQgI,EAAU,KAAA,EAInB,OAJmBM,EAK5ByC,EAAiBhM,EAAQoJ,EAAkBC,GAH7C9D,EAAWgE,EAAXhE,YACQiE,EAAgBD,EAAxBvJ,OACAsF,EAAWiE,EAAXjE,YAAWmE,EAAAvH,EAAA,EAGN,CACLjD,MAAOgG,EAAQhG,MACfc,OAAQA,EAAOkM,UACfjM,OAAQwJ,EACRnE,OAAQ2D,EACR1D,YAAAA,EACAC,YAAAA,EACA4D,YAAAA,EACApB,WAAAA,IACD,EAAAc,EAAA,KACFlD,MAAAC,KAAAC,UAAA,CAED,SAASqF,EAAgB7G,GACvB,IAAMhH,EAAMgH,EAAOrC,gBAAAA,EAAAA,cAAA,CAAA,EAAQb,QAAQ9D,KAAG,GAAA,CAAE+G,QAASC,IAAYlD,QAAQ9D,IAC/D6O,EAAWtC,EAAauC,UAAU,WAAY,CAAC,QAAS,SAAU,CAAEzE,SAAU,OAAQrK,IAAAA,IAC5F,GAAI6O,EAAS7B,MAAO,MAAM6B,EAAS7B,MACnC,GAAwB,IAApB6B,EAAS7G,SAAiB6G,EAASnM,OAAQ,MAAO,GAGtD,IADA,IAAMoJ,EAAmC,GACzCiD,EAAA,EAAAC,EAmBF,SAAkCtM,GAChC,IAEwBuM,EAFlBC,EAAsB,GACtBC,EAAQzM,EAAO0M,MAAM,MAAMC,EAAA7I,EAAAA,0BACd2I,GAAK,IAAxB,IAAAE,EAAA5I,MAAAwI,EAAAI,EAAAzL,KAAA8C,MAA0B,CAAA,IAAf4I,EAAIL,EAAAtI,MACb,KAAI2I,EAAKC,SAAS,oBAAsBD,EAAKC,SAAS,sBAAwBD,EAAKC,SAAS,OAA5F,CAEA,IAAMC,EAAQ,sBAAsBC,KAAKH,GAC/B,MAALE,GAAAA,EAAQ,IACbN,EAAUQ,KAAK9E,OAAO+E,SAASH,EAAM,GAAI,IAAII,WAJsD,CAKrG,CAAC,CAAA,MAAAC,GAAAR,EAAAlH,EAAA0H,EAAA,CAAA,QAAAR,EAAAjH,GAAA,CACD,OAAO8G,CACT,CA9ByBY,CAAyBjB,EAASnM,QAAOqM,EAAAC,EAAAzK,OAAAwK,IAAE,CAA7D,IAAMgB,EAAQf,EAAAD,GACXiB,EAAazD,EAAauC,UAAU,OAAQ,CAAC,KAAMiB,GAAW,CAAE/P,IAAAA,IACtE,GAAIgQ,EAAWhD,MAAO,MAAMgD,EAAWhD,MACvC,GAA0B,IAAtBgD,EAAWhI,QAA6C,IAA7BgI,EAAWtN,OAAO6B,OAAjD,CAEA,IAAM0L,EAAmB1D,EAAauC,UAAU,UAAW,CAAC,gBAAiBiB,GAAW,CAAE1F,SAAU,OAAQrK,IAAAA,IAC5G,GAAIiQ,EAAiBjD,MAAO,MAAMiD,EAAiBjD,MACnD,IAAMkD,EAAaD,EAAiBvN,OAAOyN,OAAOC,WAAW,SAAU,KAEvEtE,EAAY4D,KAAK,CACf5G,KAAI,GAAA5D,OAAKgL,GAAc,SAAQ,KAAAhL,OAAI6K,EAAQ,QAC3C/B,KAAMgC,EAAWtN,OAAOkN,SAAS,UACjCvF,SAAU,UATmD,CAWjE,CAEA,OAAOyB,CACT,CAeA,SAAS6C,EACPhM,EACAoJ,EACAC,GAEA,IAAMwD,EAAQ,+BAA+BC,KAAK9M,GAC5CwJ,EAAmBqD,EAAQ7M,EAAOyH,MAAM,EAAGoF,EAAMlB,OAAOM,UAAYjM,EAAOiM,UAC3EyB,EAAyC,KAArBzF,OAAY,MAAL4E,SAAAA,EAAQ,KAAc,EACvD,MAAO,CACL7M,OAAQwJ,EACRlE,YAAa2C,OAAY,MAAL4E,OAAK,EAALA,EAAQ,KAAO5C,KAAKC,MAAQ,IAAOd,EACvD7D,YAAauF,KAAKC,IAAI2C,EAAmBrE,GAE7C,CAAC,SAEc3F,IAAmB,OAAAiK,EAAAhI,MAAAC,KAAAC,UAAA,CAAA,SAAA8H,IAgCjC,OAhCiCA,EAAA3R,EAAAA,iBAAAC,EAAAA,cAAAC,EAAlC,SAAA0R,IAAA,IAAAC,EAAAC,EAAAC,EAAA,OAAA9R,gBAAA6E,EAAA,SAAAkN,GAAA,cAAAA,EAAA/M,GAAA,KAAA,EAAA,GAC2B,UAArBE,QAAQ7F,SAAoB,CAAA0S,EAAA/M,EAAA,EAAA,KAAA,CAAA,MACxB,IAAIK,MAAM,sDAAqD,KAAA,EAAAuM,EAAA5R,EAAAA,cAAAC,WAAA2R,IAAA,IAAAxJ,EAAA4E,EAAAgF,EAAA,OAAAhS,gBAAA6E,EAAA,SAAAoN,GAAA,cAAAA,EAAAjN,GAAA,KAAA,EAWlE,OAPGoD,EAAO,IAAA9B,OAAOwL,IAEdE,EAAOrE,EAAaC,MAAM,OAAQ,CAACxF,EAAS,UAAW,IAAK,eAAgB,OAAQ,CACxF0F,MAAO,YAEJI,GAAG,QAAS,SAACE,GAChBpB,EAAaoB,CACf,GAAG6D,EAAAjN,EAAA,EAEG4J,EAAAA,WAAKsD,KAAiC,KAAA,EAAA,IACxClF,EAAU,CAAAiF,EAAAjN,EAAA,EAAA,KAAA,CAAA,MAAQgI,EAAU,KAAA,EAAA,GACV,OAAlBgF,EAAKjF,SAAiB,CAAAkF,EAAAjN,EAAA,EAAA,KAAA,CAAA,OAAAiN,EAAAhM,EAAA,EAAA,GAAA,KAAA,EAAA,OAAAgM,EAAAhM,EAAA,EAAA,CAAAT,EAEnB,CACL4C,QAAAA,EACAqB,QAAO,WAAA,IAAA0I,EAAApS,EAAAA,iBAAAC,EAAAA,cAAAC,EAAE,SAAAmS,IAAA,OAAApS,gBAAA6E,EAAA,SAAAwN,GAAA,cAAAA,EAAArN,GAAA,KAAA,EAAA,GACFgN,EAAKM,OAAM,CAAAD,EAAArN,EAAA,EAAA,KAAA,CACO,OAArBgN,EAAKO,KAAK,WAAWF,EAAArN,EAAA,EACf4J,EAAAA,WAAK4D,KAAkC,KAAA,EACvB,OAAlBR,EAAKjF,UAAmBiF,EAAKO,KAAK,WAAW,KAAA,EAAA,OAAAF,EAAApM,EAAA,GAAA,EAAAmM,EAAA,IAJ9C,OAMN,WANM,OAAAD,EAAAzI,MAAAC,KAAAC,UAAA,CAAA,CAAA,MAOR,EAAAgI,EAAA,GAvBME,EAAgB,GAAE,KAAA,EAAA,KAAEA,EAAgB,KAAG,CAAAC,EAAA/M,EAAA,EAAA,KAAA,CAAA,OAAA+M,EAAApC,EAAAC,EAAAA,kBAAAgC,KAAA,GAAA,KAAA,EAAA,GAAA,KAAAC,EAAAE,EAAAvM,GAAA,CAAAuM,EAAA/M,EAAA,EAAA,KAAA,CAAA,OAAA+M,EAAA9L,EAAA,EAAA,GAAA,KAAA,EAAA,IAAA4L,EAAA,CAAAE,EAAA/M,EAAA,EAAA,KAAA,CAAA,OAAA+M,EAAA9L,EAAA,EAAA4L,EAAArM,GAAA,KAAA,EAAEsM,IAAeC,EAAA/M,EAAA,EAAA,MAAA,KAAA,EAAA,MA0B3D,IAAIK,MAAM,8BAA6B,KAAA,EAAA,OAAA0M,EAAA9L,EAAA,GAAA,EAAA0L,EAAA,IAC9CD,EAAAhI,MAAAC,KAAAC,UAAA,CAAA,SAEckG,EAAW2C,GAAA,OAAAC,EAAAhJ,MAAAC,KAAAC,UAAA,CAAA,SAAA8I,IAKzB,OALyBA,EAAA3S,EAAAA,iBAAAC,EAAAA,cAAAC,EAA1B,SAAA0S,EAA2B7F,GAAgC,OAAA9M,gBAAA6E,EAAA,SAAA+N,GAAA,cAAAA,EAAA5N,GAAA,KAAA,EAAA,GACpD8H,EAAMkC,IAAG,CAAA4D,EAAA5N,EAAA,EAAA,KAAA,CAAA,OAAA4N,EAAA3M,EAAA,GAAA,KAAA,EACyB,OAAvC4M,EAAiB/F,EAAMkC,IAAK,WAAW4D,EAAA5N,EAAA,EACjC4J,EAAAA,WAAKkE,KAAqC,KAAA,EACzB,OAAnBhG,EAAMC,UAAmB8F,EAAiB/F,EAAMkC,IAAK,WAAW,KAAA,EAAA,OAAA4D,EAAA3M,EAAA,GAAA,EAAA0M,EAAA,KACrEjJ,MAAAC,KAAAC,UAAA,CAED,SAASmF,EAA4BgE,GACnC,IAAKA,GAAuC,UAArB7N,QAAQ7F,SAAsB,OAAO,EAE5D,IAAM2T,EAASrF,EAAauC,UAAU,KAAM,CAAC,KAAM,OAAQ,eAAgB,WAAY+C,OAAOF,IAAkB,CAC9GtH,SAAU,SAEZ,OAAIuH,EAAO5E,OAA2B,IAAlB4E,EAAO5J,SAAiB4J,EAAOlP,OAAe,EAE3DkP,EAAOlP,OACX0M,MAAM,MACNvF,IAAI,SAACyF,GAAI,OAAK1E,OAAO0E,EAAKa,OAAO,GACjC7G,OAAO,SAAC3C,GAAK,OAAKiE,OAAOkH,SAASnL,IAAUA,EAAQ,CAAC,GACrDoL,OAAO,SAACC,EAAKrL,GAAK,OAAKqL,EAAc,KAARrL,CAAY,EAAE,EAChD,CAEA,SAAS8K,EAAiBE,EAAwBzE,GAChD,IACE,GAAyB,UAArBpJ,QAAQ7F,SAEV,YADA6F,QAAQqN,MAAMQ,EAAgBzE,EAGlC,CAAE,MAAA+E,GACA,CAGF,IACEnO,QAAQqN,KAAKQ,EAAgBzE,EAC/B,CAAE,MAAAgF,GACA,CAEJ,CAAC,SAEclJ,EAAUmJ,GAAA,OAAAC,EAAA9J,MAAAC,KAAAC,UAAA,CAAA,SAAA4J,IAOxB,OAPwBA,EAAAzT,EAAAA,iBAAAC,EAAAA,cAAAC,EAAzB,SAAAwT,EAA0BpJ,GAAgB,OAAArK,gBAAA6E,EAAA,SAAA6O,GAAA,cAAAA,EAAA3O,EAAA2O,EAAA1O,GAAA,KAAA,EAAA,OAAA0O,EAAA3O,EAAA,EAAA2O,EAAA1O,EAAA,EAEhC2O,EAAGC,OAAOvJ,GAAS,KAAA,EAAA,OAAAqJ,EAAAzN,EAAA,GAClB,GAAI,KAAA,EAAA,OAAAyN,EAAA3O,EAAA,EAAA2O,EAAAlO,EAAAkO,EAAAzN,EAAA,GAEJ,GAAK,EAAAwN,EAAA,KAAA,CAAA,CAAA,EAAA,IAAA,KAEf/J,MAAAC,KAAAC,UAAA,CAED,SAAS3C,EAAemH,GACtB,OAAOA,aAAiB/I,MAAQ+I,EAAMyF,QAAUZ,OAAO7E,EACzD,+BAhkBA,SAA2C0F,EAAAC,GAAA,OAAAjU,EAAA4J,MAAAC,KAAAC,UAAA"}
1
+ {"version":3,"file":"guiCommand.cjs","names":["os","z","parseArgs","readProblemMarkdownFrontMatter","judgeByStaticAnalysis","findEntryPointFile","DecisionCode","findLanguageDefinitionByPath","snapshotWorkingDirectory","copyTestCaseFileInput","cleanWorkingDirectory","readOutputFiles","path","languageIdToDefinition","spawnSyncWithTimeout","readFileTestCases","childProcess","fs"],"sources":["../../src/presets/guiCommand.ts"],"sourcesContent":["import childProcess from 'node:child_process';\nimport fs from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { setTimeout as wait } from 'node:timers/promises';\n\nimport { z } from 'zod';\n\nimport { cleanWorkingDirectory, snapshotWorkingDirectory } from '../helpers/cleanWorkingDirectory.js';\nimport { copyTestCaseFileInput } from '../helpers/copyTestCaseFileInput.js';\nimport { findEntryPointFile } from '../helpers/findEntryPointFile.js';\nimport { findLanguageDefinitionByPath } from '../helpers/findLanguageDefinitionByPath.js';\nimport { judgeByStaticAnalysis } from '../helpers/judgeByStaticAnalysis.js';\nimport { parseArgs } from '../helpers/parseArgs.js';\nimport { printTestCaseResult } from '../helpers/printTestCaseResult.js';\nimport { readOutputFiles } from '../helpers/readOutputFiles.js';\nimport { readProblemMarkdownFrontMatter } from '../helpers/readProblemMarkdownFrontMatter.js';\nimport { readTestCases as readFileTestCases } from '../helpers/readTestCases.js';\nimport { spawnSyncWithTimeout } from '../helpers/spawnSyncWithTimeout.js';\nimport { DecisionCode } from '../types/decisionCode.js';\nimport { languageIdToDefinition } from '../types/language.js';\nimport type { ProblemMarkdownFrontMatter } from '../types/problem.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\nconst BUILD_TIMEOUT_SECONDS = 10;\nconst JUDGE_DEFAULT_TIMEOUT_SECONDS = 5;\nconst SCREENSHOT_WAIT_SECONDS = 0.3;\nconst XVFB_STARTUP_WAIT_SECONDS = 0.3;\nconst XVFB_SHUTDOWN_WAIT_SECONDS = 0.1;\nconst PROCESS_SHUTDOWN_WAIT_SECONDS = 0.2;\nconst STOP_DETECTION_THRESHOLD = 5;\nconst TIME_COMMAND = [os.platform() === 'darwin' ? 'gtime' : '/usr/bin/time', '--format', '%e %M'] as const;\n\nconst judgeParamsSchema = z.object({\n language: z.union([z.string(), z.array(z.string())]).optional(),\n});\n\ninterface BaseGuiTestCase {\n id: string;\n input?: string;\n fileInputPath?: string;\n}\n\nexport interface GuiScreenshotFile {\n path: string;\n data: string;\n encoding: 'base64';\n}\n\nexport interface GuiCommandRunResult {\n stdin: string;\n stdout: string;\n stderr: string;\n status: number | undefined;\n timeSeconds: number;\n memoryBytes: number;\n screenshots: GuiScreenshotFile[];\n stopReason: 'process_exit' | 'stable_screenshot' | 'timeout';\n}\n\ninterface GuiJudgeContext {\n timeLimitSeconds: number;\n problemMarkdownFrontMatter: Pick<ProblemMarkdownFrontMatter, 'memoryLimitByte' | 'requiredOutputFilePaths'>;\n}\n\ntype GuiJudgeCaseResult = Pick<\n TestCaseResult,\n 'decisionCode' | 'feedbackMarkdown' | 'stderr' | 'stdout' | 'outputFiles'\n>;\n\nexport interface GuiCommandJudgePresetOptions<TTestCase extends BaseGuiTestCase = BaseGuiTestCase> {\n mainFilePath?: string;\n runTimeoutSeconds?: number;\n screenshotWaitSeconds?: number;\n stopDetectionThreshold?: number;\n readTestCases?: (problemDir: string) => Promise<readonly TTestCase[]>;\n prepare?: (context: {\n cwd: string;\n env: NodeJS.ProcessEnv;\n mainFilePath: string;\n problemMarkdownFrontMatter: ProblemMarkdownFrontMatter;\n }) => Promise<Partial<GuiJudgeCaseResult> | undefined> | Partial<GuiJudgeCaseResult> | undefined;\n resolveInput?: (context: { testCase: TTestCase; cwd: string; env: NodeJS.ProcessEnv }) => Promise<string> | string;\n command?: (context: {\n testCase: TTestCase;\n cwd: string;\n env: NodeJS.ProcessEnv;\n mainFilePath: string;\n }) => Promise<readonly [string, ...string[]]> | readonly [string, ...string[]];\n runCommand?: (context: {\n testCase: TTestCase;\n command: readonly [string, ...string[]];\n stdin: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeLimitSeconds: number;\n screenshotWaitSeconds: number;\n stopDetectionThreshold: number;\n }) => Promise<GuiCommandRunResult> | GuiCommandRunResult;\n test: (context: {\n testCase: TTestCase;\n runResult: GuiCommandRunResult;\n outputFiles: NonNullable<TestCaseResult['outputFiles']>;\n context: GuiJudgeContext;\n }) => Promise<Partial<GuiJudgeCaseResult>> | Partial<GuiJudgeCaseResult>;\n}\n\n/**\n * A preset function for judging GUI programs by collecting screenshots while the program runs.\n *\n * Keep problem-specific logic in `prepare`, `command`, and `test`.\n *\n * @example\n * Create `judge.ts`:\n * ```ts\n * import { DecisionCode } from '@exercode/problem-utils';\n * import { guiCommandJudgePreset } from '@exercode/problem-utils/presets/guiCommand';\n *\n * await guiCommandJudgePreset(import.meta.dirname, {\n * mainFilePath: 'Main.java',\n * readTestCases: async () => [{ id: 'default' }],\n * test: ({ runResult }) => {\n * return runResult.screenshots.length > 0\n * ? { decisionCode: DecisionCode.ACCEPTED }\n * : { decisionCode: DecisionCode.WRONG_ANSWER };\n * },\n * });\n * ```\n */\nexport async function guiCommandJudgePreset<TTestCase extends BaseGuiTestCase = BaseGuiTestCase>(\n problemDir: string,\n options: GuiCommandJudgePresetOptions<TTestCase>\n): Promise<void> {\n const args = parseArgs(process.argv);\n if (!args.cwd) throw new Error('cwd argument required');\n const params = judgeParamsSchema.parse(args.params);\n\n const problemMarkdownFrontMatter = await readProblemMarkdownFrontMatter(problemDir);\n const configuredTestCases = await (options.readTestCases ?? readGuiTestCases<TTestCase>)(problemDir);\n const testCases =\n configuredTestCases.length > 0 ? configuredTestCases : ([{ id: 'default' }] as unknown as readonly TTestCase[]);\n const prebuildTestCaseId = testCases[0]?.id ?? 'prebuild';\n\n const staticAnalysisResult = await judgeByStaticAnalysis(args.cwd, problemMarkdownFrontMatter);\n if (staticAnalysisResult) {\n printTestCaseResult({ testCaseId: prebuildTestCaseId, ...staticAnalysisResult });\n return;\n }\n\n const initialMainFilePath = options.mainFilePath ?? (await findEntryPointFile(args.cwd, params.language));\n if (!initialMainFilePath) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,\n stderr: options.mainFilePath\n ? `required main file not found: ${options.mainFilePath}`\n : `main file not found${params.language ? `: language: ${params.language}` : ''}`,\n });\n return;\n }\n\n const languageDefinition = findLanguageDefinitionByPath(initialMainFilePath);\n if (!languageDefinition) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.WRONG_ANSWER,\n stderr: 'unsupported language',\n });\n return;\n }\n\n const env = { ...process.env, CI: '', FORCE_COLOR: '0' };\n\n let resolvedMainFilePath = await resolveMainFilePath({\n cwd: args.cwd,\n language: params.language,\n configuredMainFilePath: options.mainFilePath,\n });\n if (languageDefinition.prebuild) {\n try {\n await languageDefinition.prebuild(args.cwd);\n const prebuiltMainFilePath = await resolveMainFilePath({\n cwd: args.cwd,\n language: params.language ?? inferLanguageIdsByPath(initialMainFilePath),\n configuredMainFilePath: options.mainFilePath,\n allowConfiguredPathFallback: true,\n });\n if (prebuiltMainFilePath) resolvedMainFilePath = prebuiltMainFilePath;\n } catch (error) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.BUILD_ERROR,\n stderr: errorToMessage(error),\n });\n return;\n }\n }\n if (!resolvedMainFilePath) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,\n stderr: options.mainFilePath\n ? `required main file not found: ${options.mainFilePath}`\n : `main file not found${params.language ? `: language: ${params.language}` : ''}`,\n });\n return;\n }\n\n const prepareResult =\n (await options.prepare?.({\n cwd: args.cwd,\n env,\n mainFilePath: resolvedMainFilePath,\n problemMarkdownFrontMatter,\n })) ??\n runDefaultPrepare({\n cwd: args.cwd,\n env,\n mainFilePath: resolvedMainFilePath,\n languageDefinition,\n });\n if (prepareResult) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: prepareResult.decisionCode ?? DecisionCode.BUILD_ERROR,\n feedbackMarkdown: prepareResult.feedbackMarkdown,\n stderr: prepareResult.stderr,\n stdout: prepareResult.stdout,\n outputFiles: prepareResult.outputFiles,\n });\n return;\n }\n\n const cwdSnapshot = await snapshotWorkingDirectory(args.cwd);\n let displayServer: Awaited<ReturnType<typeof ensureDisplayServer>> | undefined;\n let currentTestCaseId = prebuildTestCaseId;\n let currentStdin: string | undefined;\n try {\n displayServer = options.runCommand ? undefined : await ensureDisplayServer();\n const sharedFileInputPath = (configuredTestCases as { shared?: { fileInputPath?: string } }).shared?.fileInputPath;\n for (const testCase of testCases) {\n currentTestCaseId = testCase.id;\n if (sharedFileInputPath) await copyTestCaseFileInput(sharedFileInputPath, args.cwd);\n if (testCase.fileInputPath) await copyTestCaseFileInput(testCase.fileInputPath, args.cwd);\n\n const timeLimitSeconds =\n typeof problemMarkdownFrontMatter.timeLimitMs === 'number'\n ? problemMarkdownFrontMatter.timeLimitMs / 1000\n : (options.runTimeoutSeconds ?? JUDGE_DEFAULT_TIMEOUT_SECONDS);\n\n const runEnv = displayServer ? { ...env, DISPLAY: displayServer.display } : env;\n const stdin = (await options.resolveInput?.({ testCase, cwd: args.cwd, env: runEnv })) ?? testCase.input ?? '';\n currentStdin = stdin;\n const command =\n (await options.command?.({ testCase, cwd: args.cwd, env: runEnv, mainFilePath: resolvedMainFilePath })) ??\n languageDefinition.command(resolvedMainFilePath);\n\n let runResult: GuiCommandRunResult;\n try {\n runResult = options.runCommand\n ? await options.runCommand({\n testCase,\n command,\n stdin,\n cwd: args.cwd,\n env: runEnv,\n timeLimitSeconds,\n screenshotWaitSeconds: options.screenshotWaitSeconds ?? SCREENSHOT_WAIT_SECONDS,\n stopDetectionThreshold: options.stopDetectionThreshold ?? STOP_DETECTION_THRESHOLD,\n })\n : await spawnGuiProgram({\n command,\n stdin,\n cwd: args.cwd,\n env: runEnv,\n timeLimitSeconds,\n screenshotWaitSeconds: options.screenshotWaitSeconds ?? SCREENSHOT_WAIT_SECONDS,\n stopDetectionThreshold: options.stopDetectionThreshold ?? STOP_DETECTION_THRESHOLD,\n });\n } catch (error) {\n printTestCaseResult({\n testCaseId: testCase.id,\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stdin,\n stderr: errorToMessage(error),\n });\n await cleanWorkingDirectory(args.cwd, cwdSnapshot);\n return;\n }\n\n const outputFiles = await readOutputFiles(args.cwd, problemMarkdownFrontMatter.requiredOutputFilePaths ?? []);\n const judgeContext: GuiJudgeContext = {\n timeLimitSeconds,\n problemMarkdownFrontMatter: {\n memoryLimitByte: problemMarkdownFrontMatter.memoryLimitByte,\n requiredOutputFilePaths: problemMarkdownFrontMatter.requiredOutputFilePaths,\n },\n };\n const baseJudgeResult = evaluateGuiRunResult({ runResult, outputFiles, context: judgeContext });\n let judgeResult = baseJudgeResult;\n if (baseJudgeResult.decisionCode === DecisionCode.ACCEPTED) {\n try {\n const extendedJudgeResult = await options.test({\n testCase,\n runResult,\n outputFiles,\n context: judgeContext,\n });\n judgeResult = {\n decisionCode: extendedJudgeResult.decisionCode ?? baseJudgeResult.decisionCode,\n feedbackMarkdown: extendedJudgeResult.feedbackMarkdown,\n stderr: extendedJudgeResult.stderr,\n stdout: extendedJudgeResult.stdout,\n outputFiles: extendedJudgeResult.outputFiles,\n };\n } catch (error) {\n judgeResult = {\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stderr: errorToMessage(error),\n };\n }\n }\n\n const decisionCode = judgeResult.decisionCode ?? DecisionCode.ACCEPTED;\n const stdout = judgeResult.stdout ?? runResult.stdout;\n const stderr = judgeResult.stderr ?? runResult.stderr;\n printTestCaseResult({\n testCaseId: testCase.id,\n decisionCode,\n exitStatus: runResult.status,\n stdin: runResult.stdin || undefined,\n stdout: stdout || undefined,\n stderr: stderr || undefined,\n timeSeconds: runResult.timeSeconds,\n memoryBytes: runResult.memoryBytes,\n feedbackMarkdown: judgeResult.feedbackMarkdown,\n outputFiles: judgeResult.outputFiles ?? (outputFiles.length > 0 ? outputFiles : undefined),\n });\n\n await cleanWorkingDirectory(args.cwd, cwdSnapshot);\n if (decisionCode !== DecisionCode.ACCEPTED) break;\n }\n } catch (error) {\n printTestCaseResult({\n testCaseId: currentTestCaseId,\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stdin: currentStdin,\n stderr: errorToMessage(error),\n });\n await cleanWorkingDirectory(args.cwd, cwdSnapshot);\n } finally {\n await displayServer?.dispose();\n }\n}\n\nasync function resolveMainFilePath(context: {\n cwd: string;\n language?: string | string[];\n configuredMainFilePath?: string;\n allowConfiguredPathFallback?: boolean;\n}): Promise<string | undefined> {\n if (context.configuredMainFilePath) {\n const resolvedPath = path.join(context.cwd, context.configuredMainFilePath);\n if (await pathExists(resolvedPath)) return context.configuredMainFilePath;\n if (!context.allowConfiguredPathFallback) return undefined;\n }\n\n return await findEntryPointFile(context.cwd, context.language);\n}\n\nfunction inferLanguageIdsByPath(filePath: string): string[] | undefined {\n const languageIds = Object.entries(languageIdToDefinition)\n .filter(([, definition]) => definition.fileExtensions.some((ext) => filePath.endsWith(ext)))\n .map(([languageId]) => languageId);\n return languageIds.length > 0 ? languageIds : undefined;\n}\n\nfunction runDefaultPrepare(context: {\n cwd: string;\n env: NodeJS.ProcessEnv;\n mainFilePath: string;\n languageDefinition: NonNullable<ReturnType<typeof findLanguageDefinitionByPath>>;\n}): Partial<GuiJudgeCaseResult> | undefined {\n const buildCommand = context.languageDefinition.buildCommand?.(context.mainFilePath);\n if (!buildCommand) return undefined;\n\n const buildResult = spawnSyncWithTimeout(\n buildCommand[0],\n buildCommand.slice(1),\n { cwd: context.cwd, encoding: 'utf8', env: context.env },\n BUILD_TIMEOUT_SECONDS\n );\n\n if (buildResult.timeSeconds > BUILD_TIMEOUT_SECONDS) {\n return {\n decisionCode: DecisionCode.BUILD_TIME_LIMIT_EXCEEDED,\n stderr: buildResult.stderr || undefined,\n };\n }\n\n if (buildResult.status !== 0) {\n return {\n decisionCode: DecisionCode.BUILD_ERROR,\n stderr: buildResult.stderr || buildResult.stdout || undefined,\n };\n }\n\n return undefined;\n}\n\nfunction evaluateGuiRunResult(context: {\n runResult: GuiCommandRunResult;\n outputFiles: NonNullable<TestCaseResult['outputFiles']>;\n context: GuiJudgeContext;\n}): Partial<GuiJudgeCaseResult> {\n if (context.runResult.stopReason === 'timeout') {\n return {\n decisionCode: DecisionCode.TIME_LIMIT_EXCEEDED,\n stderr: context.runResult.stderr,\n };\n }\n\n if (context.runResult.status !== 0) {\n return {\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stderr: context.runResult.stderr,\n };\n }\n\n if (\n context.runResult.memoryBytes >\n (context.context.problemMarkdownFrontMatter.memoryLimitByte ?? Number.POSITIVE_INFINITY)\n ) {\n return {\n decisionCode: DecisionCode.MEMORY_LIMIT_EXCEEDED,\n stderr: context.runResult.stderr,\n };\n }\n\n const requiredOutputFilesCount = context.context.problemMarkdownFrontMatter.requiredOutputFilePaths?.length ?? 0;\n if (context.outputFiles.length < requiredOutputFilesCount) {\n return {\n decisionCode: DecisionCode.MISSING_REQUIRED_OUTPUT_FILE_ERROR,\n };\n }\n\n return { decisionCode: DecisionCode.ACCEPTED };\n}\n\nasync function readGuiTestCases<TTestCase extends BaseGuiTestCase>(problemDir: string): Promise<readonly TTestCase[]> {\n return (await readFileTestCases(path.join(problemDir, 'test_cases'))) as unknown as readonly TTestCase[];\n}\n\nasync function spawnGuiProgram(context: {\n command: readonly [string, ...string[]];\n stdin: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeLimitSeconds: number;\n screenshotWaitSeconds: number;\n stopDetectionThreshold: number;\n}): Promise<GuiCommandRunResult> {\n const wrappedCommand = ['timeout', context.timeLimitSeconds.toFixed(3), ...TIME_COMMAND, ...context.command] as const;\n const child = childProcess.spawn(wrappedCommand[0], wrappedCommand.slice(1), {\n cwd: context.cwd,\n env: context.env,\n detached: process.platform !== 'win32',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n child.stdout.setEncoding('utf8');\n child.stderr.setEncoding('utf8');\n\n let stdout = '';\n let stderr = '';\n let exitCode: number | undefined;\n let spawnError: Error | undefined;\n let stopReason: GuiCommandRunResult['stopReason'] = 'process_exit';\n const screenshotSignaturesHistory: string[][] = [];\n let screenshots: GuiScreenshotFile[] = [];\n const startTimeSeconds = Date.now() / 1000;\n let sampledMemoryBytes = 0;\n\n child.stdout.on('data', (chunk: string) => {\n stdout += chunk;\n });\n child.stderr.on('data', (chunk: string) => {\n stderr += chunk;\n });\n child.on('error', (error) => {\n spawnError = error;\n exitCode = 1;\n });\n child.on('close', (code, signal) => {\n if (code === 124) {\n stopReason = 'timeout';\n exitCode = 0;\n return;\n }\n if (signal) {\n exitCode = 1;\n stderr = stderr\n ? `${stderr}\\nprocess terminated by signal: ${signal}`\n : `process terminated by signal: ${signal}`;\n return;\n }\n exitCode = code ?? 1;\n });\n\n if (context.stdin) child.stdin.write(context.stdin);\n child.stdin.end();\n\n while (exitCode === undefined) {\n await wait(context.screenshotWaitSeconds * 1000);\n sampledMemoryBytes = Math.max(sampledMemoryBytes, readProcessGroupMemoryBytes(child.pid));\n const currentScreenshots = takeScreenshots(context.env.DISPLAY);\n screenshots = currentScreenshots.toSorted((a, b) => a.data.length - b.data.length);\n\n if (screenshots.length > 0) {\n const screenshotSignatures = screenshots.map((file) => file.data).toSorted();\n screenshotSignaturesHistory.unshift(screenshotSignatures);\n screenshotSignaturesHistory.length = Math.min(screenshotSignaturesHistory.length, context.stopDetectionThreshold);\n if (\n screenshotSignaturesHistory.length === context.stopDetectionThreshold &&\n screenshotSignaturesHistory.every(\n (files) =>\n files.length === screenshotSignatures.length &&\n files.every((file, index) => file === screenshotSignatures[index])\n )\n ) {\n stopReason = 'stable_screenshot';\n exitCode = 0;\n break;\n }\n }\n\n if (Date.now() / 1000 - startTimeSeconds > context.timeLimitSeconds) {\n stopReason = 'timeout';\n exitCode = 0;\n break;\n }\n }\n\n if (stopReason !== 'process_exit' && child.exitCode === null) {\n child.removeAllListeners('close');\n child.removeAllListeners('error');\n }\n await stopProcess(child);\n if (spawnError) throw spawnError;\n const {\n memoryBytes,\n stderr: normalizedStderr,\n timeSeconds,\n } = parseTimedStderr(stderr, startTimeSeconds, sampledMemoryBytes);\n\n return {\n stdin: context.stdin,\n stdout: stdout.trimEnd(),\n stderr: normalizedStderr,\n status: exitCode,\n timeSeconds,\n memoryBytes,\n screenshots,\n stopReason,\n };\n}\n\nfunction takeScreenshots(display: string | undefined): GuiScreenshotFile[] {\n const env = display ? { ...process.env, DISPLAY: display } : process.env;\n const xwininfo = childProcess.spawnSync('xwininfo', ['-root', '-tree'], { encoding: 'utf8', env });\n if (xwininfo.error) throw xwininfo.error;\n if (xwininfo.status !== 0 || !xwininfo.stdout) return [];\n\n const screenshots: GuiScreenshotFile[] = [];\n for (const windowId of extractTopLevelWindowIds(xwininfo.stdout)) {\n const screenshot = childProcess.spawnSync('maim', ['-i', windowId], { env });\n if (screenshot.error) throw screenshot.error;\n if (screenshot.status !== 0 || screenshot.stdout.length === 0) continue;\n\n const windowNameResult = childProcess.spawnSync('xdotool', ['getwindowname', windowId], { encoding: 'utf8', env });\n if (windowNameResult.error) throw windowNameResult.error;\n const windowName = windowNameResult.stdout.trim().replaceAll(/[\\s/]/g, '_');\n\n screenshots.push({\n path: `${windowName || 'window'}_${windowId}.png`,\n data: screenshot.stdout.toString('base64'),\n encoding: 'base64',\n });\n }\n\n return screenshots;\n}\n\nfunction extractTopLevelWindowIds(stdout: string): string[] {\n const windowIds: string[] = [];\n const lines = stdout.split('\\n');\n for (const line of lines) {\n if (line.includes('Root window id:') || line.includes('Parent window id:') || line.includes('()')) continue;\n\n const match = /^\\s{5}(0x[\\da-f]+) /.exec(line);\n if (!match?.[1]) continue;\n windowIds.push(Number.parseInt(match[1], 16).toString());\n }\n return windowIds;\n}\n\nfunction parseTimedStderr(\n stderr: string,\n startTimeSeconds: number,\n sampledMemoryBytes: number\n): Pick<GuiCommandRunResult, 'stderr' | 'timeSeconds' | 'memoryBytes'> {\n const match = /(?:^|\\n)(\\d+\\.\\d+) (\\d+)\\s*$/.exec(stderr);\n const normalizedStderr = match ? stderr.slice(0, match.index).trimEnd() : stderr.trimEnd();\n const parsedMemoryBytes = Number(match?.[2]) * 1024 || 0;\n return {\n stderr: normalizedStderr,\n timeSeconds: Number(match?.[1]) || Date.now() / 1000 - startTimeSeconds,\n memoryBytes: Math.max(parsedMemoryBytes, sampledMemoryBytes),\n };\n}\n\nasync function ensureDisplayServer(): Promise<{ display: string; dispose: () => Promise<void> }> {\n if (process.platform !== 'linux') {\n throw new Error('GUI screenshot capture is supported only on Linux.');\n }\n\n for (let displayNumber = 90; displayNumber < 100; displayNumber++) {\n const display = `:${displayNumber}`;\n let spawnError: Error | undefined;\n const xvfb = childProcess.spawn('Xvfb', [display, '-screen', '0', '1280x1024x24', '-ac'], {\n stdio: 'ignore',\n });\n xvfb.on('error', (error) => {\n spawnError = error;\n });\n\n await wait(XVFB_STARTUP_WAIT_SECONDS * 1000);\n if (spawnError) throw spawnError;\n if (xvfb.exitCode !== null) continue;\n\n return {\n display,\n dispose: async () => {\n if (!xvfb.killed) {\n xvfb.kill('SIGTERM');\n await wait(XVFB_SHUTDOWN_WAIT_SECONDS * 1000);\n if (xvfb.exitCode === null) xvfb.kill('SIGKILL');\n }\n },\n };\n }\n\n throw new Error('Xvfb could not be started.');\n}\n\nasync function stopProcess(child: childProcess.ChildProcess): Promise<void> {\n if (!child.pid) return;\n killProcessGroup(child.pid, 'SIGTERM');\n await wait(PROCESS_SHUTDOWN_WAIT_SECONDS * 1000);\n if (child.exitCode === null) killProcessGroup(child.pid, 'SIGKILL');\n}\n\nfunction readProcessGroupMemoryBytes(processGroupId: number | undefined): number {\n if (!processGroupId || process.platform !== 'linux') return 0;\n\n const result = childProcess.spawnSync('ps', ['-o', 'rss=', '--no-headers', '--pgroup', String(processGroupId)], {\n encoding: 'utf8',\n });\n if (result.error || result.status !== 0 || !result.stdout) return 0;\n\n return result.stdout\n .split('\\n')\n .map((line) => Number(line.trim()))\n .filter((value) => Number.isFinite(value) && value > 0)\n .reduce((sum, value) => sum + value * 1024, 0);\n}\n\nfunction killProcessGroup(processGroupId: number, signal: NodeJS.Signals): void {\n try {\n if (process.platform !== 'win32') {\n process.kill(-processGroupId, signal);\n return;\n }\n } catch {\n // The process group may already be gone. Fall back to the direct PID below.\n }\n\n try {\n process.kill(processGroupId, signal);\n } catch {\n // The direct child may also already be gone.\n }\n}\n\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction errorToMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":"09BAwBA,MAEM,EAA0B,GAK1B,EAAe,CAACA,EAAAA,QAAG,SAAS,IAAM,SAAW,QAAU,gBAAiB,WAAY,OAAO,EAE3F,EAAoBC,EAAAA,EAAE,OAAO,CACjC,SAAUA,EAAAA,EAAE,MAAM,CAACA,EAAAA,EAAE,OAAO,EAAGA,EAAAA,EAAE,MAAMA,EAAAA,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAChE,CAAC,EA8FD,eAAsB,EACpB,EACA,EACe,CACf,IAAM,EAAOC,EAAAA,UAAU,QAAQ,IAAI,EACnC,GAAI,CAAC,EAAK,IAAK,MAAU,MAAM,uBAAuB,EACtD,IAAM,EAAS,EAAkB,MAAM,EAAK,MAAM,EAE5C,EAA6B,MAAMC,EAAAA,+BAA+B,CAAU,EAC5E,EAAsB,MAAO,EAAQ,eAAiB,EAAA,CAA6B,CAAU,EAC7F,EACJ,EAAoB,OAAS,EAAI,EAAuB,CAAC,CAAE,GAAI,SAAU,CAAC,EACtE,EAAqB,EAAU,EAAE,EAAE,IAAM,WAEzC,EAAuB,MAAMC,EAAAA,sBAAsB,EAAK,IAAK,CAA0B,EAC7F,GAAI,EAAsB,CACxB,EAAA,oBAAoB,CAAE,WAAY,EAAoB,GAAG,CAAqB,CAAC,EAC/E,MACF,CAEA,IAAM,EAAsB,EAAQ,cAAiB,MAAMC,EAAAA,mBAAmB,EAAK,IAAK,EAAO,QAAQ,EACvG,GAAI,CAAC,EAAqB,CACxB,EAAA,oBAAoB,CAClB,WAAY,EACZ,aAAcC,EAAAA,aAAa,uCAC3B,OAAQ,EAAQ,aACZ,iCAAiC,EAAQ,eACzC,sBAAsB,EAAO,SAAW,eAAe,EAAO,WAAa,IACjF,CAAC,EACD,MACF,CAEA,IAAM,EAAqBC,EAAAA,6BAA6B,CAAmB,EAC3E,GAAI,CAAC,EAAoB,CACvB,EAAA,oBAAoB,CAClB,WAAY,EACZ,aAAcD,EAAAA,aAAa,aAC3B,OAAQ,sBACV,CAAC,EACD,MACF,CAEA,IAAM,EAAM,CAAE,GAAG,QAAQ,IAAK,GAAI,GAAI,YAAa,GAAI,EAEnD,EAAuB,MAAM,EAAoB,CACnD,IAAK,EAAK,IACV,SAAU,EAAO,SACjB,uBAAwB,EAAQ,YAClC,CAAC,EACD,GAAI,EAAmB,SACrB,GAAI,CACF,MAAM,EAAmB,SAAS,EAAK,GAAG,EAC1C,IAAM,EAAuB,MAAM,EAAoB,CACrD,IAAK,EAAK,IACV,SAAU,EAAO,UAAY,EAAuB,CAAmB,EACvE,uBAAwB,EAAQ,aAChC,4BAA6B,EAC/B,CAAC,EACG,IAAsB,EAAuB,EACnD,OAAS,EAAO,CACd,EAAA,oBAAoB,CAClB,WAAY,EACZ,aAAcA,EAAAA,aAAa,YAC3B,OAAQ,EAAe,CAAK,CAC9B,CAAC,EACD,MACF,CAEF,GAAI,CAAC,EAAsB,CACzB,EAAA,oBAAoB,CAClB,WAAY,EACZ,aAAcA,EAAAA,aAAa,uCAC3B,OAAQ,EAAQ,aACZ,iCAAiC,EAAQ,eACzC,sBAAsB,EAAO,SAAW,eAAe,EAAO,WAAa,IACjF,CAAC,EACD,MACF,CAEA,IAAM,EACH,MAAM,EAAQ,UAAU,CACvB,IAAK,EAAK,IACV,MACA,aAAc,EACd,4BACF,CAAC,GACD,EAAkB,CAChB,IAAK,EAAK,IACV,MACA,aAAc,EACd,oBACF,CAAC,EACH,GAAI,EAAe,CACjB,EAAA,oBAAoB,CAClB,WAAY,EACZ,aAAc,EAAc,cAAgBA,EAAAA,aAAa,YACzD,iBAAkB,EAAc,iBAChC,OAAQ,EAAc,OACtB,OAAQ,EAAc,OACtB,YAAa,EAAc,WAC7B,CAAC,EACD,MACF,CAEA,IAAM,EAAc,MAAME,EAAAA,yBAAyB,EAAK,GAAG,EACvD,EACA,EAAoB,EACpB,EACJ,GAAI,CACF,EAAgB,EAAQ,WAAa,IAAA,GAAY,MAAM,EAAoB,EAC3E,IAAM,EAAuB,EAAgE,QAAQ,cACrG,IAAK,IAAM,KAAY,EAAW,CAChC,EAAoB,EAAS,GACzB,GAAqB,MAAMC,EAAAA,sBAAsB,EAAqB,EAAK,GAAG,EAC9E,EAAS,eAAe,MAAMA,EAAAA,sBAAsB,EAAS,cAAe,EAAK,GAAG,EAExF,IAAM,EACJ,OAAO,EAA2B,aAAgB,SAC9C,EAA2B,YAAc,IACxC,EAAQ,mBAAqB,EAE9B,EAAS,EAAgB,CAAE,GAAG,EAAK,QAAS,EAAc,OAAQ,EAAI,EACtE,EAAS,MAAM,EAAQ,eAAe,CAAE,WAAU,IAAK,EAAK,IAAK,IAAK,CAAO,CAAC,GAAM,EAAS,OAAS,GAC5G,EAAe,EACf,IAAM,EACH,MAAM,EAAQ,UAAU,CAAE,WAAU,IAAK,EAAK,IAAK,IAAK,EAAQ,aAAc,CAAqB,CAAC,GACrG,EAAmB,QAAQ,CAAoB,EAE7C,EACJ,GAAI,CACF,EAAY,EAAQ,WAChB,MAAM,EAAQ,WAAW,CACvB,WACA,UACA,QACA,IAAK,EAAK,IACV,IAAK,EACL,mBACA,sBAAuB,EAAQ,uBAAyB,EACxD,uBAAwB,EAAQ,wBAA0B,CAC5D,CAAC,EACD,MAAM,EAAgB,CACpB,UACA,QACA,IAAK,EAAK,IACV,IAAK,EACL,mBACA,sBAAuB,EAAQ,uBAAyB,EACxD,uBAAwB,EAAQ,wBAA0B,CAC5D,CAAC,CACP,OAAS,EAAO,CACd,EAAA,oBAAoB,CAClB,WAAY,EAAS,GACrB,aAAcH,EAAAA,aAAa,cAC3B,QACA,OAAQ,EAAe,CAAK,CAC9B,CAAC,EACD,MAAMI,EAAAA,sBAAsB,EAAK,IAAK,CAAW,EACjD,MACF,CAEA,IAAM,EAAc,MAAMC,EAAAA,gBAAgB,EAAK,IAAK,EAA2B,yBAA2B,CAAC,CAAC,EACtG,EAAgC,CACpC,mBACA,2BAA4B,CAC1B,gBAAiB,EAA2B,gBAC5C,wBAAyB,EAA2B,uBACtD,CACF,EACM,EAAkB,EAAqB,CAAE,YAAW,cAAa,QAAS,CAAa,CAAC,EAC1F,EAAc,EAClB,GAAI,EAAgB,eAAiBL,EAAAA,aAAa,SAChD,GAAI,CACF,IAAM,EAAsB,MAAM,EAAQ,KAAK,CAC7C,WACA,YACA,cACA,QAAS,CACX,CAAC,EACD,EAAc,CACZ,aAAc,EAAoB,cAAgB,EAAgB,aAClE,iBAAkB,EAAoB,iBACtC,OAAQ,EAAoB,OAC5B,OAAQ,EAAoB,OAC5B,YAAa,EAAoB,WACnC,CACF,OAAS,EAAO,CACd,EAAc,CACZ,aAAcA,EAAAA,aAAa,cAC3B,OAAQ,EAAe,CAAK,CAC9B,CACF,CAGF,IAAM,EAAe,EAAY,cAAgBA,EAAAA,aAAa,SACxD,EAAS,EAAY,QAAU,EAAU,OACzC,EAAS,EAAY,QAAU,EAAU,OAe/C,GAdA,EAAA,oBAAoB,CAClB,WAAY,EAAS,GACrB,eACA,WAAY,EAAU,OACtB,MAAO,EAAU,OAAS,IAAA,GAC1B,OAAQ,GAAU,IAAA,GAClB,OAAQ,GAAU,IAAA,GAClB,YAAa,EAAU,YACvB,YAAa,EAAU,YACvB,iBAAkB,EAAY,iBAC9B,YAAa,EAAY,cAAgB,EAAY,OAAS,EAAI,EAAc,IAAA,GAClF,CAAC,EAED,MAAMI,EAAAA,sBAAsB,EAAK,IAAK,CAAW,EAC7C,IAAiBJ,EAAAA,aAAa,SAAU,KAC9C,CACF,OAAS,EAAO,CACd,EAAA,oBAAoB,CAClB,WAAY,EACZ,aAAcA,EAAAA,aAAa,cAC3B,MAAO,EACP,OAAQ,EAAe,CAAK,CAC9B,CAAC,EACD,MAAMI,EAAAA,sBAAsB,EAAK,IAAK,CAAW,CACnD,QAAU,CACR,MAAM,GAAe,QAAQ,CAC/B,CACF,CAEA,eAAe,EAAoB,EAKH,CAC9B,GAAI,EAAQ,uBAAwB,CAElC,GAAI,MAAM,EADWE,EAAAA,QAAK,KAAK,EAAQ,IAAK,EAAQ,sBACpB,CAAC,EAAG,OAAO,EAAQ,uBACnD,GAAI,CAAC,EAAQ,4BAA6B,MAC5C,CAEA,OAAO,MAAMP,EAAAA,mBAAmB,EAAQ,IAAK,EAAQ,QAAQ,CAC/D,CAEA,SAAS,EAAuB,EAAwC,CACtE,IAAM,EAAc,OAAO,QAAQQ,EAAAA,sBAAsB,CAAC,CACvD,QAAQ,EAAG,KAAgB,EAAW,eAAe,KAAM,GAAQ,EAAS,SAAS,CAAG,CAAC,CAAC,CAAC,CAC3F,KAAK,CAAC,KAAgB,CAAU,EACnC,OAAO,EAAY,OAAS,EAAI,EAAc,IAAA,EAChD,CAEA,SAAS,EAAkB,EAKiB,CAC1C,IAAM,EAAe,EAAQ,mBAAmB,eAAe,EAAQ,YAAY,EACnF,GAAI,CAAC,EAAc,OAEnB,IAAM,EAAcC,EAAAA,qBAClB,EAAa,GACb,EAAa,MAAM,CAAC,EACpB,CAAE,IAAK,EAAQ,IAAK,SAAU,OAAQ,IAAK,EAAQ,GAAI,EACvD,EACF,EAEA,GAAI,EAAY,YAAc,GAC5B,MAAO,CACL,aAAcR,EAAAA,aAAa,0BAC3B,OAAQ,EAAY,QAAU,IAAA,EAChC,EAGF,GAAI,EAAY,SAAW,EACzB,MAAO,CACL,aAAcA,EAAAA,aAAa,YAC3B,OAAQ,EAAY,QAAU,EAAY,QAAU,IAAA,EACtD,CAIJ,CAEA,SAAS,EAAqB,EAIE,CAC9B,GAAI,EAAQ,UAAU,aAAe,UACnC,MAAO,CACL,aAAcA,EAAAA,aAAa,oBAC3B,OAAQ,EAAQ,UAAU,MAC5B,EAGF,GAAI,EAAQ,UAAU,SAAW,EAC/B,MAAO,CACL,aAAcA,EAAAA,aAAa,cAC3B,OAAQ,EAAQ,UAAU,MAC5B,EAGF,GACE,EAAQ,UAAU,aACjB,EAAQ,QAAQ,2BAA2B,iBAAmB,KAE/D,MAAO,CACL,aAAcA,EAAAA,aAAa,sBAC3B,OAAQ,EAAQ,UAAU,MAC5B,EAGF,IAAM,EAA2B,EAAQ,QAAQ,2BAA2B,yBAAyB,QAAU,EAO/G,OANI,EAAQ,YAAY,OAAS,EACxB,CACL,aAAcA,EAAAA,aAAa,kCAC7B,EAGK,CAAE,aAAcA,EAAAA,aAAa,QAAS,CAC/C,CAEA,eAAe,EAAoD,EAAmD,CACpH,OAAQ,MAAMS,EAAAA,cAAkBH,EAAAA,QAAK,KAAK,EAAY,YAAY,CAAC,CACrE,CAEA,eAAe,EAAgB,EAQE,CAC/B,IAAM,EAAiB,CAAC,UAAW,EAAQ,iBAAiB,QAAQ,CAAC,EAAG,GAAG,EAAc,GAAG,EAAQ,OAAO,EACrG,EAAQI,EAAAA,QAAa,MAAM,EAAe,GAAI,EAAe,MAAM,CAAC,EAAG,CAC3E,IAAK,EAAQ,IACb,IAAK,EAAQ,IACb,SAAU,QAAQ,WAAa,QAC/B,MAAO,CAAC,OAAQ,OAAQ,MAAM,CAChC,CAAC,EAED,EAAM,OAAO,YAAY,MAAM,EAC/B,EAAM,OAAO,YAAY,MAAM,EAE/B,IAAI,EAAS,GACT,EAAS,GACT,EACA,EACA,EAAgD,eAC9C,EAA0C,CAAC,EAC7C,EAAmC,CAAC,EAClC,EAAmB,KAAK,IAAI,EAAI,IAClC,EAAqB,EA+BzB,IA7BA,EAAM,OAAO,GAAG,OAAS,GAAkB,CACzC,GAAU,CACZ,CAAC,EACD,EAAM,OAAO,GAAG,OAAS,GAAkB,CACzC,GAAU,CACZ,CAAC,EACD,EAAM,GAAG,QAAU,GAAU,CAC3B,EAAa,EACb,EAAW,CACb,CAAC,EACD,EAAM,GAAG,SAAU,EAAM,IAAW,CAClC,GAAI,IAAS,IAAK,CAChB,EAAa,UACb,EAAW,EACX,MACF,CACA,GAAI,EAAQ,CACV,EAAW,EACX,EAAS,EACL,GAAG,EAAO,kCAAkC,IAC5C,iCAAiC,IACrC,MACF,CACA,EAAW,GAAQ,CACrB,CAAC,EAEG,EAAQ,OAAO,EAAM,MAAM,MAAM,EAAQ,KAAK,EAClD,EAAM,MAAM,IAAI,EAET,IAAa,IAAA,IAAW,CAM7B,GALA,MAAA,EAAA,EAAA,WAAA,CAAW,EAAQ,sBAAwB,GAAI,EAC/C,EAAqB,KAAK,IAAI,EAAoB,EAA4B,EAAM,GAAG,CAAC,EAExF,EAD2B,EAAgB,EAAQ,IAAI,OACxB,CAAC,CAAC,UAAU,EAAG,IAAM,EAAE,KAAK,OAAS,EAAE,KAAK,MAAM,EAE7E,EAAY,OAAS,EAAG,CAC1B,IAAM,EAAuB,EAAY,IAAK,GAAS,EAAK,IAAI,CAAC,CAAC,SAAS,EAG3E,GAFA,EAA4B,QAAQ,CAAoB,EACxD,EAA4B,OAAS,KAAK,IAAI,EAA4B,OAAQ,EAAQ,sBAAsB,EAE9G,EAA4B,SAAW,EAAQ,wBAC/C,EAA4B,MACzB,GACC,EAAM,SAAW,EAAqB,QACtC,EAAM,OAAO,EAAM,IAAU,IAAS,EAAqB,EAAM,CACrE,EACA,CACA,EAAa,oBACb,EAAW,EACX,KACF,CACF,CAEA,GAAI,KAAK,IAAI,EAAI,IAAO,EAAmB,EAAQ,iBAAkB,CACnE,EAAa,UACb,EAAW,EACX,KACF,CACF,CAOA,GALI,IAAe,gBAAkB,EAAM,WAAa,OACtD,EAAM,mBAAmB,OAAO,EAChC,EAAM,mBAAmB,OAAO,GAElC,MAAM,EAAY,CAAK,EACnB,EAAY,MAAM,EACtB,GAAM,CACJ,cACA,OAAQ,EACR,eACE,EAAiB,EAAQ,EAAkB,CAAkB,EAEjE,MAAO,CACL,MAAO,EAAQ,MACf,OAAQ,EAAO,QAAQ,EACvB,OAAQ,EACR,OAAQ,EACR,cACA,cACA,cACA,YACF,CACF,CAEA,SAAS,EAAgB,EAAkD,CACzE,IAAM,EAAM,EAAU,CAAE,GAAG,QAAQ,IAAK,QAAS,CAAQ,EAAI,QAAQ,IAC/D,EAAWA,EAAAA,QAAa,UAAU,WAAY,CAAC,QAAS,OAAO,EAAG,CAAE,SAAU,OAAQ,KAAI,CAAC,EACjG,GAAI,EAAS,MAAO,MAAM,EAAS,MACnC,GAAI,EAAS,SAAW,GAAK,CAAC,EAAS,OAAQ,MAAO,CAAC,EAEvD,IAAM,EAAmC,CAAC,EAC1C,IAAK,IAAM,KAAY,EAAyB,EAAS,MAAM,EAAG,CAChE,IAAM,EAAaA,EAAAA,QAAa,UAAU,OAAQ,CAAC,KAAM,CAAQ,EAAG,CAAE,KAAI,CAAC,EAC3E,GAAI,EAAW,MAAO,MAAM,EAAW,MACvC,GAAI,EAAW,SAAW,GAAK,EAAW,OAAO,SAAW,EAAG,SAE/D,IAAM,EAAmBA,EAAAA,QAAa,UAAU,UAAW,CAAC,gBAAiB,CAAQ,EAAG,CAAE,SAAU,OAAQ,KAAI,CAAC,EACjH,GAAI,EAAiB,MAAO,MAAM,EAAiB,MACnD,IAAM,EAAa,EAAiB,OAAO,KAAK,CAAC,CAAC,WAAW,SAAU,GAAG,EAE1E,EAAY,KAAK,CACf,KAAM,GAAG,GAAc,SAAS,GAAG,EAAS,MAC5C,KAAM,EAAW,OAAO,SAAS,QAAQ,EACzC,SAAU,QACZ,CAAC,CACH,CAEA,OAAO,CACT,CAEA,SAAS,EAAyB,EAA0B,CAC1D,IAAM,EAAsB,CAAC,EACvB,EAAQ,EAAO,MAAM;CAAI,EAC/B,IAAK,IAAM,KAAQ,EAAO,CACxB,GAAI,EAAK,SAAS,iBAAiB,GAAK,EAAK,SAAS,mBAAmB,GAAK,EAAK,SAAS,IAAI,EAAG,SAEnG,IAAM,EAAQ,sBAAsB,KAAK,CAAI,EACxC,IAAQ,IACb,EAAU,KAAK,OAAO,SAAS,EAAM,GAAI,EAAE,CAAC,CAAC,SAAS,CAAC,CACzD,CACA,OAAO,CACT,CAEA,SAAS,EACP,EACA,EACA,EACqE,CACrE,IAAM,EAAQ,+BAA+B,KAAK,CAAM,EAClD,EAAmB,EAAQ,EAAO,MAAM,EAAG,EAAM,KAAK,CAAC,CAAC,QAAQ,EAAI,EAAO,QAAQ,EACnF,EAAoB,OAAO,IAAQ,EAAE,EAAI,MAAQ,EACvD,MAAO,CACL,OAAQ,EACR,YAAa,OAAO,IAAQ,EAAE,GAAK,KAAK,IAAI,EAAI,IAAO,EACvD,YAAa,KAAK,IAAI,EAAmB,CAAkB,CAC7D,CACF,CAEA,eAAe,GAAkF,CAC/F,GAAI,QAAQ,WAAa,QACvB,MAAU,MAAM,oDAAoD,EAGtE,IAAK,IAAI,EAAgB,GAAI,EAAgB,IAAK,IAAiB,CACjE,IAAM,EAAU,IAAI,IAChB,EACE,EAAOA,EAAAA,QAAa,MAAM,OAAQ,CAAC,EAAS,UAAW,IAAK,eAAgB,KAAK,EAAG,CACxF,MAAO,QACT,CAAC,EAMD,GALA,EAAK,GAAG,QAAU,GAAU,CAC1B,EAAa,CACf,CAAC,EAED,MAAA,EAAA,EAAA,WAAA,CAAW,GAA4B,GAAI,EACvC,EAAY,MAAM,EAClB,KAAK,WAAa,KAEtB,MAAO,CACL,UACA,QAAS,SAAY,CACd,EAAK,SACR,EAAK,KAAK,SAAS,EACnB,MAAA,EAAA,EAAA,WAAA,CAAW,GAA6B,GAAI,EACxC,EAAK,WAAa,MAAM,EAAK,KAAK,SAAS,EAEnD,CACF,CACF,CAEA,MAAU,MAAM,4BAA4B,CAC9C,CAEA,eAAe,EAAY,EAAiD,CACrE,EAAM,MACX,EAAiB,EAAM,IAAK,SAAS,EACrC,MAAA,EAAA,EAAA,WAAA,CAAW,GAAgC,GAAI,EAC3C,EAAM,WAAa,MAAM,EAAiB,EAAM,IAAK,SAAS,EACpE,CAEA,SAAS,EAA4B,EAA4C,CAC/E,GAAI,CAAC,GAAkB,QAAQ,WAAa,QAAS,MAAO,GAE5D,IAAM,EAASA,EAAAA,QAAa,UAAU,KAAM,CAAC,KAAM,OAAQ,eAAgB,WAAY,OAAO,CAAc,CAAC,EAAG,CAC9G,SAAU,MACZ,CAAC,EAGD,OAFI,EAAO,OAAS,EAAO,SAAW,GAAK,CAAC,EAAO,OAAe,EAE3D,EAAO,OACX,MAAM;CAAI,CAAC,CACX,IAAK,GAAS,OAAO,EAAK,KAAK,CAAC,CAAC,CAAC,CAClC,OAAQ,GAAU,OAAO,SAAS,CAAK,GAAK,EAAQ,CAAC,CAAC,CACtD,QAAQ,EAAK,IAAU,EAAM,EAAQ,KAAM,CAAC,CACjD,CAEA,SAAS,EAAiB,EAAwB,EAA8B,CAC9E,GAAI,CACF,GAAI,QAAQ,WAAa,QAAS,CAChC,QAAQ,KAAK,CAAC,EAAgB,CAAM,EACpC,MACF,CACF,MAAQ,CAER,CAEA,GAAI,CACF,QAAQ,KAAK,EAAgB,CAAM,CACrC,MAAQ,CAER,CACF,CAEA,eAAe,EAAW,EAAoC,CAC5D,GAAI,CAEF,OADA,MAAMC,EAAAA,QAAG,OAAO,CAAQ,EACjB,EACT,MAAQ,CACN,MAAO,EACT,CACF,CAEA,SAAS,EAAe,EAAwB,CAC9C,OAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,CAC9D"}
@@ -1,2 +1,4 @@
1
- import{asyncToGenerator as e,regenerator as n,createForOfIteratorHelper as r,objectSpread2 as t,slicedToArray as i,regeneratorValues as s,toConsumableArray as a}from"../_virtual/_rollupPluginBabelHelpers.js";import o from"node:child_process";import u from"node:fs/promises";import c from"node:os";import d from"node:path";import{setTimeout as l}from"node:timers/promises";import{z as f}from"zod";import{cleanWorkingDirectory as p,snapshotWorkingDirectory as m}from"../helpers/cleanWorkingDirectory.js";import{copyTestCaseFileInput as h}from"../helpers/copyTestCaseFileInput.js";import{findEntryPointFile as v}from"../helpers/findEntryPointFile.js";import{findLanguageDefinitionByPath as w}from"../helpers/findLanguageDefinitionByPath.js";import{judgeByStaticAnalysis as b}from"../helpers/judgeByStaticAnalysis.js";import{parseArgs as g}from"../helpers/parseArgs.js";import{printTestCaseResult as k}from"../helpers/printTestCaseResult.js";import{readOutputFiles as C}from"../helpers/readOutputFiles.js";import{readProblemMarkdownFrontMatter as I}from"../helpers/readProblemMarkdownFrontMatter.js";import{readTestCases as y}from"../helpers/readTestCases.js";import{spawnSyncWithTimeout as E}from"../helpers/spawnSyncWithTimeout.js";import{DecisionCode as R}from"../types/decisionCode.js";import{languageIdToDefinition as S}from"../types/language.js";var F=["darwin"===c.platform()?"gtime":"/usr/bin/time","--format","%e %M"],M=f.object({language:f.union([f.string(),f.array(f.string())]).optional()});function P(e,n){return _.apply(this,arguments)}function _(){return(_=e(n().m(function e(i,s){var a,o,u,c,d,l,f,y,E,S,F,P,_,T,N,U,A,G,q,X,Y,Q,H,K,V,$,J,Z,ee,ne,re,te,ie,se,ae,oe,ue,ce,de,le,fe,pe,me,he,ve,we,be,ge,ke,Ce,Ie,ye,Ee,Re,Se,Fe,Me,Pe,_e,De,Te,Le,xe,Oe,je,Ne,Be,Ue,Ae,Ge,We,qe;return n().w(function(e){for(;;)switch(e.p=e.n){case 0:if((f=g(process.argv)).cwd){e.n=1;break}throw new Error("cwd argument required");case 1:return y=M.parse(f.params),e.n=2,I(i);case 2:return E=e.v,e.n=3,(null!=(a=s.readTestCases)?a:j)(i);case 3:return S=e.v,F=S.length>0?S:[{id:"default"}],P=null!=(o=null==(u=F[0])?void 0:u.id)?o:"prebuild",e.n=4,b(f.cwd,E);case 4:if(!(_=e.v)){e.n=5;break}return k(t({testCaseId:P},_)),e.a(2);case 5:if(null==(c=s.mainFilePath)){e.n=6;break}Te=c,e.n=8;break;case 6:return e.n=7,v(f.cwd,y.language);case 7:Te=e.v;case 8:if(T=Te){e.n=9;break}return k({testCaseId:P,decisionCode:R.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,stderr:s.mainFilePath?"required main file not found: ".concat(s.mainFilePath):"main file not found".concat(y.language?": language: ".concat(y.language):"")}),e.a(2);case 9:if(N=w(T)){e.n=10;break}return k({testCaseId:P,decisionCode:R.WRONG_ANSWER,stderr:"unsupported language"}),e.a(2);case 10:return U=t(t({},process.env),{},{CI:"",FORCE_COLOR:"0"}),e.n=11,D({cwd:f.cwd,language:y.language,configuredMainFilePath:s.mainFilePath});case 11:if(A=e.v,!N.prebuild){e.n=16;break}return e.p=12,e.n=13,N.prebuild(f.cwd);case 13:return e.n=14,D({cwd:f.cwd,language:null!=(G=y.language)?G:L(T),configuredMainFilePath:s.mainFilePath,allowConfiguredPathFallback:!0});case 14:(q=e.v)&&(A=q),e.n=16;break;case 15:return e.p=15,Le=e.v,k({testCaseId:P,decisionCode:R.BUILD_ERROR,stderr:z(Le)}),e.a(2);case 16:if(A){e.n=17;break}return k({testCaseId:P,decisionCode:R.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,stderr:s.mainFilePath?"required main file not found: ".concat(s.mainFilePath):"main file not found".concat(y.language?": language: ".concat(y.language):"")}),e.a(2);case 17:return e.n=18,null==(l=s.prepare)?void 0:l.call(s,{cwd:f.cwd,env:U,mainFilePath:A,problemMarkdownFrontMatter:E});case 18:if(null==(d=e.v)){e.n=19;break}xe=d,e.n=20;break;case 19:xe=x({cwd:f.cwd,env:U,mainFilePath:A,languageDefinition:N});case 20:if(!(X=xe)){e.n=21;break}return k({testCaseId:P,decisionCode:null!=(Y=X.decisionCode)?Y:R.BUILD_ERROR,feedbackMarkdown:X.feedbackMarkdown,stderr:X.stderr,stdout:X.stdout,outputFiles:X.outputFiles}),e.a(2);case 21:return e.n=22,m(f.cwd);case 22:if(Q=e.v,K=P,e.p=23,!s.runCommand){e.n=24;break}Oe=void 0,e.n=26;break;case 24:return e.n=25,W();case 25:Oe=e.v;case 26:H=Oe,J=null==($=S.shared)?void 0:$.fileInputPath,Z=r(F),e.p=27,Z.s();case 28:if((ee=Z.n()).done){e.n=54;break}if(fe=ee.value,K=fe.id,!J){e.n=29;break}return e.n=29,h(J,f.cwd);case 29:if(!fe.fileInputPath){e.n=30;break}return e.n=30,h(fe.fileInputPath,f.cwd);case 30:return pe="number"==typeof E.timeLimitMs?E.timeLimitMs/1e3:null!=(ne=s.runTimeoutSeconds)?ne:5,me=H?t(t({},U),{},{DISPLAY:H.display}):U,e.n=31,null==(ie=s.resolveInput)?void 0:ie.call(s,{testCase:fe,cwd:f.cwd,env:me});case 31:if(null==(te=e.v)){e.n=32;break}je=te,e.n=33;break;case 32:je=fe.input;case 33:if(null==(re=je)){e.n=34;break}Ne=re,e.n=35;break;case 34:Ne="";case 35:return V=he=Ne,e.n=36,null==(ae=s.command)?void 0:ae.call(s,{testCase:fe,cwd:f.cwd,env:me,mainFilePath:A});case 36:if(null==(se=e.v)){e.n=37;break}Be=se,e.n=38;break;case 37:Be=N.command(A);case 38:if(ve=Be,we=void 0,e.p=39,!s.runCommand){e.n=41;break}return e.n=40,s.runCommand({testCase:fe,command:ve,stdin:he,cwd:f.cwd,env:me,timeLimitSeconds:pe,screenshotWaitSeconds:null!=(be=s.screenshotWaitSeconds)?be:.3,stopDetectionThreshold:null!=(ge=s.stopDetectionThreshold)?ge:5});case 40:Ue=e.v,e.n=43;break;case 41:return e.n=42,B({command:ve,stdin:he,cwd:f.cwd,env:me,timeLimitSeconds:pe,screenshotWaitSeconds:null!=(ke=s.screenshotWaitSeconds)?ke:.3,stopDetectionThreshold:null!=(Ce=s.stopDetectionThreshold)?Ce:5});case 42:Ue=e.v;case 43:we=Ue,e.n=46;break;case 44:return e.p=44,Ae=e.v,k({testCaseId:fe.id,decisionCode:R.RUNTIME_ERROR,stdin:he,stderr:z(Ae)}),e.n=45,p(f.cwd,Q);case 45:return e.a(2);case 46:return e.n=47,C(f.cwd,null!=(oe=E.requiredOutputFilePaths)?oe:[]);case 47:if(Ie=e.v,ye={timeLimitSeconds:pe,problemMarkdownFrontMatter:{memoryLimitByte:E.memoryLimitByte,requiredOutputFilePaths:E.requiredOutputFilePaths}},Ee=O({runResult:we,outputFiles:Ie,context:ye}),Re=Ee,Ee.decisionCode!==R.ACCEPTED){e.n=51;break}return e.p=48,e.n=49,s.test({testCase:fe,runResult:we,outputFiles:Ie,context:ye});case 49:Fe=e.v,Re={decisionCode:null!=(Se=Fe.decisionCode)?Se:Ee.decisionCode,feedbackMarkdown:Fe.feedbackMarkdown,stderr:Fe.stderr,stdout:Fe.stdout,outputFiles:Fe.outputFiles},e.n=51;break;case 50:e.p=50,Ge=e.v,Re={decisionCode:R.RUNTIME_ERROR,stderr:z(Ge)};case 51:return Me=null!=(ue=Re.decisionCode)?ue:R.ACCEPTED,Pe=null!=(ce=Re.stdout)?ce:we.stdout,_e=null!=(de=Re.stderr)?de:we.stderr,k({testCaseId:fe.id,decisionCode:Me,exitStatus:we.status,stdin:we.stdin||void 0,stdout:Pe||void 0,stderr:_e||void 0,timeSeconds:we.timeSeconds,memoryBytes:we.memoryBytes,feedbackMarkdown:Re.feedbackMarkdown,outputFiles:null!=(le=Re.outputFiles)?le:Ie.length>0?Ie:void 0}),e.n=52,p(f.cwd,Q);case 52:if(Me===R.ACCEPTED){e.n=53;break}return e.a(3,54);case 53:e.n=28;break;case 54:e.n=56;break;case 55:e.p=55,We=e.v,Z.e(We);case 56:return e.p=56,Z.f(),e.f(56);case 57:e.n=59;break;case 58:return e.p=58,qe=e.v,k({testCaseId:K,decisionCode:R.RUNTIME_ERROR,stdin:V,stderr:z(qe)}),e.n=59,p(f.cwd,Q);case 59:return e.p=59,e.n=60,null==(De=H)?void 0:De.dispose();case 60:return e.f(59);case 61:return e.a(2)}},e,null,[[48,50],[39,44],[27,55,56,57],[23,58,59,61],[12,15]])}))).apply(this,arguments)}function D(e){return T.apply(this,arguments)}function T(){return(T=e(n().m(function e(r){var t;return n().w(function(e){for(;;)switch(e.n){case 0:if(!r.configuredMainFilePath){e.n=3;break}return t=d.join(r.cwd,r.configuredMainFilePath),e.n=1,K(t);case 1:if(!e.v){e.n=2;break}return e.a(2,r.configuredMainFilePath);case 2:if(r.allowConfiguredPathFallback){e.n=3;break}return e.a(2,void 0);case 3:return e.n=4,v(r.cwd,r.language);case 4:return e.a(2,e.v)}},e)}))).apply(this,arguments)}function L(e){var n=Object.entries(S).filter(function(n){return i(n,2)[1].fileExtensions.some(function(n){return e.endsWith(n)})}).map(function(e){return i(e,1)[0]});return n.length>0?n:void 0}function x(e){var n,r,t=null==(n=(r=e.languageDefinition).buildCommand)?void 0:n.call(r,e.mainFilePath);if(t){var i=E(t[0],t.slice(1),{cwd:e.cwd,encoding:"utf8",env:e.env},10);return i.timeSeconds>10?{decisionCode:R.BUILD_TIME_LIMIT_EXCEEDED,stderr:i.stderr||void 0}:0!==i.status?{decisionCode:R.BUILD_ERROR,stderr:i.stderr||i.stdout||void 0}:void 0}}function O(e){var n,r,t;if("timeout"===e.runResult.stopReason)return{decisionCode:R.TIME_LIMIT_EXCEEDED,stderr:e.runResult.stderr};if(0!==e.runResult.status)return{decisionCode:R.RUNTIME_ERROR,stderr:e.runResult.stderr};if(e.runResult.memoryBytes>(null!=(n=e.context.problemMarkdownFrontMatter.memoryLimitByte)?n:Number.POSITIVE_INFINITY))return{decisionCode:R.MEMORY_LIMIT_EXCEEDED,stderr:e.runResult.stderr};var i=null!=(r=null==(t=e.context.problemMarkdownFrontMatter.requiredOutputFilePaths)?void 0:t.length)?r:0;return e.outputFiles.length<i?{decisionCode:R.MISSING_REQUIRED_OUTPUT_FILE_ERROR}:{decisionCode:R.ACCEPTED}}function j(e){return N.apply(this,arguments)}function N(){return(N=e(n().m(function e(r){return n().w(function(e){for(;;)switch(e.n){case 0:return e.n=1,y(d.join(r,"test_cases"));case 1:return e.a(2,e.v)}},e)}))).apply(this,arguments)}function B(e){return U.apply(this,arguments)}function U(){return(U=e(n().m(function e(r){var t,i,u,c,d,f,p,m,h,v,w,b,g,k,C,I;return n().w(function(e){for(;;)switch(e.n){case 0:t=["timeout",r.timeLimitSeconds.toFixed(3)].concat(F,a(r.command)),(i=o.spawn(t[0],t.slice(1),{cwd:r.cwd,env:r.env,detached:"win32"!==process.platform,stdio:["pipe","pipe","pipe"]})).stdout.setEncoding("utf8"),i.stderr.setEncoding("utf8"),u="",c="",p="process_exit",m=[],h=[],v=Date.now()/1e3,w=0,i.stdout.on("data",function(e){u+=e}),i.stderr.on("data",function(e){c+=e}),i.on("error",function(e){f=e,d=1}),i.on("close",function(e,n){return 124===e?(p="timeout",void(d=0)):n?(d=1,void(c=c?"".concat(c,"\nprocess terminated by signal: ").concat(n):"process terminated by signal: ".concat(n))):void(d=null!=e?e:1)}),r.stdin&&i.stdin.write(r.stdin),i.stdin.end(),b=n().m(function e(){var t,s;return n().w(function(e){for(;;)switch(e.n){case 0:return e.n=1,l(1e3*r.screenshotWaitSeconds);case 1:if(w=Math.max(w,Q(i.pid)),t=A(r.env.DISPLAY),!((h=t.toSorted(function(e,n){return e.data.length-n.data.length})).length>0)){e.n=2;break}if(s=h.map(function(e){return e.data}).toSorted(),m.unshift(s),m.length=Math.min(m.length,r.stopDetectionThreshold),m.length!==r.stopDetectionThreshold||!m.every(function(e){return e.length===s.length&&e.every(function(e,n){return e===s[n]})})){e.n=2;break}return p="stable_screenshot",d=0,e.a(2,0);case 2:if(!(Date.now()/1e3-v>r.timeLimitSeconds)){e.n=3;break}return p="timeout",d=0,e.a(2,0);case 3:return e.a(2)}},e)});case 1:if(void 0!==d){e.n=4;break}return e.d(s(b()),2);case 2:if(0!==e.v){e.n=3;break}return e.a(3,4);case 3:e.n=1;break;case 4:return"process_exit"!==p&&null===i.exitCode&&(i.removeAllListeners("close"),i.removeAllListeners("error")),e.n=5,X(i);case 5:if(!f){e.n=6;break}throw f;case 6:return g=G(c,v,w),k=g.memoryBytes,C=g.stderr,I=g.timeSeconds,e.a(2,{stdin:r.stdin,stdout:u.trimEnd(),stderr:C,status:d,timeSeconds:I,memoryBytes:k,screenshots:h,stopReason:p})}},e)}))).apply(this,arguments)}function A(e){var n=e?t(t({},process.env),{},{DISPLAY:e}):process.env,i=o.spawnSync("xwininfo",["-root","-tree"],{encoding:"utf8",env:n});if(i.error)throw i.error;if(0!==i.status||!i.stdout)return[];for(var s=[],a=0,u=function(e){var n,t=[],i=e.split("\n"),s=r(i);try{for(s.s();!(n=s.n()).done;){var a=n.value;if(!(a.includes("Root window id:")||a.includes("Parent window id:")||a.includes("()"))){var o=/^\s{5}(0x[\da-f]+) /.exec(a);null!=o&&o[1]&&t.push(Number.parseInt(o[1],16).toString())}}}catch(e){s.e(e)}finally{s.f()}return t}(i.stdout);a<u.length;a++){var c=u[a],d=o.spawnSync("maim",["-i",c],{env:n});if(d.error)throw d.error;if(0===d.status&&0!==d.stdout.length){var l=o.spawnSync("xdotool",["getwindowname",c],{encoding:"utf8",env:n});if(l.error)throw l.error;var f=l.stdout.trim().replaceAll(/[\s/]/g,"_");s.push({path:"".concat(f||"window","_").concat(c,".png"),data:d.stdout.toString("base64"),encoding:"base64"})}}return s}function G(e,n,r){var t=/(?:^|\n)(\d+\.\d+) (\d+)\s*$/.exec(e),i=t?e.slice(0,t.index).trimEnd():e.trimEnd(),s=1024*Number(null==t?void 0:t[2])||0;return{stderr:i,timeSeconds:Number(null==t?void 0:t[1])||Date.now()/1e3-n,memoryBytes:Math.max(s,r)}}function W(){return q.apply(this,arguments)}function q(){return q=e(n().m(function r(){var t,i,a;return n().w(function(r){for(;;)switch(r.n){case 0:if("linux"===process.platform){r.n=1;break}throw new Error("GUI screenshot capture is supported only on Linux.");case 1:t=n().m(function r(){var t,i,s;return n().w(function(r){for(;;)switch(r.n){case 0:return t=":".concat(a),(s=o.spawn("Xvfb",[t,"-screen","0","1280x1024x24","-ac"],{stdio:"ignore"})).on("error",function(e){i=e}),r.n=1,l(300);case 1:if(!i){r.n=2;break}throw i;case 2:if(null===s.exitCode){r.n=3;break}return r.a(2,0);case 3:return r.a(2,{v:{display:t,dispose:function(){var r=e(n().m(function e(){return n().w(function(e){for(;;)switch(e.n){case 0:if(s.killed){e.n=2;break}return s.kill("SIGTERM"),e.n=1,l(100);case 1:null===s.exitCode&&s.kill("SIGKILL");case 2:return e.a(2)}},e)}));return function(){return r.apply(this,arguments)}}()}})}},r)}),a=90;case 2:if(!(a<100)){r.n=6;break}return r.d(s(t()),3);case 3:if(0!==(i=r.v)){r.n=4;break}return r.a(3,5);case 4:if(!i){r.n=5;break}return r.a(2,i.v);case 5:a++,r.n=2;break;case 6:throw new Error("Xvfb could not be started.");case 7:return r.a(2)}},r)})),q.apply(this,arguments)}function X(e){return Y.apply(this,arguments)}function Y(){return(Y=e(n().m(function e(r){return n().w(function(e){for(;;)switch(e.n){case 0:if(r.pid){e.n=1;break}return e.a(2);case 1:return H(r.pid,"SIGTERM"),e.n=2,l(200);case 2:null===r.exitCode&&H(r.pid,"SIGKILL");case 3:return e.a(2)}},e)}))).apply(this,arguments)}function Q(e){if(!e||"linux"!==process.platform)return 0;var n=o.spawnSync("ps",["-o","rss=","--no-headers","--pgroup",String(e)],{encoding:"utf8"});return n.error||0!==n.status||!n.stdout?0:n.stdout.split("\n").map(function(e){return Number(e.trim())}).filter(function(e){return Number.isFinite(e)&&e>0}).reduce(function(e,n){return e+1024*n},0)}function H(e,n){try{if("win32"!==process.platform)return void process.kill(-e,n)}catch(e){}try{process.kill(e,n)}catch(e){}}function K(e){return V.apply(this,arguments)}function V(){return(V=e(n().m(function e(r){return n().w(function(e){for(;;)switch(e.p=e.n){case 0:return e.p=0,e.n=1,u.access(r);case 1:return e.a(2,!0);case 2:return e.p=2,e.v,e.a(2,!1)}},e,null,[[0,2]])}))).apply(this,arguments)}function z(e){return e instanceof Error?e.message:String(e)}export{P as guiCommandJudgePreset};
2
- //# sourceMappingURL=guiCommand.js.map
1
+ import{parseArgs as e}from"../helpers/parseArgs.js";import{printTestCaseResult as t}from"../helpers/printTestCaseResult.js";import{languageIdToDefinition as n}from"../types/language.js";import{DecisionCode as r}from"../types/decisionCode.js";import{cleanWorkingDirectory as i,snapshotWorkingDirectory as a}from"../helpers/cleanWorkingDirectory.js";import{copyTestCaseFileInput as o}from"../helpers/copyTestCaseFileInput.js";import{findEntryPointFile as s}from"../helpers/findEntryPointFile.js";import{findLanguageDefinitionByPath as c}from"../helpers/findLanguageDefinitionByPath.js";import{judgeByStaticAnalysis as l}from"../helpers/judgeByStaticAnalysis.js";import{readOutputFiles as u}from"../helpers/readOutputFiles.js";import{readProblemMarkdownFrontMatter as d}from"../helpers/readProblemMarkdownFrontMatter.js";import{readTestCases as f}from"../helpers/readTestCases.js";import{spawnSyncWithTimeout as p}from"../helpers/spawnSyncWithTimeout.js";import{z as m}from"zod";import h from"node:child_process";import g from"node:fs/promises";import _ from"node:os";import v from"node:path";import{setTimeout as y}from"node:timers/promises";const b=.3,x=[_.platform()===`darwin`?`gtime`:`/usr/bin/time`,`--format`,`%e %M`],S=m.object({language:m.union([m.string(),m.array(m.string())]).optional()});async function C(n,f){let p=e(process.argv);if(!p.cwd)throw Error(`cwd argument required`);let m=S.parse(p.params),h=await d(n),g=await(f.readTestCases??O)(n),_=g.length>0?g:[{id:`default`}],v=_[0]?.id??`prebuild`,y=await l(p.cwd,h);if(y){t({testCaseId:v,...y});return}let x=f.mainFilePath??await s(p.cwd,m.language);if(!x){t({testCaseId:v,decisionCode:r.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,stderr:f.mainFilePath?`required main file not found: ${f.mainFilePath}`:`main file not found${m.language?`: language: ${m.language}`:``}`});return}let C=c(x);if(!C){t({testCaseId:v,decisionCode:r.WRONG_ANSWER,stderr:`unsupported language`});return}let A={...process.env,CI:``,FORCE_COLOR:`0`},j=await w({cwd:p.cwd,language:m.language,configuredMainFilePath:f.mainFilePath});if(C.prebuild)try{await C.prebuild(p.cwd);let e=await w({cwd:p.cwd,language:m.language??T(x),configuredMainFilePath:f.mainFilePath,allowConfiguredPathFallback:!0});e&&(j=e)}catch(e){t({testCaseId:v,decisionCode:r.BUILD_ERROR,stderr:R(e)});return}if(!j){t({testCaseId:v,decisionCode:r.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,stderr:f.mainFilePath?`required main file not found: ${f.mainFilePath}`:`main file not found${m.language?`: language: ${m.language}`:``}`});return}let M=await f.prepare?.({cwd:p.cwd,env:A,mainFilePath:j,problemMarkdownFrontMatter:h})??E({cwd:p.cwd,env:A,mainFilePath:j,languageDefinition:C});if(M){t({testCaseId:v,decisionCode:M.decisionCode??r.BUILD_ERROR,feedbackMarkdown:M.feedbackMarkdown,stderr:M.stderr,stdout:M.stdout,outputFiles:M.outputFiles});return}let P=await a(p.cwd),F,I=v,L;try{F=f.runCommand?void 0:await N();let e=g.shared?.fileInputPath;for(let n of _){I=n.id,e&&await o(e,p.cwd),n.fileInputPath&&await o(n.fileInputPath,p.cwd);let a=typeof h.timeLimitMs==`number`?h.timeLimitMs/1e3:f.runTimeoutSeconds??5,s=F?{...A,DISPLAY:F.display}:A,c=await f.resolveInput?.({testCase:n,cwd:p.cwd,env:s})??n.input??``;L=c;let l=await f.command?.({testCase:n,cwd:p.cwd,env:s,mainFilePath:j})??C.command(j),d;try{d=f.runCommand?await f.runCommand({testCase:n,command:l,stdin:c,cwd:p.cwd,env:s,timeLimitSeconds:a,screenshotWaitSeconds:f.screenshotWaitSeconds??b,stopDetectionThreshold:f.stopDetectionThreshold??5}):await k({command:l,stdin:c,cwd:p.cwd,env:s,timeLimitSeconds:a,screenshotWaitSeconds:f.screenshotWaitSeconds??b,stopDetectionThreshold:f.stopDetectionThreshold??5})}catch(e){t({testCaseId:n.id,decisionCode:r.RUNTIME_ERROR,stdin:c,stderr:R(e)}),await i(p.cwd,P);return}let m=await u(p.cwd,h.requiredOutputFilePaths??[]),g={timeLimitSeconds:a,problemMarkdownFrontMatter:{memoryLimitByte:h.memoryLimitByte,requiredOutputFilePaths:h.requiredOutputFilePaths}},_=D({runResult:d,outputFiles:m,context:g}),v=_;if(_.decisionCode===r.ACCEPTED)try{let e=await f.test({testCase:n,runResult:d,outputFiles:m,context:g});v={decisionCode:e.decisionCode??_.decisionCode,feedbackMarkdown:e.feedbackMarkdown,stderr:e.stderr,stdout:e.stdout,outputFiles:e.outputFiles}}catch(e){v={decisionCode:r.RUNTIME_ERROR,stderr:R(e)}}let y=v.decisionCode??r.ACCEPTED,x=v.stdout??d.stdout,S=v.stderr??d.stderr;if(t({testCaseId:n.id,decisionCode:y,exitStatus:d.status,stdin:d.stdin||void 0,stdout:x||void 0,stderr:S||void 0,timeSeconds:d.timeSeconds,memoryBytes:d.memoryBytes,feedbackMarkdown:v.feedbackMarkdown,outputFiles:v.outputFiles??(m.length>0?m:void 0)}),await i(p.cwd,P),y!==r.ACCEPTED)break}}catch(e){t({testCaseId:I,decisionCode:r.RUNTIME_ERROR,stdin:L,stderr:R(e)}),await i(p.cwd,P)}finally{await F?.dispose()}}async function w(e){if(e.configuredMainFilePath){if(await L(v.join(e.cwd,e.configuredMainFilePath)))return e.configuredMainFilePath;if(!e.allowConfiguredPathFallback)return}return await s(e.cwd,e.language)}function T(e){let t=Object.entries(n).filter(([,t])=>t.fileExtensions.some(t=>e.endsWith(t))).map(([e])=>e);return t.length>0?t:void 0}function E(e){let t=e.languageDefinition.buildCommand?.(e.mainFilePath);if(!t)return;let n=p(t[0],t.slice(1),{cwd:e.cwd,encoding:`utf8`,env:e.env},10);if(n.timeSeconds>10)return{decisionCode:r.BUILD_TIME_LIMIT_EXCEEDED,stderr:n.stderr||void 0};if(n.status!==0)return{decisionCode:r.BUILD_ERROR,stderr:n.stderr||n.stdout||void 0}}function D(e){if(e.runResult.stopReason===`timeout`)return{decisionCode:r.TIME_LIMIT_EXCEEDED,stderr:e.runResult.stderr};if(e.runResult.status!==0)return{decisionCode:r.RUNTIME_ERROR,stderr:e.runResult.stderr};if(e.runResult.memoryBytes>(e.context.problemMarkdownFrontMatter.memoryLimitByte??1/0))return{decisionCode:r.MEMORY_LIMIT_EXCEEDED,stderr:e.runResult.stderr};let t=e.context.problemMarkdownFrontMatter.requiredOutputFilePaths?.length??0;return e.outputFiles.length<t?{decisionCode:r.MISSING_REQUIRED_OUTPUT_FILE_ERROR}:{decisionCode:r.ACCEPTED}}async function O(e){return await f(v.join(e,`test_cases`))}async function k(e){let t=[`timeout`,e.timeLimitSeconds.toFixed(3),...x,...e.command],n=h.spawn(t[0],t.slice(1),{cwd:e.cwd,env:e.env,detached:process.platform!==`win32`,stdio:[`pipe`,`pipe`,`pipe`]});n.stdout.setEncoding(`utf8`),n.stderr.setEncoding(`utf8`);let r=``,i=``,a,o,s=`process_exit`,c=[],l=[],u=Date.now()/1e3,d=0;for(n.stdout.on(`data`,e=>{r+=e}),n.stderr.on(`data`,e=>{i+=e}),n.on(`error`,e=>{o=e,a=1}),n.on(`close`,(e,t)=>{if(e===124){s=`timeout`,a=0;return}if(t){a=1,i=i?`${i}\nprocess terminated by signal: ${t}`:`process terminated by signal: ${t}`;return}a=e??1}),e.stdin&&n.stdin.write(e.stdin),n.stdin.end();a===void 0;){if(await y(e.screenshotWaitSeconds*1e3),d=Math.max(d,F(n.pid)),l=A(e.env.DISPLAY).toSorted((e,t)=>e.data.length-t.data.length),l.length>0){let t=l.map(e=>e.data).toSorted();if(c.unshift(t),c.length=Math.min(c.length,e.stopDetectionThreshold),c.length===e.stopDetectionThreshold&&c.every(e=>e.length===t.length&&e.every((e,n)=>e===t[n]))){s=`stable_screenshot`,a=0;break}}if(Date.now()/1e3-u>e.timeLimitSeconds){s=`timeout`,a=0;break}}if(s!==`process_exit`&&n.exitCode===null&&(n.removeAllListeners(`close`),n.removeAllListeners(`error`)),await P(n),o)throw o;let{memoryBytes:f,stderr:p,timeSeconds:m}=M(i,u,d);return{stdin:e.stdin,stdout:r.trimEnd(),stderr:p,status:a,timeSeconds:m,memoryBytes:f,screenshots:l,stopReason:s}}function A(e){let t=e?{...process.env,DISPLAY:e}:process.env,n=h.spawnSync(`xwininfo`,[`-root`,`-tree`],{encoding:`utf8`,env:t});if(n.error)throw n.error;if(n.status!==0||!n.stdout)return[];let r=[];for(let e of j(n.stdout)){let n=h.spawnSync(`maim`,[`-i`,e],{env:t});if(n.error)throw n.error;if(n.status!==0||n.stdout.length===0)continue;let i=h.spawnSync(`xdotool`,[`getwindowname`,e],{encoding:`utf8`,env:t});if(i.error)throw i.error;let a=i.stdout.trim().replaceAll(/[\s/]/g,`_`);r.push({path:`${a||`window`}_${e}.png`,data:n.stdout.toString(`base64`),encoding:`base64`})}return r}function j(e){let t=[],n=e.split(`
2
+ `);for(let e of n){if(e.includes(`Root window id:`)||e.includes(`Parent window id:`)||e.includes(`()`))continue;let n=/^\s{5}(0x[\da-f]+) /.exec(e);n?.[1]&&t.push(Number.parseInt(n[1],16).toString())}return t}function M(e,t,n){let r=/(?:^|\n)(\d+\.\d+) (\d+)\s*$/.exec(e),i=r?e.slice(0,r.index).trimEnd():e.trimEnd(),a=Number(r?.[2])*1024||0;return{stderr:i,timeSeconds:Number(r?.[1])||Date.now()/1e3-t,memoryBytes:Math.max(a,n)}}async function N(){if(process.platform!==`linux`)throw Error(`GUI screenshot capture is supported only on Linux.`);for(let e=90;e<100;e++){let t=`:${e}`,n,r=h.spawn(`Xvfb`,[t,`-screen`,`0`,`1280x1024x24`,`-ac`],{stdio:`ignore`});if(r.on(`error`,e=>{n=e}),await y(.3*1e3),n)throw n;if(r.exitCode===null)return{display:t,dispose:async()=>{r.killed||(r.kill(`SIGTERM`),await y(.1*1e3),r.exitCode===null&&r.kill(`SIGKILL`))}}}throw Error(`Xvfb could not be started.`)}async function P(e){e.pid&&(I(e.pid,`SIGTERM`),await y(.2*1e3),e.exitCode===null&&I(e.pid,`SIGKILL`))}function F(e){if(!e||process.platform!==`linux`)return 0;let t=h.spawnSync(`ps`,[`-o`,`rss=`,`--no-headers`,`--pgroup`,String(e)],{encoding:`utf8`});return t.error||t.status!==0||!t.stdout?0:t.stdout.split(`
3
+ `).map(e=>Number(e.trim())).filter(e=>Number.isFinite(e)&&e>0).reduce((e,t)=>e+t*1024,0)}function I(e,t){try{if(process.platform!==`win32`){process.kill(-e,t);return}}catch{}try{process.kill(e,t)}catch{}}async function L(e){try{return await g.access(e),!0}catch{return!1}}function R(e){return e instanceof Error?e.message:String(e)}export{C as guiCommandJudgePreset};
4
+ //# sourceMappingURL=guiCommand.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"guiCommand.js","sources":["../../src/presets/guiCommand.ts"],"sourcesContent":["import childProcess from 'node:child_process';\nimport fs from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { setTimeout as wait } from 'node:timers/promises';\n\nimport { z } from 'zod';\n\nimport { cleanWorkingDirectory, snapshotWorkingDirectory } from '../helpers/cleanWorkingDirectory.js';\nimport { copyTestCaseFileInput } from '../helpers/copyTestCaseFileInput.js';\nimport { findEntryPointFile } from '../helpers/findEntryPointFile.js';\nimport { findLanguageDefinitionByPath } from '../helpers/findLanguageDefinitionByPath.js';\nimport { judgeByStaticAnalysis } from '../helpers/judgeByStaticAnalysis.js';\nimport { parseArgs } from '../helpers/parseArgs.js';\nimport { printTestCaseResult } from '../helpers/printTestCaseResult.js';\nimport { readOutputFiles } from '../helpers/readOutputFiles.js';\nimport { readProblemMarkdownFrontMatter } from '../helpers/readProblemMarkdownFrontMatter.js';\nimport { readTestCases as readFileTestCases } from '../helpers/readTestCases.js';\nimport { spawnSyncWithTimeout } from '../helpers/spawnSyncWithTimeout.js';\nimport { DecisionCode } from '../types/decisionCode.js';\nimport { languageIdToDefinition } from '../types/language.js';\nimport type { ProblemMarkdownFrontMatter } from '../types/problem.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\nconst BUILD_TIMEOUT_SECONDS = 10;\nconst JUDGE_DEFAULT_TIMEOUT_SECONDS = 5;\nconst SCREENSHOT_WAIT_SECONDS = 0.3;\nconst XVFB_STARTUP_WAIT_SECONDS = 0.3;\nconst XVFB_SHUTDOWN_WAIT_SECONDS = 0.1;\nconst PROCESS_SHUTDOWN_WAIT_SECONDS = 0.2;\nconst STOP_DETECTION_THRESHOLD = 5;\nconst TIME_COMMAND = [os.platform() === 'darwin' ? 'gtime' : '/usr/bin/time', '--format', '%e %M'] as const;\n\nconst judgeParamsSchema = z.object({\n language: z.union([z.string(), z.array(z.string())]).optional(),\n});\n\ninterface BaseGuiTestCase {\n id: string;\n input?: string;\n fileInputPath?: string;\n}\n\nexport interface GuiScreenshotFile {\n path: string;\n data: string;\n encoding: 'base64';\n}\n\nexport interface GuiCommandRunResult {\n stdin: string;\n stdout: string;\n stderr: string;\n status: number | undefined;\n timeSeconds: number;\n memoryBytes: number;\n screenshots: GuiScreenshotFile[];\n stopReason: 'process_exit' | 'stable_screenshot' | 'timeout';\n}\n\ninterface GuiJudgeContext {\n timeLimitSeconds: number;\n problemMarkdownFrontMatter: Pick<ProblemMarkdownFrontMatter, 'memoryLimitByte' | 'requiredOutputFilePaths'>;\n}\n\ntype GuiJudgeCaseResult = Pick<\n TestCaseResult,\n 'decisionCode' | 'feedbackMarkdown' | 'stderr' | 'stdout' | 'outputFiles'\n>;\n\nexport interface GuiCommandJudgePresetOptions<TTestCase extends BaseGuiTestCase = BaseGuiTestCase> {\n mainFilePath?: string;\n runTimeoutSeconds?: number;\n screenshotWaitSeconds?: number;\n stopDetectionThreshold?: number;\n readTestCases?: (problemDir: string) => Promise<readonly TTestCase[]>;\n prepare?: (context: {\n cwd: string;\n env: NodeJS.ProcessEnv;\n mainFilePath: string;\n problemMarkdownFrontMatter: ProblemMarkdownFrontMatter;\n }) => Promise<Partial<GuiJudgeCaseResult> | undefined> | Partial<GuiJudgeCaseResult> | undefined;\n resolveInput?: (context: { testCase: TTestCase; cwd: string; env: NodeJS.ProcessEnv }) => Promise<string> | string;\n command?: (context: {\n testCase: TTestCase;\n cwd: string;\n env: NodeJS.ProcessEnv;\n mainFilePath: string;\n }) => Promise<readonly [string, ...string[]]> | readonly [string, ...string[]];\n runCommand?: (context: {\n testCase: TTestCase;\n command: readonly [string, ...string[]];\n stdin: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeLimitSeconds: number;\n screenshotWaitSeconds: number;\n stopDetectionThreshold: number;\n }) => Promise<GuiCommandRunResult> | GuiCommandRunResult;\n test: (context: {\n testCase: TTestCase;\n runResult: GuiCommandRunResult;\n outputFiles: NonNullable<TestCaseResult['outputFiles']>;\n context: GuiJudgeContext;\n }) => Promise<Partial<GuiJudgeCaseResult>> | Partial<GuiJudgeCaseResult>;\n}\n\n/**\n * A preset function for judging GUI programs by collecting screenshots while the program runs.\n *\n * Keep problem-specific logic in `prepare`, `command`, and `test`.\n *\n * @example\n * Create `judge.ts`:\n * ```ts\n * import { DecisionCode } from '@exercode/problem-utils';\n * import { guiCommandJudgePreset } from '@exercode/problem-utils/presets/guiCommand';\n *\n * await guiCommandJudgePreset(import.meta.dirname, {\n * mainFilePath: 'Main.java',\n * readTestCases: async () => [{ id: 'default' }],\n * test: ({ runResult }) => {\n * return runResult.screenshots.length > 0\n * ? { decisionCode: DecisionCode.ACCEPTED }\n * : { decisionCode: DecisionCode.WRONG_ANSWER };\n * },\n * });\n * ```\n */\nexport async function guiCommandJudgePreset<TTestCase extends BaseGuiTestCase = BaseGuiTestCase>(\n problemDir: string,\n options: GuiCommandJudgePresetOptions<TTestCase>\n): Promise<void> {\n const args = parseArgs(process.argv);\n if (!args.cwd) throw new Error('cwd argument required');\n const params = judgeParamsSchema.parse(args.params);\n\n const problemMarkdownFrontMatter = await readProblemMarkdownFrontMatter(problemDir);\n const configuredTestCases = await (options.readTestCases ?? readGuiTestCases<TTestCase>)(problemDir);\n const testCases =\n configuredTestCases.length > 0 ? configuredTestCases : ([{ id: 'default' }] as unknown as readonly TTestCase[]);\n const prebuildTestCaseId = testCases[0]?.id ?? 'prebuild';\n\n const staticAnalysisResult = await judgeByStaticAnalysis(args.cwd, problemMarkdownFrontMatter);\n if (staticAnalysisResult) {\n printTestCaseResult({ testCaseId: prebuildTestCaseId, ...staticAnalysisResult });\n return;\n }\n\n const initialMainFilePath = options.mainFilePath ?? (await findEntryPointFile(args.cwd, params.language));\n if (!initialMainFilePath) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,\n stderr: options.mainFilePath\n ? `required main file not found: ${options.mainFilePath}`\n : `main file not found${params.language ? `: language: ${params.language}` : ''}`,\n });\n return;\n }\n\n const languageDefinition = findLanguageDefinitionByPath(initialMainFilePath);\n if (!languageDefinition) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.WRONG_ANSWER,\n stderr: 'unsupported language',\n });\n return;\n }\n\n const env = { ...process.env, CI: '', FORCE_COLOR: '0' };\n\n let resolvedMainFilePath = await resolveMainFilePath({\n cwd: args.cwd,\n language: params.language,\n configuredMainFilePath: options.mainFilePath,\n });\n if (languageDefinition.prebuild) {\n try {\n await languageDefinition.prebuild(args.cwd);\n const prebuiltMainFilePath = await resolveMainFilePath({\n cwd: args.cwd,\n language: params.language ?? inferLanguageIdsByPath(initialMainFilePath),\n configuredMainFilePath: options.mainFilePath,\n allowConfiguredPathFallback: true,\n });\n if (prebuiltMainFilePath) resolvedMainFilePath = prebuiltMainFilePath;\n } catch (error) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.BUILD_ERROR,\n stderr: errorToMessage(error),\n });\n return;\n }\n }\n if (!resolvedMainFilePath) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,\n stderr: options.mainFilePath\n ? `required main file not found: ${options.mainFilePath}`\n : `main file not found${params.language ? `: language: ${params.language}` : ''}`,\n });\n return;\n }\n\n const prepareResult =\n (await options.prepare?.({\n cwd: args.cwd,\n env,\n mainFilePath: resolvedMainFilePath,\n problemMarkdownFrontMatter,\n })) ??\n runDefaultPrepare({\n cwd: args.cwd,\n env,\n mainFilePath: resolvedMainFilePath,\n languageDefinition,\n });\n if (prepareResult) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: prepareResult.decisionCode ?? DecisionCode.BUILD_ERROR,\n feedbackMarkdown: prepareResult.feedbackMarkdown,\n stderr: prepareResult.stderr,\n stdout: prepareResult.stdout,\n outputFiles: prepareResult.outputFiles,\n });\n return;\n }\n\n const cwdSnapshot = await snapshotWorkingDirectory(args.cwd);\n let displayServer: Awaited<ReturnType<typeof ensureDisplayServer>> | undefined;\n let currentTestCaseId = prebuildTestCaseId;\n let currentStdin: string | undefined;\n try {\n displayServer = options.runCommand ? undefined : await ensureDisplayServer();\n const sharedFileInputPath = (configuredTestCases as { shared?: { fileInputPath?: string } }).shared?.fileInputPath;\n for (const testCase of testCases) {\n currentTestCaseId = testCase.id;\n if (sharedFileInputPath) await copyTestCaseFileInput(sharedFileInputPath, args.cwd);\n if (testCase.fileInputPath) await copyTestCaseFileInput(testCase.fileInputPath, args.cwd);\n\n const timeLimitSeconds =\n typeof problemMarkdownFrontMatter.timeLimitMs === 'number'\n ? problemMarkdownFrontMatter.timeLimitMs / 1000\n : (options.runTimeoutSeconds ?? JUDGE_DEFAULT_TIMEOUT_SECONDS);\n\n const runEnv = displayServer ? { ...env, DISPLAY: displayServer.display } : env;\n const stdin = (await options.resolveInput?.({ testCase, cwd: args.cwd, env: runEnv })) ?? testCase.input ?? '';\n currentStdin = stdin;\n const command =\n (await options.command?.({ testCase, cwd: args.cwd, env: runEnv, mainFilePath: resolvedMainFilePath })) ??\n languageDefinition.command(resolvedMainFilePath);\n\n let runResult: GuiCommandRunResult;\n try {\n runResult = options.runCommand\n ? await options.runCommand({\n testCase,\n command,\n stdin,\n cwd: args.cwd,\n env: runEnv,\n timeLimitSeconds,\n screenshotWaitSeconds: options.screenshotWaitSeconds ?? SCREENSHOT_WAIT_SECONDS,\n stopDetectionThreshold: options.stopDetectionThreshold ?? STOP_DETECTION_THRESHOLD,\n })\n : await spawnGuiProgram({\n command,\n stdin,\n cwd: args.cwd,\n env: runEnv,\n timeLimitSeconds,\n screenshotWaitSeconds: options.screenshotWaitSeconds ?? SCREENSHOT_WAIT_SECONDS,\n stopDetectionThreshold: options.stopDetectionThreshold ?? STOP_DETECTION_THRESHOLD,\n });\n } catch (error) {\n printTestCaseResult({\n testCaseId: testCase.id,\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stdin,\n stderr: errorToMessage(error),\n });\n await cleanWorkingDirectory(args.cwd, cwdSnapshot);\n return;\n }\n\n const outputFiles = await readOutputFiles(args.cwd, problemMarkdownFrontMatter.requiredOutputFilePaths ?? []);\n const judgeContext: GuiJudgeContext = {\n timeLimitSeconds,\n problemMarkdownFrontMatter: {\n memoryLimitByte: problemMarkdownFrontMatter.memoryLimitByte,\n requiredOutputFilePaths: problemMarkdownFrontMatter.requiredOutputFilePaths,\n },\n };\n const baseJudgeResult = evaluateGuiRunResult({ runResult, outputFiles, context: judgeContext });\n let judgeResult = baseJudgeResult;\n if (baseJudgeResult.decisionCode === DecisionCode.ACCEPTED) {\n try {\n const extendedJudgeResult = await options.test({\n testCase,\n runResult,\n outputFiles,\n context: judgeContext,\n });\n judgeResult = {\n decisionCode: extendedJudgeResult.decisionCode ?? baseJudgeResult.decisionCode,\n feedbackMarkdown: extendedJudgeResult.feedbackMarkdown,\n stderr: extendedJudgeResult.stderr,\n stdout: extendedJudgeResult.stdout,\n outputFiles: extendedJudgeResult.outputFiles,\n };\n } catch (error) {\n judgeResult = {\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stderr: errorToMessage(error),\n };\n }\n }\n\n const decisionCode = judgeResult.decisionCode ?? DecisionCode.ACCEPTED;\n const stdout = judgeResult.stdout ?? runResult.stdout;\n const stderr = judgeResult.stderr ?? runResult.stderr;\n printTestCaseResult({\n testCaseId: testCase.id,\n decisionCode,\n exitStatus: runResult.status,\n stdin: runResult.stdin || undefined,\n stdout: stdout || undefined,\n stderr: stderr || undefined,\n timeSeconds: runResult.timeSeconds,\n memoryBytes: runResult.memoryBytes,\n feedbackMarkdown: judgeResult.feedbackMarkdown,\n outputFiles: judgeResult.outputFiles ?? (outputFiles.length > 0 ? outputFiles : undefined),\n });\n\n await cleanWorkingDirectory(args.cwd, cwdSnapshot);\n if (decisionCode !== DecisionCode.ACCEPTED) break;\n }\n } catch (error) {\n printTestCaseResult({\n testCaseId: currentTestCaseId,\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stdin: currentStdin,\n stderr: errorToMessage(error),\n });\n await cleanWorkingDirectory(args.cwd, cwdSnapshot);\n } finally {\n await displayServer?.dispose();\n }\n}\n\nasync function resolveMainFilePath(context: {\n cwd: string;\n language?: string | string[];\n configuredMainFilePath?: string;\n allowConfiguredPathFallback?: boolean;\n}): Promise<string | undefined> {\n if (context.configuredMainFilePath) {\n const resolvedPath = path.join(context.cwd, context.configuredMainFilePath);\n if (await pathExists(resolvedPath)) return context.configuredMainFilePath;\n if (!context.allowConfiguredPathFallback) return undefined;\n }\n\n return await findEntryPointFile(context.cwd, context.language);\n}\n\nfunction inferLanguageIdsByPath(filePath: string): string[] | undefined {\n const languageIds = Object.entries(languageIdToDefinition)\n .filter(([, definition]) => definition.fileExtensions.some((ext) => filePath.endsWith(ext)))\n .map(([languageId]) => languageId);\n return languageIds.length > 0 ? languageIds : undefined;\n}\n\nfunction runDefaultPrepare(context: {\n cwd: string;\n env: NodeJS.ProcessEnv;\n mainFilePath: string;\n languageDefinition: NonNullable<ReturnType<typeof findLanguageDefinitionByPath>>;\n}): Partial<GuiJudgeCaseResult> | undefined {\n const buildCommand = context.languageDefinition.buildCommand?.(context.mainFilePath);\n if (!buildCommand) return undefined;\n\n const buildResult = spawnSyncWithTimeout(\n buildCommand[0],\n buildCommand.slice(1),\n { cwd: context.cwd, encoding: 'utf8', env: context.env },\n BUILD_TIMEOUT_SECONDS\n );\n\n if (buildResult.timeSeconds > BUILD_TIMEOUT_SECONDS) {\n return {\n decisionCode: DecisionCode.BUILD_TIME_LIMIT_EXCEEDED,\n stderr: buildResult.stderr || undefined,\n };\n }\n\n if (buildResult.status !== 0) {\n return {\n decisionCode: DecisionCode.BUILD_ERROR,\n stderr: buildResult.stderr || buildResult.stdout || undefined,\n };\n }\n\n return undefined;\n}\n\nfunction evaluateGuiRunResult(context: {\n runResult: GuiCommandRunResult;\n outputFiles: NonNullable<TestCaseResult['outputFiles']>;\n context: GuiJudgeContext;\n}): Partial<GuiJudgeCaseResult> {\n if (context.runResult.stopReason === 'timeout') {\n return {\n decisionCode: DecisionCode.TIME_LIMIT_EXCEEDED,\n stderr: context.runResult.stderr,\n };\n }\n\n if (context.runResult.status !== 0) {\n return {\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stderr: context.runResult.stderr,\n };\n }\n\n if (\n context.runResult.memoryBytes >\n (context.context.problemMarkdownFrontMatter.memoryLimitByte ?? Number.POSITIVE_INFINITY)\n ) {\n return {\n decisionCode: DecisionCode.MEMORY_LIMIT_EXCEEDED,\n stderr: context.runResult.stderr,\n };\n }\n\n const requiredOutputFilesCount = context.context.problemMarkdownFrontMatter.requiredOutputFilePaths?.length ?? 0;\n if (context.outputFiles.length < requiredOutputFilesCount) {\n return {\n decisionCode: DecisionCode.MISSING_REQUIRED_OUTPUT_FILE_ERROR,\n };\n }\n\n return { decisionCode: DecisionCode.ACCEPTED };\n}\n\nasync function readGuiTestCases<TTestCase extends BaseGuiTestCase>(problemDir: string): Promise<readonly TTestCase[]> {\n return (await readFileTestCases(path.join(problemDir, 'test_cases'))) as unknown as readonly TTestCase[];\n}\n\nasync function spawnGuiProgram(context: {\n command: readonly [string, ...string[]];\n stdin: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeLimitSeconds: number;\n screenshotWaitSeconds: number;\n stopDetectionThreshold: number;\n}): Promise<GuiCommandRunResult> {\n const wrappedCommand = ['timeout', context.timeLimitSeconds.toFixed(3), ...TIME_COMMAND, ...context.command] as const;\n const child = childProcess.spawn(wrappedCommand[0], wrappedCommand.slice(1), {\n cwd: context.cwd,\n env: context.env,\n detached: process.platform !== 'win32',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n child.stdout.setEncoding('utf8');\n child.stderr.setEncoding('utf8');\n\n let stdout = '';\n let stderr = '';\n let exitCode: number | undefined;\n let spawnError: Error | undefined;\n let stopReason: GuiCommandRunResult['stopReason'] = 'process_exit';\n const screenshotSignaturesHistory: string[][] = [];\n let screenshots: GuiScreenshotFile[] = [];\n const startTimeSeconds = Date.now() / 1000;\n let sampledMemoryBytes = 0;\n\n child.stdout.on('data', (chunk: string) => {\n stdout += chunk;\n });\n child.stderr.on('data', (chunk: string) => {\n stderr += chunk;\n });\n child.on('error', (error) => {\n spawnError = error;\n exitCode = 1;\n });\n child.on('close', (code, signal) => {\n if (code === 124) {\n stopReason = 'timeout';\n exitCode = 0;\n return;\n }\n if (signal) {\n exitCode = 1;\n stderr = stderr\n ? `${stderr}\\nprocess terminated by signal: ${signal}`\n : `process terminated by signal: ${signal}`;\n return;\n }\n exitCode = code ?? 1;\n });\n\n if (context.stdin) child.stdin.write(context.stdin);\n child.stdin.end();\n\n while (exitCode === undefined) {\n await wait(context.screenshotWaitSeconds * 1000);\n sampledMemoryBytes = Math.max(sampledMemoryBytes, readProcessGroupMemoryBytes(child.pid));\n const currentScreenshots = takeScreenshots(context.env.DISPLAY);\n screenshots = currentScreenshots.toSorted((a, b) => a.data.length - b.data.length);\n\n if (screenshots.length > 0) {\n const screenshotSignatures = screenshots.map((file) => file.data).toSorted();\n screenshotSignaturesHistory.unshift(screenshotSignatures);\n screenshotSignaturesHistory.length = Math.min(screenshotSignaturesHistory.length, context.stopDetectionThreshold);\n if (\n screenshotSignaturesHistory.length === context.stopDetectionThreshold &&\n screenshotSignaturesHistory.every(\n (files) =>\n files.length === screenshotSignatures.length &&\n files.every((file, index) => file === screenshotSignatures[index])\n )\n ) {\n stopReason = 'stable_screenshot';\n exitCode = 0;\n break;\n }\n }\n\n if (Date.now() / 1000 - startTimeSeconds > context.timeLimitSeconds) {\n stopReason = 'timeout';\n exitCode = 0;\n break;\n }\n }\n\n if (stopReason !== 'process_exit' && child.exitCode === null) {\n child.removeAllListeners('close');\n child.removeAllListeners('error');\n }\n await stopProcess(child);\n if (spawnError) throw spawnError;\n const {\n memoryBytes,\n stderr: normalizedStderr,\n timeSeconds,\n } = parseTimedStderr(stderr, startTimeSeconds, sampledMemoryBytes);\n\n return {\n stdin: context.stdin,\n stdout: stdout.trimEnd(),\n stderr: normalizedStderr,\n status: exitCode,\n timeSeconds,\n memoryBytes,\n screenshots,\n stopReason,\n };\n}\n\nfunction takeScreenshots(display: string | undefined): GuiScreenshotFile[] {\n const env = display ? { ...process.env, DISPLAY: display } : process.env;\n const xwininfo = childProcess.spawnSync('xwininfo', ['-root', '-tree'], { encoding: 'utf8', env });\n if (xwininfo.error) throw xwininfo.error;\n if (xwininfo.status !== 0 || !xwininfo.stdout) return [];\n\n const screenshots: GuiScreenshotFile[] = [];\n for (const windowId of extractTopLevelWindowIds(xwininfo.stdout)) {\n const screenshot = childProcess.spawnSync('maim', ['-i', windowId], { env });\n if (screenshot.error) throw screenshot.error;\n if (screenshot.status !== 0 || screenshot.stdout.length === 0) continue;\n\n const windowNameResult = childProcess.spawnSync('xdotool', ['getwindowname', windowId], { encoding: 'utf8', env });\n if (windowNameResult.error) throw windowNameResult.error;\n const windowName = windowNameResult.stdout.trim().replaceAll(/[\\s/]/g, '_');\n\n screenshots.push({\n path: `${windowName || 'window'}_${windowId}.png`,\n data: screenshot.stdout.toString('base64'),\n encoding: 'base64',\n });\n }\n\n return screenshots;\n}\n\nfunction extractTopLevelWindowIds(stdout: string): string[] {\n const windowIds: string[] = [];\n const lines = stdout.split('\\n');\n for (const line of lines) {\n if (line.includes('Root window id:') || line.includes('Parent window id:') || line.includes('()')) continue;\n\n const match = /^\\s{5}(0x[\\da-f]+) /.exec(line);\n if (!match?.[1]) continue;\n windowIds.push(Number.parseInt(match[1], 16).toString());\n }\n return windowIds;\n}\n\nfunction parseTimedStderr(\n stderr: string,\n startTimeSeconds: number,\n sampledMemoryBytes: number\n): Pick<GuiCommandRunResult, 'stderr' | 'timeSeconds' | 'memoryBytes'> {\n const match = /(?:^|\\n)(\\d+\\.\\d+) (\\d+)\\s*$/.exec(stderr);\n const normalizedStderr = match ? stderr.slice(0, match.index).trimEnd() : stderr.trimEnd();\n const parsedMemoryBytes = Number(match?.[2]) * 1024 || 0;\n return {\n stderr: normalizedStderr,\n timeSeconds: Number(match?.[1]) || Date.now() / 1000 - startTimeSeconds,\n memoryBytes: Math.max(parsedMemoryBytes, sampledMemoryBytes),\n };\n}\n\nasync function ensureDisplayServer(): Promise<{ display: string; dispose: () => Promise<void> }> {\n if (process.platform !== 'linux') {\n throw new Error('GUI screenshot capture is supported only on Linux.');\n }\n\n for (let displayNumber = 90; displayNumber < 100; displayNumber++) {\n const display = `:${displayNumber}`;\n let spawnError: Error | undefined;\n const xvfb = childProcess.spawn('Xvfb', [display, '-screen', '0', '1280x1024x24', '-ac'], {\n stdio: 'ignore',\n });\n xvfb.on('error', (error) => {\n spawnError = error;\n });\n\n await wait(XVFB_STARTUP_WAIT_SECONDS * 1000);\n if (spawnError) throw spawnError;\n if (xvfb.exitCode !== null) continue;\n\n return {\n display,\n dispose: async () => {\n if (!xvfb.killed) {\n xvfb.kill('SIGTERM');\n await wait(XVFB_SHUTDOWN_WAIT_SECONDS * 1000);\n if (xvfb.exitCode === null) xvfb.kill('SIGKILL');\n }\n },\n };\n }\n\n throw new Error('Xvfb could not be started.');\n}\n\nasync function stopProcess(child: childProcess.ChildProcess): Promise<void> {\n if (!child.pid) return;\n killProcessGroup(child.pid, 'SIGTERM');\n await wait(PROCESS_SHUTDOWN_WAIT_SECONDS * 1000);\n if (child.exitCode === null) killProcessGroup(child.pid, 'SIGKILL');\n}\n\nfunction readProcessGroupMemoryBytes(processGroupId: number | undefined): number {\n if (!processGroupId || process.platform !== 'linux') return 0;\n\n const result = childProcess.spawnSync('ps', ['-o', 'rss=', '--no-headers', '--pgroup', String(processGroupId)], {\n encoding: 'utf8',\n });\n if (result.error || result.status !== 0 || !result.stdout) return 0;\n\n return result.stdout\n .split('\\n')\n .map((line) => Number(line.trim()))\n .filter((value) => Number.isFinite(value) && value > 0)\n .reduce((sum, value) => sum + value * 1024, 0);\n}\n\nfunction killProcessGroup(processGroupId: number, signal: NodeJS.Signals): void {\n try {\n if (process.platform !== 'win32') {\n process.kill(-processGroupId, signal);\n return;\n }\n } catch {\n // The process group may already be gone. Fall back to the direct PID below.\n }\n\n try {\n process.kill(processGroupId, signal);\n } catch {\n // The direct child may also already be gone.\n }\n}\n\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction errorToMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"names":["TIME_COMMAND","os","platform","judgeParamsSchema","z","object","language","union","string","array","optional","guiCommandJudgePreset","_x","_x2","_guiCommandJudgePreset","apply","this","arguments","_asyncToGenerator","_regenerator","m","_callee","problemDir","options","_options$readTestCase","_testCases$0$id","_testCases$","_options$mainFilePath","_yield$options$prepar","_options$prepare","args","params","problemMarkdownFrontMatter","configuredTestCases","testCases","prebuildTestCaseId","staticAnalysisResult","initialMainFilePath","languageDefinition","env","resolvedMainFilePath","_params$language","prebuiltMainFilePath","prepareResult","_prepareResult$decisi","cwdSnapshot","displayServer","currentTestCaseId","currentStdin","_shared","sharedFileInputPath","_iterator2","_step2","_options$runTimeoutSe","_ref5","_yield$options$resolv","_options$resolveInput","_yield$options$comman","_options$command","_problemMarkdownFront","_judgeResult$decision","_judgeResult$stdout","_judgeResult$stderr","_judgeResult$outputFi","testCase","timeLimitSeconds","runEnv","stdin","command","runResult","_options$screenshotWa","_options$stopDetectio","_options$screenshotWa2","_options$stopDetectio2","outputFiles","judgeContext","baseJudgeResult","judgeResult","_extendedJudgeResult$","extendedJudgeResult","decisionCode","stdout","stderr","_displayServer","_t","_t2","_t4","_t5","_t7","_t9","_t1","_t10","_t11","_t12","_t13","_t14","w","_context","p","n","parseArgs","process","argv","cwd","Error","parse","readProblemMarkdownFrontMatter","v","readTestCases","readGuiTestCases","length","id","judgeByStaticAnalysis","printTestCaseResult","_objectSpread","testCaseId","a","mainFilePath","findEntryPointFile","DecisionCode","MISSING_REQUIRED_SUBMISSION_FILE_ERROR","concat","findLanguageDefinitionByPath","WRONG_ANSWER","CI","FORCE_COLOR","resolveMainFilePath","configuredMainFilePath","prebuild","inferLanguageIdsByPath","allowConfiguredPathFallback","BUILD_ERROR","errorToMessage","prepare","call","runDefaultPrepare","feedbackMarkdown","snapshotWorkingDirectory","runCommand","undefined","ensureDisplayServer","shared","fileInputPath","_createForOfIteratorHelper","s","done","value","copyTestCaseFileInput","timeLimitMs","runTimeoutSeconds","DISPLAY","display","resolveInput","input","screenshotWaitSeconds","stopDetectionThreshold","spawnGuiProgram","RUNTIME_ERROR","cleanWorkingDirectory","readOutputFiles","requiredOutputFilePaths","memoryLimitByte","evaluateGuiRunResult","context","ACCEPTED","test","exitStatus","status","timeSeconds","memoryBytes","e","f","dispose","_x3","_resolveMainFilePath","_callee2","resolvedPath","_context2","path","join","pathExists","filePath","languageIds","Object","entries","languageIdToDefinition","filter","_ref","_slicedToArray","fileExtensions","some","ext","endsWith","map","_ref3","_context$languageDefi","_context$languageDefi2","buildCommand","buildResult","spawnSyncWithTimeout","slice","encoding","BUILD_TIME_LIMIT_EXCEEDED","_context$context$prob","_context$context$prob2","_context$context$prob3","stopReason","TIME_LIMIT_EXCEEDED","Number","POSITIVE_INFINITY","MEMORY_LIMIT_EXCEEDED","requiredOutputFilesCount","MISSING_REQUIRED_OUTPUT_FILE_ERROR","_x4","_readGuiTestCases","_callee3","_context3","readFileTestCases","_x5","_spawnGuiProgram","_callee4","wrappedCommand","child","exitCode","spawnError","screenshotSignaturesHistory","screenshots","startTimeSeconds","sampledMemoryBytes","_loop","_parseTimedStderr","normalizedStderr","_context5","toFixed","_toConsumableArray","childProcess","spawn","detached","stdio","setEncoding","Date","now","on","chunk","error","code","signal","write","end","currentScreenshots","screenshotSignatures","_context4","wait","Math","max","readProcessGroupMemoryBytes","pid","takeScreenshots","toSorted","b","data","file","unshift","min","every","files","index","d","_regeneratorValues","removeAllListeners","stopProcess","parseTimedStderr","trimEnd","xwininfo","spawnSync","_i","_extractTopLevelWindo","_step","windowIds","lines","split","_iterator","line","includes","match","exec","push","parseInt","toString","err","extractTopLevelWindowIds","windowId","screenshot","windowNameResult","windowName","trim","replaceAll","parsedMemoryBytes","_ensureDisplayServer","_callee6","_loop2","_ret2","displayNumber","_context8","xvfb","_context7","XVFB_STARTUP_WAIT_SECONDS","_dispose","_callee5","_context6","killed","kill","XVFB_SHUTDOWN_WAIT_SECONDS","_x6","_stopProcess","_callee7","_context9","killProcessGroup","PROCESS_SHUTDOWN_WAIT_SECONDS","processGroupId","result","String","isFinite","reduce","sum","_unused","_unused2","_x7","_pathExists","_callee8","_context0","fs","access","message"],"mappings":"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"}
1
+ {"version":3,"file":"guiCommand.js","names":["readFileTestCases","wait"],"sources":["../../src/presets/guiCommand.ts"],"sourcesContent":["import childProcess from 'node:child_process';\nimport fs from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { setTimeout as wait } from 'node:timers/promises';\n\nimport { z } from 'zod';\n\nimport { cleanWorkingDirectory, snapshotWorkingDirectory } from '../helpers/cleanWorkingDirectory.js';\nimport { copyTestCaseFileInput } from '../helpers/copyTestCaseFileInput.js';\nimport { findEntryPointFile } from '../helpers/findEntryPointFile.js';\nimport { findLanguageDefinitionByPath } from '../helpers/findLanguageDefinitionByPath.js';\nimport { judgeByStaticAnalysis } from '../helpers/judgeByStaticAnalysis.js';\nimport { parseArgs } from '../helpers/parseArgs.js';\nimport { printTestCaseResult } from '../helpers/printTestCaseResult.js';\nimport { readOutputFiles } from '../helpers/readOutputFiles.js';\nimport { readProblemMarkdownFrontMatter } from '../helpers/readProblemMarkdownFrontMatter.js';\nimport { readTestCases as readFileTestCases } from '../helpers/readTestCases.js';\nimport { spawnSyncWithTimeout } from '../helpers/spawnSyncWithTimeout.js';\nimport { DecisionCode } from '../types/decisionCode.js';\nimport { languageIdToDefinition } from '../types/language.js';\nimport type { ProblemMarkdownFrontMatter } from '../types/problem.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\nconst BUILD_TIMEOUT_SECONDS = 10;\nconst JUDGE_DEFAULT_TIMEOUT_SECONDS = 5;\nconst SCREENSHOT_WAIT_SECONDS = 0.3;\nconst XVFB_STARTUP_WAIT_SECONDS = 0.3;\nconst XVFB_SHUTDOWN_WAIT_SECONDS = 0.1;\nconst PROCESS_SHUTDOWN_WAIT_SECONDS = 0.2;\nconst STOP_DETECTION_THRESHOLD = 5;\nconst TIME_COMMAND = [os.platform() === 'darwin' ? 'gtime' : '/usr/bin/time', '--format', '%e %M'] as const;\n\nconst judgeParamsSchema = z.object({\n language: z.union([z.string(), z.array(z.string())]).optional(),\n});\n\ninterface BaseGuiTestCase {\n id: string;\n input?: string;\n fileInputPath?: string;\n}\n\nexport interface GuiScreenshotFile {\n path: string;\n data: string;\n encoding: 'base64';\n}\n\nexport interface GuiCommandRunResult {\n stdin: string;\n stdout: string;\n stderr: string;\n status: number | undefined;\n timeSeconds: number;\n memoryBytes: number;\n screenshots: GuiScreenshotFile[];\n stopReason: 'process_exit' | 'stable_screenshot' | 'timeout';\n}\n\ninterface GuiJudgeContext {\n timeLimitSeconds: number;\n problemMarkdownFrontMatter: Pick<ProblemMarkdownFrontMatter, 'memoryLimitByte' | 'requiredOutputFilePaths'>;\n}\n\ntype GuiJudgeCaseResult = Pick<\n TestCaseResult,\n 'decisionCode' | 'feedbackMarkdown' | 'stderr' | 'stdout' | 'outputFiles'\n>;\n\nexport interface GuiCommandJudgePresetOptions<TTestCase extends BaseGuiTestCase = BaseGuiTestCase> {\n mainFilePath?: string;\n runTimeoutSeconds?: number;\n screenshotWaitSeconds?: number;\n stopDetectionThreshold?: number;\n readTestCases?: (problemDir: string) => Promise<readonly TTestCase[]>;\n prepare?: (context: {\n cwd: string;\n env: NodeJS.ProcessEnv;\n mainFilePath: string;\n problemMarkdownFrontMatter: ProblemMarkdownFrontMatter;\n }) => Promise<Partial<GuiJudgeCaseResult> | undefined> | Partial<GuiJudgeCaseResult> | undefined;\n resolveInput?: (context: { testCase: TTestCase; cwd: string; env: NodeJS.ProcessEnv }) => Promise<string> | string;\n command?: (context: {\n testCase: TTestCase;\n cwd: string;\n env: NodeJS.ProcessEnv;\n mainFilePath: string;\n }) => Promise<readonly [string, ...string[]]> | readonly [string, ...string[]];\n runCommand?: (context: {\n testCase: TTestCase;\n command: readonly [string, ...string[]];\n stdin: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeLimitSeconds: number;\n screenshotWaitSeconds: number;\n stopDetectionThreshold: number;\n }) => Promise<GuiCommandRunResult> | GuiCommandRunResult;\n test: (context: {\n testCase: TTestCase;\n runResult: GuiCommandRunResult;\n outputFiles: NonNullable<TestCaseResult['outputFiles']>;\n context: GuiJudgeContext;\n }) => Promise<Partial<GuiJudgeCaseResult>> | Partial<GuiJudgeCaseResult>;\n}\n\n/**\n * A preset function for judging GUI programs by collecting screenshots while the program runs.\n *\n * Keep problem-specific logic in `prepare`, `command`, and `test`.\n *\n * @example\n * Create `judge.ts`:\n * ```ts\n * import { DecisionCode } from '@exercode/problem-utils';\n * import { guiCommandJudgePreset } from '@exercode/problem-utils/presets/guiCommand';\n *\n * await guiCommandJudgePreset(import.meta.dirname, {\n * mainFilePath: 'Main.java',\n * readTestCases: async () => [{ id: 'default' }],\n * test: ({ runResult }) => {\n * return runResult.screenshots.length > 0\n * ? { decisionCode: DecisionCode.ACCEPTED }\n * : { decisionCode: DecisionCode.WRONG_ANSWER };\n * },\n * });\n * ```\n */\nexport async function guiCommandJudgePreset<TTestCase extends BaseGuiTestCase = BaseGuiTestCase>(\n problemDir: string,\n options: GuiCommandJudgePresetOptions<TTestCase>\n): Promise<void> {\n const args = parseArgs(process.argv);\n if (!args.cwd) throw new Error('cwd argument required');\n const params = judgeParamsSchema.parse(args.params);\n\n const problemMarkdownFrontMatter = await readProblemMarkdownFrontMatter(problemDir);\n const configuredTestCases = await (options.readTestCases ?? readGuiTestCases<TTestCase>)(problemDir);\n const testCases =\n configuredTestCases.length > 0 ? configuredTestCases : ([{ id: 'default' }] as unknown as readonly TTestCase[]);\n const prebuildTestCaseId = testCases[0]?.id ?? 'prebuild';\n\n const staticAnalysisResult = await judgeByStaticAnalysis(args.cwd, problemMarkdownFrontMatter);\n if (staticAnalysisResult) {\n printTestCaseResult({ testCaseId: prebuildTestCaseId, ...staticAnalysisResult });\n return;\n }\n\n const initialMainFilePath = options.mainFilePath ?? (await findEntryPointFile(args.cwd, params.language));\n if (!initialMainFilePath) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,\n stderr: options.mainFilePath\n ? `required main file not found: ${options.mainFilePath}`\n : `main file not found${params.language ? `: language: ${params.language}` : ''}`,\n });\n return;\n }\n\n const languageDefinition = findLanguageDefinitionByPath(initialMainFilePath);\n if (!languageDefinition) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.WRONG_ANSWER,\n stderr: 'unsupported language',\n });\n return;\n }\n\n const env = { ...process.env, CI: '', FORCE_COLOR: '0' };\n\n let resolvedMainFilePath = await resolveMainFilePath({\n cwd: args.cwd,\n language: params.language,\n configuredMainFilePath: options.mainFilePath,\n });\n if (languageDefinition.prebuild) {\n try {\n await languageDefinition.prebuild(args.cwd);\n const prebuiltMainFilePath = await resolveMainFilePath({\n cwd: args.cwd,\n language: params.language ?? inferLanguageIdsByPath(initialMainFilePath),\n configuredMainFilePath: options.mainFilePath,\n allowConfiguredPathFallback: true,\n });\n if (prebuiltMainFilePath) resolvedMainFilePath = prebuiltMainFilePath;\n } catch (error) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.BUILD_ERROR,\n stderr: errorToMessage(error),\n });\n return;\n }\n }\n if (!resolvedMainFilePath) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,\n stderr: options.mainFilePath\n ? `required main file not found: ${options.mainFilePath}`\n : `main file not found${params.language ? `: language: ${params.language}` : ''}`,\n });\n return;\n }\n\n const prepareResult =\n (await options.prepare?.({\n cwd: args.cwd,\n env,\n mainFilePath: resolvedMainFilePath,\n problemMarkdownFrontMatter,\n })) ??\n runDefaultPrepare({\n cwd: args.cwd,\n env,\n mainFilePath: resolvedMainFilePath,\n languageDefinition,\n });\n if (prepareResult) {\n printTestCaseResult({\n testCaseId: prebuildTestCaseId,\n decisionCode: prepareResult.decisionCode ?? DecisionCode.BUILD_ERROR,\n feedbackMarkdown: prepareResult.feedbackMarkdown,\n stderr: prepareResult.stderr,\n stdout: prepareResult.stdout,\n outputFiles: prepareResult.outputFiles,\n });\n return;\n }\n\n const cwdSnapshot = await snapshotWorkingDirectory(args.cwd);\n let displayServer: Awaited<ReturnType<typeof ensureDisplayServer>> | undefined;\n let currentTestCaseId = prebuildTestCaseId;\n let currentStdin: string | undefined;\n try {\n displayServer = options.runCommand ? undefined : await ensureDisplayServer();\n const sharedFileInputPath = (configuredTestCases as { shared?: { fileInputPath?: string } }).shared?.fileInputPath;\n for (const testCase of testCases) {\n currentTestCaseId = testCase.id;\n if (sharedFileInputPath) await copyTestCaseFileInput(sharedFileInputPath, args.cwd);\n if (testCase.fileInputPath) await copyTestCaseFileInput(testCase.fileInputPath, args.cwd);\n\n const timeLimitSeconds =\n typeof problemMarkdownFrontMatter.timeLimitMs === 'number'\n ? problemMarkdownFrontMatter.timeLimitMs / 1000\n : (options.runTimeoutSeconds ?? JUDGE_DEFAULT_TIMEOUT_SECONDS);\n\n const runEnv = displayServer ? { ...env, DISPLAY: displayServer.display } : env;\n const stdin = (await options.resolveInput?.({ testCase, cwd: args.cwd, env: runEnv })) ?? testCase.input ?? '';\n currentStdin = stdin;\n const command =\n (await options.command?.({ testCase, cwd: args.cwd, env: runEnv, mainFilePath: resolvedMainFilePath })) ??\n languageDefinition.command(resolvedMainFilePath);\n\n let runResult: GuiCommandRunResult;\n try {\n runResult = options.runCommand\n ? await options.runCommand({\n testCase,\n command,\n stdin,\n cwd: args.cwd,\n env: runEnv,\n timeLimitSeconds,\n screenshotWaitSeconds: options.screenshotWaitSeconds ?? SCREENSHOT_WAIT_SECONDS,\n stopDetectionThreshold: options.stopDetectionThreshold ?? STOP_DETECTION_THRESHOLD,\n })\n : await spawnGuiProgram({\n command,\n stdin,\n cwd: args.cwd,\n env: runEnv,\n timeLimitSeconds,\n screenshotWaitSeconds: options.screenshotWaitSeconds ?? SCREENSHOT_WAIT_SECONDS,\n stopDetectionThreshold: options.stopDetectionThreshold ?? STOP_DETECTION_THRESHOLD,\n });\n } catch (error) {\n printTestCaseResult({\n testCaseId: testCase.id,\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stdin,\n stderr: errorToMessage(error),\n });\n await cleanWorkingDirectory(args.cwd, cwdSnapshot);\n return;\n }\n\n const outputFiles = await readOutputFiles(args.cwd, problemMarkdownFrontMatter.requiredOutputFilePaths ?? []);\n const judgeContext: GuiJudgeContext = {\n timeLimitSeconds,\n problemMarkdownFrontMatter: {\n memoryLimitByte: problemMarkdownFrontMatter.memoryLimitByte,\n requiredOutputFilePaths: problemMarkdownFrontMatter.requiredOutputFilePaths,\n },\n };\n const baseJudgeResult = evaluateGuiRunResult({ runResult, outputFiles, context: judgeContext });\n let judgeResult = baseJudgeResult;\n if (baseJudgeResult.decisionCode === DecisionCode.ACCEPTED) {\n try {\n const extendedJudgeResult = await options.test({\n testCase,\n runResult,\n outputFiles,\n context: judgeContext,\n });\n judgeResult = {\n decisionCode: extendedJudgeResult.decisionCode ?? baseJudgeResult.decisionCode,\n feedbackMarkdown: extendedJudgeResult.feedbackMarkdown,\n stderr: extendedJudgeResult.stderr,\n stdout: extendedJudgeResult.stdout,\n outputFiles: extendedJudgeResult.outputFiles,\n };\n } catch (error) {\n judgeResult = {\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stderr: errorToMessage(error),\n };\n }\n }\n\n const decisionCode = judgeResult.decisionCode ?? DecisionCode.ACCEPTED;\n const stdout = judgeResult.stdout ?? runResult.stdout;\n const stderr = judgeResult.stderr ?? runResult.stderr;\n printTestCaseResult({\n testCaseId: testCase.id,\n decisionCode,\n exitStatus: runResult.status,\n stdin: runResult.stdin || undefined,\n stdout: stdout || undefined,\n stderr: stderr || undefined,\n timeSeconds: runResult.timeSeconds,\n memoryBytes: runResult.memoryBytes,\n feedbackMarkdown: judgeResult.feedbackMarkdown,\n outputFiles: judgeResult.outputFiles ?? (outputFiles.length > 0 ? outputFiles : undefined),\n });\n\n await cleanWorkingDirectory(args.cwd, cwdSnapshot);\n if (decisionCode !== DecisionCode.ACCEPTED) break;\n }\n } catch (error) {\n printTestCaseResult({\n testCaseId: currentTestCaseId,\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stdin: currentStdin,\n stderr: errorToMessage(error),\n });\n await cleanWorkingDirectory(args.cwd, cwdSnapshot);\n } finally {\n await displayServer?.dispose();\n }\n}\n\nasync function resolveMainFilePath(context: {\n cwd: string;\n language?: string | string[];\n configuredMainFilePath?: string;\n allowConfiguredPathFallback?: boolean;\n}): Promise<string | undefined> {\n if (context.configuredMainFilePath) {\n const resolvedPath = path.join(context.cwd, context.configuredMainFilePath);\n if (await pathExists(resolvedPath)) return context.configuredMainFilePath;\n if (!context.allowConfiguredPathFallback) return undefined;\n }\n\n return await findEntryPointFile(context.cwd, context.language);\n}\n\nfunction inferLanguageIdsByPath(filePath: string): string[] | undefined {\n const languageIds = Object.entries(languageIdToDefinition)\n .filter(([, definition]) => definition.fileExtensions.some((ext) => filePath.endsWith(ext)))\n .map(([languageId]) => languageId);\n return languageIds.length > 0 ? languageIds : undefined;\n}\n\nfunction runDefaultPrepare(context: {\n cwd: string;\n env: NodeJS.ProcessEnv;\n mainFilePath: string;\n languageDefinition: NonNullable<ReturnType<typeof findLanguageDefinitionByPath>>;\n}): Partial<GuiJudgeCaseResult> | undefined {\n const buildCommand = context.languageDefinition.buildCommand?.(context.mainFilePath);\n if (!buildCommand) return undefined;\n\n const buildResult = spawnSyncWithTimeout(\n buildCommand[0],\n buildCommand.slice(1),\n { cwd: context.cwd, encoding: 'utf8', env: context.env },\n BUILD_TIMEOUT_SECONDS\n );\n\n if (buildResult.timeSeconds > BUILD_TIMEOUT_SECONDS) {\n return {\n decisionCode: DecisionCode.BUILD_TIME_LIMIT_EXCEEDED,\n stderr: buildResult.stderr || undefined,\n };\n }\n\n if (buildResult.status !== 0) {\n return {\n decisionCode: DecisionCode.BUILD_ERROR,\n stderr: buildResult.stderr || buildResult.stdout || undefined,\n };\n }\n\n return undefined;\n}\n\nfunction evaluateGuiRunResult(context: {\n runResult: GuiCommandRunResult;\n outputFiles: NonNullable<TestCaseResult['outputFiles']>;\n context: GuiJudgeContext;\n}): Partial<GuiJudgeCaseResult> {\n if (context.runResult.stopReason === 'timeout') {\n return {\n decisionCode: DecisionCode.TIME_LIMIT_EXCEEDED,\n stderr: context.runResult.stderr,\n };\n }\n\n if (context.runResult.status !== 0) {\n return {\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stderr: context.runResult.stderr,\n };\n }\n\n if (\n context.runResult.memoryBytes >\n (context.context.problemMarkdownFrontMatter.memoryLimitByte ?? Number.POSITIVE_INFINITY)\n ) {\n return {\n decisionCode: DecisionCode.MEMORY_LIMIT_EXCEEDED,\n stderr: context.runResult.stderr,\n };\n }\n\n const requiredOutputFilesCount = context.context.problemMarkdownFrontMatter.requiredOutputFilePaths?.length ?? 0;\n if (context.outputFiles.length < requiredOutputFilesCount) {\n return {\n decisionCode: DecisionCode.MISSING_REQUIRED_OUTPUT_FILE_ERROR,\n };\n }\n\n return { decisionCode: DecisionCode.ACCEPTED };\n}\n\nasync function readGuiTestCases<TTestCase extends BaseGuiTestCase>(problemDir: string): Promise<readonly TTestCase[]> {\n return (await readFileTestCases(path.join(problemDir, 'test_cases'))) as unknown as readonly TTestCase[];\n}\n\nasync function spawnGuiProgram(context: {\n command: readonly [string, ...string[]];\n stdin: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeLimitSeconds: number;\n screenshotWaitSeconds: number;\n stopDetectionThreshold: number;\n}): Promise<GuiCommandRunResult> {\n const wrappedCommand = ['timeout', context.timeLimitSeconds.toFixed(3), ...TIME_COMMAND, ...context.command] as const;\n const child = childProcess.spawn(wrappedCommand[0], wrappedCommand.slice(1), {\n cwd: context.cwd,\n env: context.env,\n detached: process.platform !== 'win32',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n child.stdout.setEncoding('utf8');\n child.stderr.setEncoding('utf8');\n\n let stdout = '';\n let stderr = '';\n let exitCode: number | undefined;\n let spawnError: Error | undefined;\n let stopReason: GuiCommandRunResult['stopReason'] = 'process_exit';\n const screenshotSignaturesHistory: string[][] = [];\n let screenshots: GuiScreenshotFile[] = [];\n const startTimeSeconds = Date.now() / 1000;\n let sampledMemoryBytes = 0;\n\n child.stdout.on('data', (chunk: string) => {\n stdout += chunk;\n });\n child.stderr.on('data', (chunk: string) => {\n stderr += chunk;\n });\n child.on('error', (error) => {\n spawnError = error;\n exitCode = 1;\n });\n child.on('close', (code, signal) => {\n if (code === 124) {\n stopReason = 'timeout';\n exitCode = 0;\n return;\n }\n if (signal) {\n exitCode = 1;\n stderr = stderr\n ? `${stderr}\\nprocess terminated by signal: ${signal}`\n : `process terminated by signal: ${signal}`;\n return;\n }\n exitCode = code ?? 1;\n });\n\n if (context.stdin) child.stdin.write(context.stdin);\n child.stdin.end();\n\n while (exitCode === undefined) {\n await wait(context.screenshotWaitSeconds * 1000);\n sampledMemoryBytes = Math.max(sampledMemoryBytes, readProcessGroupMemoryBytes(child.pid));\n const currentScreenshots = takeScreenshots(context.env.DISPLAY);\n screenshots = currentScreenshots.toSorted((a, b) => a.data.length - b.data.length);\n\n if (screenshots.length > 0) {\n const screenshotSignatures = screenshots.map((file) => file.data).toSorted();\n screenshotSignaturesHistory.unshift(screenshotSignatures);\n screenshotSignaturesHistory.length = Math.min(screenshotSignaturesHistory.length, context.stopDetectionThreshold);\n if (\n screenshotSignaturesHistory.length === context.stopDetectionThreshold &&\n screenshotSignaturesHistory.every(\n (files) =>\n files.length === screenshotSignatures.length &&\n files.every((file, index) => file === screenshotSignatures[index])\n )\n ) {\n stopReason = 'stable_screenshot';\n exitCode = 0;\n break;\n }\n }\n\n if (Date.now() / 1000 - startTimeSeconds > context.timeLimitSeconds) {\n stopReason = 'timeout';\n exitCode = 0;\n break;\n }\n }\n\n if (stopReason !== 'process_exit' && child.exitCode === null) {\n child.removeAllListeners('close');\n child.removeAllListeners('error');\n }\n await stopProcess(child);\n if (spawnError) throw spawnError;\n const {\n memoryBytes,\n stderr: normalizedStderr,\n timeSeconds,\n } = parseTimedStderr(stderr, startTimeSeconds, sampledMemoryBytes);\n\n return {\n stdin: context.stdin,\n stdout: stdout.trimEnd(),\n stderr: normalizedStderr,\n status: exitCode,\n timeSeconds,\n memoryBytes,\n screenshots,\n stopReason,\n };\n}\n\nfunction takeScreenshots(display: string | undefined): GuiScreenshotFile[] {\n const env = display ? { ...process.env, DISPLAY: display } : process.env;\n const xwininfo = childProcess.spawnSync('xwininfo', ['-root', '-tree'], { encoding: 'utf8', env });\n if (xwininfo.error) throw xwininfo.error;\n if (xwininfo.status !== 0 || !xwininfo.stdout) return [];\n\n const screenshots: GuiScreenshotFile[] = [];\n for (const windowId of extractTopLevelWindowIds(xwininfo.stdout)) {\n const screenshot = childProcess.spawnSync('maim', ['-i', windowId], { env });\n if (screenshot.error) throw screenshot.error;\n if (screenshot.status !== 0 || screenshot.stdout.length === 0) continue;\n\n const windowNameResult = childProcess.spawnSync('xdotool', ['getwindowname', windowId], { encoding: 'utf8', env });\n if (windowNameResult.error) throw windowNameResult.error;\n const windowName = windowNameResult.stdout.trim().replaceAll(/[\\s/]/g, '_');\n\n screenshots.push({\n path: `${windowName || 'window'}_${windowId}.png`,\n data: screenshot.stdout.toString('base64'),\n encoding: 'base64',\n });\n }\n\n return screenshots;\n}\n\nfunction extractTopLevelWindowIds(stdout: string): string[] {\n const windowIds: string[] = [];\n const lines = stdout.split('\\n');\n for (const line of lines) {\n if (line.includes('Root window id:') || line.includes('Parent window id:') || line.includes('()')) continue;\n\n const match = /^\\s{5}(0x[\\da-f]+) /.exec(line);\n if (!match?.[1]) continue;\n windowIds.push(Number.parseInt(match[1], 16).toString());\n }\n return windowIds;\n}\n\nfunction parseTimedStderr(\n stderr: string,\n startTimeSeconds: number,\n sampledMemoryBytes: number\n): Pick<GuiCommandRunResult, 'stderr' | 'timeSeconds' | 'memoryBytes'> {\n const match = /(?:^|\\n)(\\d+\\.\\d+) (\\d+)\\s*$/.exec(stderr);\n const normalizedStderr = match ? stderr.slice(0, match.index).trimEnd() : stderr.trimEnd();\n const parsedMemoryBytes = Number(match?.[2]) * 1024 || 0;\n return {\n stderr: normalizedStderr,\n timeSeconds: Number(match?.[1]) || Date.now() / 1000 - startTimeSeconds,\n memoryBytes: Math.max(parsedMemoryBytes, sampledMemoryBytes),\n };\n}\n\nasync function ensureDisplayServer(): Promise<{ display: string; dispose: () => Promise<void> }> {\n if (process.platform !== 'linux') {\n throw new Error('GUI screenshot capture is supported only on Linux.');\n }\n\n for (let displayNumber = 90; displayNumber < 100; displayNumber++) {\n const display = `:${displayNumber}`;\n let spawnError: Error | undefined;\n const xvfb = childProcess.spawn('Xvfb', [display, '-screen', '0', '1280x1024x24', '-ac'], {\n stdio: 'ignore',\n });\n xvfb.on('error', (error) => {\n spawnError = error;\n });\n\n await wait(XVFB_STARTUP_WAIT_SECONDS * 1000);\n if (spawnError) throw spawnError;\n if (xvfb.exitCode !== null) continue;\n\n return {\n display,\n dispose: async () => {\n if (!xvfb.killed) {\n xvfb.kill('SIGTERM');\n await wait(XVFB_SHUTDOWN_WAIT_SECONDS * 1000);\n if (xvfb.exitCode === null) xvfb.kill('SIGKILL');\n }\n },\n };\n }\n\n throw new Error('Xvfb could not be started.');\n}\n\nasync function stopProcess(child: childProcess.ChildProcess): Promise<void> {\n if (!child.pid) return;\n killProcessGroup(child.pid, 'SIGTERM');\n await wait(PROCESS_SHUTDOWN_WAIT_SECONDS * 1000);\n if (child.exitCode === null) killProcessGroup(child.pid, 'SIGKILL');\n}\n\nfunction readProcessGroupMemoryBytes(processGroupId: number | undefined): number {\n if (!processGroupId || process.platform !== 'linux') return 0;\n\n const result = childProcess.spawnSync('ps', ['-o', 'rss=', '--no-headers', '--pgroup', String(processGroupId)], {\n encoding: 'utf8',\n });\n if (result.error || result.status !== 0 || !result.stdout) return 0;\n\n return result.stdout\n .split('\\n')\n .map((line) => Number(line.trim()))\n .filter((value) => Number.isFinite(value) && value > 0)\n .reduce((sum, value) => sum + value * 1024, 0);\n}\n\nfunction killProcessGroup(processGroupId: number, signal: NodeJS.Signals): void {\n try {\n if (process.platform !== 'win32') {\n process.kill(-processGroupId, signal);\n return;\n }\n } catch {\n // The process group may already be gone. Fall back to the direct PID below.\n }\n\n try {\n process.kill(processGroupId, signal);\n } catch {\n // The direct child may also already be gone.\n }\n}\n\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction errorToMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("../_virtual/_rollupPluginBabelHelpers.cjs"),r=require("node:fs"),t=require("node:path"),s=require("@ai-sdk/amazon-bedrock"),n=require("@ai-sdk/google"),a=require("@ai-sdk/openai"),o=require("@ai-sdk/xai"),i=require("ai"),u=require("zod"),c=require("../helpers/parseArgs.cjs"),d=require("../helpers/printTestCaseResult.cjs"),l=require("../helpers/readTestCases.cjs"),p=require("../types/decisionCode.cjs"),C={bedrock:s.bedrock,google:n.google,openai:a.openai,xai:o.xai},m=u.z.object({model:u.z.string().min(1)});function f(){return(f=e.asyncToGenerator(e.regenerator().m(function s(n,a){var o,u,C,f,v,b,q,w,k,T,h,E,j,D,x,R,A,y,P,z;return e.regenerator().w(function(s){for(;;)switch(s.p=s.n){case 0:if((o=c.parseArgs(process.argv)).cwd){s.n=1;break}throw new Error("cwd argument required");case 1:return u=m.parse(o.params),s.n=2,l.readTestCases(t.join(n,"test_cases"));case 2:return C=s.v,s.n=3,r.promises.readFile(t.join(o.cwd,"prompt.txt"),"utf8");case 3:f=s.v,v=e.createForOfIteratorHelper(C),s.p=4,v.s();case 5:if((b=v.n()).done){s.n=12;break}return q=b.value,w=Date.now(),s.p=6,s.n=7,i.generateText({model:g(u.model),prompt:null!=(k=null==(T=a.buildPrompt)?void 0:T.call(a,{prompt:f,testCase:q}))?k:f.replaceAll("{input}",null!=(h=q.input)?h:"")});case 7:return E=s.v,j=E.text,D=Date.now(),A=e.objectSpread2,y={testCaseId:q.id,decisionCode:p.DecisionCode.ACCEPTED,stdin:q.input,stdout:j,timeSeconds:(D-w)/1e3},s.n=8,a.test({testCase:q,result:{output:j}});case 8:if(x=A(y,s.v),d.printTestCaseResult(x),x.decisionCode===p.DecisionCode.ACCEPTED){s.n=9;break}return s.a(3,12);case 9:s.n=11;break;case 10:return s.p=10,P=s.v,R=Date.now(),d.printTestCaseResult({testCaseId:q.id,decisionCode:p.DecisionCode.RUNTIME_ERROR,stdin:q.input,stderr:P instanceof Error?P.message:String(P),timeSeconds:(R-w)/1e3}),s.a(3,12);case 11:s.n=5;break;case 12:s.n=14;break;case 13:s.p=13,z=s.v,v.e(z);case 14:return s.p=14,v.f(),s.f(14);case 15:return s.a(2)}},s,null,[[6,10],[4,13,14,15]])}))).apply(this,arguments)}function g(r){var t,s=r.split("/"),n=e.slicedToArray(s,2),a=n[0],o=n[1];if(!a||!o)throw new Error("bad model: ".concat(r));var i=null==(t=C[a])?void 0:t.call(C,o);if(!i)throw new Error("model not found: ".concat(r));return i}exports.llmJudgePreset=function(e,r){return f.apply(this,arguments)};
2
- //# sourceMappingURL=llm.cjs.map
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("../helpers/parseArgs.cjs"),n=require("../helpers/printTestCaseResult.cjs"),r=require("../types/decisionCode.cjs"),i=require("../helpers/readTestCases.cjs");let a=require("zod"),o=require("node:path");o=e.__toESM(o,1);let s=require("node:fs");s=e.__toESM(s,1);let c=require("@ai-sdk/amazon-bedrock"),l=require("@ai-sdk/google"),u=require("@ai-sdk/openai"),d=require("@ai-sdk/xai"),f=require("ai");const p={bedrock:c.bedrock,google:l.google,openai:u.openai,xai:d.xai},m=a.z.object({model:a.z.string().min(1)});async function h(e,a){let c=t.parseArgs(process.argv);if(!c.cwd)throw Error(`cwd argument required`);let l=m.parse(c.params),u=await i.readTestCases(o.default.join(e,`test_cases`)),d=await s.default.promises.readFile(o.default.join(c.cwd,`prompt.txt`),`utf8`);for(let e of u){let t=Date.now();try{let{text:i}=await(0,f.generateText)({model:g(l.model),prompt:a.buildPrompt?.({prompt:d,testCase:e})??d.replaceAll(`{input}`,e.input??``)}),o=Date.now(),s={testCaseId:e.id,decisionCode:r.DecisionCode.ACCEPTED,stdin:e.input,stdout:i,timeSeconds:(o-t)/1e3,...await a.test({testCase:e,result:{output:i}})};if(n.printTestCaseResult(s),s.decisionCode!==r.DecisionCode.ACCEPTED)break}catch(i){let a=Date.now();n.printTestCaseResult({testCaseId:e.id,decisionCode:r.DecisionCode.RUNTIME_ERROR,stdin:e.input,stderr:i instanceof Error?i.message:String(i),timeSeconds:(a-t)/1e3});break}}}function g(e){let[t,n]=e.split(`/`);if(!t||!n)throw Error(`bad model: ${e}`);let r=p[t]?.(n);if(!r)throw Error(`model not found: ${e}`);return r}exports.llmJudgePreset=h;
2
+ //# sourceMappingURL=llm.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"llm.cjs","sources":["../../src/presets/llm.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { bedrock } from '@ai-sdk/amazon-bedrock';\nimport { google } from '@ai-sdk/google';\nimport { openai } from '@ai-sdk/openai';\nimport { xai } from '@ai-sdk/xai';\nimport type { LanguageModel, ModelMessage } from 'ai';\nimport { generateText } from 'ai';\nimport { z } from 'zod';\n\nimport { parseArgs } from '../helpers/parseArgs.js';\nimport { printTestCaseResult } from '../helpers/printTestCaseResult.js';\nimport { readTestCases } from '../helpers/readTestCases.js';\nimport { DecisionCode } from '../types/decisionCode.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\nconst PROMPT_FILENAME = 'prompt.txt';\n\nconst providerByName: Record<string, typeof bedrock | typeof google | typeof openai | typeof xai> = {\n // requires `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_REGION`\n bedrock,\n // requires `GOOGLE_GENERATIVE_AI_API_KEY`\n google,\n // requires `OPENAI_API_KEY`\n openai,\n // requires `XAI_API_KEY`\n xai,\n} as const;\n\nconst judgeParamsSchema = z.object({\n model: z.string().min(1),\n});\n\ninterface LlmJudgePresetOptions {\n buildPrompt?: (context: {\n prompt: string;\n testCase: { id: string; input?: string; output?: string };\n }) => string | ModelMessage[];\n test: (context: {\n testCase: { id: string; input?: string; output?: string };\n result: { output: string };\n }) => Partial<TestCaseResult> | Promise<Partial<TestCaseResult>>;\n}\n\n/**\n * A preset judge function for running and testing a user prompt in LLM.\n *\n * @example\n * Create `judge.ts`:\n * ```ts\n * import { llmJudgePreset } from '@exercode/problem-utils/presets/llm';\n * import { DecisionCode } from '@exercode/problem-utils';\n *\n * await llmJudgePreset(import.meta.dirname, {\n * test: (context) {\n * return { decisionCode: context.result.output ? DecisionCode.ACCEPTED : DecisionCode.WRONG_ANSWER };\n * }\n * });\n * ```\n *\n * Run with the required parameters:\n * ```bash\n * bun judge.ts model_answers/java '{ \"model\": \"gemini-2.5-flash-lite\" }'\n * ```\n */\nexport async function llmJudgePreset(problemDir: string, options: LlmJudgePresetOptions): Promise<void> {\n const args = parseArgs(process.argv);\n if (!args.cwd) throw new Error('cwd argument required');\n const params = judgeParamsSchema.parse(args.params);\n\n const testCases = await readTestCases(path.join(problemDir, 'test_cases'));\n\n const prompt = await fs.promises.readFile(path.join(args.cwd, PROMPT_FILENAME), 'utf8');\n\n for (const testCase of testCases) {\n const startTimeMilliseconds = Date.now();\n try {\n const { text } = await generateText({\n model: toLanguageModel(params.model),\n prompt: options.buildPrompt?.({ prompt, testCase }) ?? prompt.replaceAll('{input}', testCase.input ?? ''),\n });\n\n const stopTimeMilliseconds = Date.now();\n\n const testCaseResult = {\n testCaseId: testCase.id,\n decisionCode: DecisionCode.ACCEPTED,\n stdin: testCase.input,\n stdout: text,\n timeSeconds: (stopTimeMilliseconds - startTimeMilliseconds) / 1000,\n ...(await options.test({ testCase, result: { output: text } })),\n };\n\n printTestCaseResult(testCaseResult);\n\n if (testCaseResult.decisionCode !== DecisionCode.ACCEPTED) break;\n } catch (error) {\n const stopTimeMilliseconds = Date.now();\n\n printTestCaseResult({\n testCaseId: testCase.id,\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stdin: testCase.input,\n stderr: error instanceof Error ? error.message : String(error),\n timeSeconds: (stopTimeMilliseconds - startTimeMilliseconds) / 1000,\n });\n\n break;\n }\n }\n}\n\nfunction toLanguageModel(model: string): LanguageModel {\n const [providerId, modelId] = model.split('/');\n if (!providerId || !modelId) throw new Error(`bad model: ${model}`);\n const languageModel = providerByName[providerId]?.(modelId);\n if (!languageModel) throw new Error(`model not found: ${model}`);\n return languageModel;\n}\n"],"names":["providerByName","bedrock","google","openai","xai","judgeParamsSchema","z","object","model","string","min","_llmJudgePreset","_asyncToGenerator","_regenerator","m","_callee","problemDir","options","args","params","testCases","prompt","_iterator","_step","testCase","startTimeMilliseconds","_options$buildPrompt","_options$buildPrompt2","_testCase$input","_yield$generateText","text","stopTimeMilliseconds","testCaseResult","_stopTimeMilliseconds","_t","_t2","_t3","_t4","w","_context","p","n","parseArgs","process","argv","cwd","Error","parse","readTestCases","path","join","v","fs","promises","readFile","_createForOfIteratorHelper","s","done","value","Date","now","generateText","toLanguageModel","buildPrompt","call","replaceAll","input","_objectSpread","testCaseId","id","decisionCode","DecisionCode","ACCEPTED","stdin","stdout","timeSeconds","test","result","output","printTestCaseResult","a","RUNTIME_ERROR","stderr","message","String","e","f","apply","this","arguments","_providerByName$provi","_model$split","split","_model$split2","_slicedToArray","providerId","modelId","concat","languageModel","_x","_x2"],"mappings":"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"}
1
+ {"version":3,"file":"llm.cjs","names":["z","parseArgs","readTestCases","path","fs","DecisionCode"],"sources":["../../src/presets/llm.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { bedrock } from '@ai-sdk/amazon-bedrock';\nimport { google } from '@ai-sdk/google';\nimport { openai } from '@ai-sdk/openai';\nimport { xai } from '@ai-sdk/xai';\nimport type { LanguageModel, ModelMessage } from 'ai';\nimport { generateText } from 'ai';\nimport { z } from 'zod';\n\nimport { parseArgs } from '../helpers/parseArgs.js';\nimport { printTestCaseResult } from '../helpers/printTestCaseResult.js';\nimport { readTestCases } from '../helpers/readTestCases.js';\nimport { DecisionCode } from '../types/decisionCode.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\nconst PROMPT_FILENAME = 'prompt.txt';\n\nconst providerByName: Record<string, typeof bedrock | typeof google | typeof openai | typeof xai> = {\n // requires `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_REGION`\n bedrock,\n // requires `GOOGLE_GENERATIVE_AI_API_KEY`\n google,\n // requires `OPENAI_API_KEY`\n openai,\n // requires `XAI_API_KEY`\n xai,\n} as const;\n\nconst judgeParamsSchema = z.object({\n model: z.string().min(1),\n});\n\ninterface LlmJudgePresetOptions {\n buildPrompt?: (context: {\n prompt: string;\n testCase: { id: string; input?: string; output?: string };\n }) => string | ModelMessage[];\n test: (context: {\n testCase: { id: string; input?: string; output?: string };\n result: { output: string };\n }) => Partial<TestCaseResult> | Promise<Partial<TestCaseResult>>;\n}\n\n/**\n * A preset judge function for running and testing a user prompt in LLM.\n *\n * @example\n * Create `judge.ts`:\n * ```ts\n * import { llmJudgePreset } from '@exercode/problem-utils/presets/llm';\n * import { DecisionCode } from '@exercode/problem-utils';\n *\n * await llmJudgePreset(import.meta.dirname, {\n * test: (context) {\n * return { decisionCode: context.result.output ? DecisionCode.ACCEPTED : DecisionCode.WRONG_ANSWER };\n * }\n * });\n * ```\n *\n * Run with the required parameters:\n * ```bash\n * bun judge.ts model_answers/java '{ \"model\": \"gemini-2.5-flash-lite\" }'\n * ```\n */\nexport async function llmJudgePreset(problemDir: string, options: LlmJudgePresetOptions): Promise<void> {\n const args = parseArgs(process.argv);\n if (!args.cwd) throw new Error('cwd argument required');\n const params = judgeParamsSchema.parse(args.params);\n\n const testCases = await readTestCases(path.join(problemDir, 'test_cases'));\n\n const prompt = await fs.promises.readFile(path.join(args.cwd, PROMPT_FILENAME), 'utf8');\n\n for (const testCase of testCases) {\n const startTimeMilliseconds = Date.now();\n try {\n const { text } = await generateText({\n model: toLanguageModel(params.model),\n prompt: options.buildPrompt?.({ prompt, testCase }) ?? prompt.replaceAll('{input}', testCase.input ?? ''),\n });\n\n const stopTimeMilliseconds = Date.now();\n\n const testCaseResult = {\n testCaseId: testCase.id,\n decisionCode: DecisionCode.ACCEPTED,\n stdin: testCase.input,\n stdout: text,\n timeSeconds: (stopTimeMilliseconds - startTimeMilliseconds) / 1000,\n ...(await options.test({ testCase, result: { output: text } })),\n };\n\n printTestCaseResult(testCaseResult);\n\n if (testCaseResult.decisionCode !== DecisionCode.ACCEPTED) break;\n } catch (error) {\n const stopTimeMilliseconds = Date.now();\n\n printTestCaseResult({\n testCaseId: testCase.id,\n decisionCode: DecisionCode.RUNTIME_ERROR,\n stdin: testCase.input,\n stderr: error instanceof Error ? error.message : String(error),\n timeSeconds: (stopTimeMilliseconds - startTimeMilliseconds) / 1000,\n });\n\n break;\n }\n }\n}\n\nfunction toLanguageModel(model: string): LanguageModel {\n const [providerId, modelId] = model.split('/');\n if (!providerId || !modelId) throw new Error(`bad model: ${model}`);\n const languageModel = providerByName[providerId]?.(modelId);\n if (!languageModel) throw new Error(`model not found: ${model}`);\n return languageModel;\n}\n"],"mappings":"4hBAiBA,MAEM,EAA8F,CAElG,QAAA,EAAA,QAEA,OAAA,EAAA,OAEA,OAAA,EAAA,OAEA,IAAA,EAAA,GACF,EAEM,EAAoBA,EAAAA,EAAE,OAAO,CACjC,MAAOA,EAAAA,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CACzB,CAAC,EAkCD,eAAsB,EAAe,EAAoB,EAA+C,CACtG,IAAM,EAAOC,EAAAA,UAAU,QAAQ,IAAI,EACnC,GAAI,CAAC,EAAK,IAAK,MAAU,MAAM,uBAAuB,EACtD,IAAM,EAAS,EAAkB,MAAM,EAAK,MAAM,EAE5C,EAAY,MAAMC,EAAAA,cAAcC,EAAAA,QAAK,KAAK,EAAY,YAAY,CAAC,EAEnE,EAAS,MAAMC,EAAAA,QAAG,SAAS,SAASD,EAAAA,QAAK,KAAK,EAAK,IAAK,YAAe,EAAG,MAAM,EAEtF,IAAK,IAAM,KAAY,EAAW,CAChC,IAAM,EAAwB,KAAK,IAAI,EACvC,GAAI,CACF,GAAM,CAAE,QAAS,MAAA,EAAA,EAAA,aAAA,CAAmB,CAClC,MAAO,EAAgB,EAAO,KAAK,EACnC,OAAQ,EAAQ,cAAc,CAAE,SAAQ,UAAS,CAAC,GAAK,EAAO,WAAW,UAAW,EAAS,OAAS,EAAE,CAC1G,CAAC,EAEK,EAAuB,KAAK,IAAI,EAEhC,EAAiB,CACrB,WAAY,EAAS,GACrB,aAAcE,EAAAA,aAAa,SAC3B,MAAO,EAAS,MAChB,OAAQ,EACR,aAAc,EAAuB,GAAyB,IAC9D,GAAI,MAAM,EAAQ,KAAK,CAAE,WAAU,OAAQ,CAAE,OAAQ,CAAK,CAAE,CAAC,CAC/D,EAIA,GAFA,EAAA,oBAAoB,CAAc,EAE9B,EAAe,eAAiBA,EAAAA,aAAa,SAAU,KAC7D,OAAS,EAAO,CACd,IAAM,EAAuB,KAAK,IAAI,EAEtC,EAAA,oBAAoB,CAClB,WAAY,EAAS,GACrB,aAAcA,EAAAA,aAAa,cAC3B,MAAO,EAAS,MAChB,OAAQ,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAC7D,aAAc,EAAuB,GAAyB,GAChE,CAAC,EAED,KACF,CACF,CACF,CAEA,SAAS,EAAgB,EAA8B,CACrD,GAAM,CAAC,EAAY,GAAW,EAAM,MAAM,GAAG,EAC7C,GAAI,CAAC,GAAc,CAAC,EAAS,MAAU,MAAM,cAAc,GAAO,EAClE,IAAM,EAAgB,EAAe,EAAW,GAAG,CAAO,EAC1D,GAAI,CAAC,EAAe,MAAU,MAAM,oBAAoB,GAAO,EAC/D,OAAO,CACT"}
@@ -1,2 +1,2 @@
1
- import{asyncToGenerator as e,regenerator as r,objectSpread2 as o,createForOfIteratorHelper as t,slicedToArray as a}from"../_virtual/_rollupPluginBabelHelpers.js";import s from"node:fs";import n from"node:path";import{bedrock as i}from"@ai-sdk/amazon-bedrock";import{google as p}from"@ai-sdk/google";import{openai as c}from"@ai-sdk/openai";import{xai as d}from"@ai-sdk/xai";import{generateText as m}from"ai";import{z as l}from"zod";import{parseArgs as u}from"../helpers/parseArgs.js";import{printTestCaseResult as f}from"../helpers/printTestCaseResult.js";import{readTestCases as v}from"../helpers/readTestCases.js";import{DecisionCode as w}from"../types/decisionCode.js";var C={bedrock:i,google:p,openai:c,xai:d},b=l.object({model:l.string().min(1)});function g(e,r){return k.apply(this,arguments)}function k(){return(k=e(r().m(function e(a,i){var p,c,d,l,C,g,k,E,j,T,x,y,A,D,R,I,P,S,_,z;return r().w(function(e){for(;;)switch(e.p=e.n){case 0:if((p=u(process.argv)).cwd){e.n=1;break}throw new Error("cwd argument required");case 1:return c=b.parse(p.params),e.n=2,v(n.join(a,"test_cases"));case 2:return d=e.v,e.n=3,s.promises.readFile(n.join(p.cwd,"prompt.txt"),"utf8");case 3:l=e.v,C=t(d),e.p=4,C.s();case 5:if((g=C.n()).done){e.n=12;break}return k=g.value,E=Date.now(),e.p=6,e.n=7,m({model:h(c.model),prompt:null!=(j=null==(T=i.buildPrompt)?void 0:T.call(i,{prompt:l,testCase:k}))?j:l.replaceAll("{input}",null!=(x=k.input)?x:"")});case 7:return y=e.v,A=y.text,D=Date.now(),P=o,S={testCaseId:k.id,decisionCode:w.ACCEPTED,stdin:k.input,stdout:A,timeSeconds:(D-E)/1e3},e.n=8,i.test({testCase:k,result:{output:A}});case 8:if(R=P(S,e.v),f(R),R.decisionCode===w.ACCEPTED){e.n=9;break}return e.a(3,12);case 9:e.n=11;break;case 10:return e.p=10,_=e.v,I=Date.now(),f({testCaseId:k.id,decisionCode:w.RUNTIME_ERROR,stdin:k.input,stderr:_ instanceof Error?_.message:String(_),timeSeconds:(I-E)/1e3}),e.a(3,12);case 11:e.n=5;break;case 12:e.n=14;break;case 13:e.p=13,z=e.v,C.e(z);case 14:return e.p=14,C.f(),e.f(14);case 15:return e.a(2)}},e,null,[[6,10],[4,13,14,15]])}))).apply(this,arguments)}function h(e){var r,o=e.split("/"),t=a(o,2),s=t[0],n=t[1];if(!s||!n)throw new Error("bad model: ".concat(e));var i=null==(r=C[s])?void 0:r.call(C,n);if(!i)throw new Error("model not found: ".concat(e));return i}export{g as llmJudgePreset};
2
- //# sourceMappingURL=llm.js.map
1
+ import{parseArgs as e}from"../helpers/parseArgs.js";import{printTestCaseResult as t}from"../helpers/printTestCaseResult.js";import{DecisionCode as n}from"../types/decisionCode.js";import{readTestCases as r}from"../helpers/readTestCases.js";import{z as i}from"zod";import a from"node:path";import o from"node:fs";import{bedrock as s}from"@ai-sdk/amazon-bedrock";import{google as c}from"@ai-sdk/google";import{openai as l}from"@ai-sdk/openai";import{xai as u}from"@ai-sdk/xai";import{generateText as d}from"ai";const f={bedrock:s,google:c,openai:l,xai:u},p=i.object({model:i.string().min(1)});async function m(i,s){let c=e(process.argv);if(!c.cwd)throw Error(`cwd argument required`);let l=p.parse(c.params),u=await r(a.join(i,`test_cases`)),f=await o.promises.readFile(a.join(c.cwd,`prompt.txt`),`utf8`);for(let e of u){let r=Date.now();try{let{text:i}=await d({model:h(l.model),prompt:s.buildPrompt?.({prompt:f,testCase:e})??f.replaceAll(`{input}`,e.input??``)}),a=Date.now(),o={testCaseId:e.id,decisionCode:n.ACCEPTED,stdin:e.input,stdout:i,timeSeconds:(a-r)/1e3,...await s.test({testCase:e,result:{output:i}})};if(t(o),o.decisionCode!==n.ACCEPTED)break}catch(i){let a=Date.now();t({testCaseId:e.id,decisionCode:n.RUNTIME_ERROR,stdin:e.input,stderr:i instanceof Error?i.message:String(i),timeSeconds:(a-r)/1e3});break}}}function h(e){let[t,n]=e.split(`/`);if(!t||!n)throw Error(`bad model: ${e}`);let r=f[t]?.(n);if(!r)throw Error(`model not found: ${e}`);return r}export{m as llmJudgePreset};
2
+ //# sourceMappingURL=llm.js.map