@smwb/onreel-git-mcp 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tracker/tracker.const.ts","../../src/tracker/tracker.lib.ts","../../src/tracker/mapping.const.ts","../../src/tracker/http.lib.ts","../../src/tracker/ci.schema.ts","../../src/tracker/ci.lib.ts","../../src/tracker/github-ci.lib.ts","../../src/tracker/gitlab-ci.lib.ts","../../src/tracker/sourcecraft-ci.lib.ts","../../src/tracker/registry.lib.ts","../../src/tracker/pull.schema.ts","../../src/tracker/github-pull.lib.ts","../../src/tracker/github.lib.ts","../../src/tracker/gitlab-pull.lib.ts","../../src/tracker/gitlab.lib.ts","../../src/tracker/jira.lib.ts","../../src/tracker/local.lib.ts","../../src/tracker/sourcecraft-pull.lib.ts","../../src/tracker/sourcecraft.lib.ts","../../src/tracker/builtin.lib.ts","../../src/tracker/secrets.lib.ts","../../src/tracker/pull.lib.ts"],"sourcesContent":["// Константы адаптеров трекеров библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/tracker.const.ts — дословная копия; фильтры и возможности списков — свои (#14),\n// пределы лога CI — свои (#16).\nimport type { CiStatusCategory } from './ci.schema.ts';\nimport type { IssueCapabilities } from './tracker.types.ts';\n\n/** Потолок ожидания ответа внешнего трекера, мс. */\nexport const TRACKER_TIMEOUT_MS = 15_000;\n\n/** Размер страницы списка задач по умолчанию; потолок — 500 по контракту. */\nexport const TRACKER_PAGE_LIMIT_DEFAULT = 50;\n\n/** Сколько символов тела ответа трекера попадает в текст ошибки. */\nexport const TRACKER_ERROR_BODY_MAX = 300;\n\n/** Файл секретов подключений в каталоге данных host: токены трекеров по projectId, права 0600 (D-352). */\nexport const TRACKER_SECRETS_FILE = 'tracker-secrets.json';\n\n/** Автор комментариев, которые пользователь пишет в локальном трекере. */\nexport const TRACKER_LOCAL_AUTHOR = 'owner';\n\n/** Фильтры списка задач — имена полей IssueQuery; порядок — для текстов отказов. */\nexport const ISSUE_FILTERS = ['status', 'labels', 'assignee', 'author', 'search', 'createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore'] as const;\nexport type IssueFilter = (typeof ISSUE_FILTERS)[number];\n\n/** Поля сортировки задач единой модели. */\nexport const ISSUE_SORT_FIELDS = ['created', 'updated', 'priority', 'title', 'comments'] as const;\nexport type IssueSortField = (typeof ISSUE_SORT_FIELDS)[number];\n\n/** Фильтры списка комментариев — имена полей CommentQuery. */\nexport const COMMENT_FILTERS = ['updatedAfter'] as const;\nexport type CommentFilter = (typeof COMMENT_FILTERS)[number];\n\n/** Возможности трекера без раздела issues (свои трекеры потребителя): статус и страницы, комментарии по порядку. */\nexport const LEGACY_ISSUE_CAPABILITIES: IssueCapabilities = {\n list: { filters: ['status'], clientSide: ['status'], sorts: [] },\n comments: { filters: [], clientSide: [], order: ['asc'] },\n};\n\n/** Окно лога CI по умолчанию и потолок окна одного вызова, байт (D-006). */\nexport const CI_LOG_DEFAULT_BYTES = 16 * 1024;\nexport const CI_LOG_MAX_BYTES = 1024 * 1024;\n/** Потолок чтения тела лога: дальше поток обрывается, лог — truncated. */\nexport const CI_LOG_READ_MAX_BYTES = 64 * 1024 * 1024;\n/** Таймаут загрузки лога, мс: логи больше ответов API. */\nexport const CI_LOG_TIMEOUT_MS = 60_000;\n/** Сколько страниц лога SourceCraft читается за один вызов log(). */\nexport const CI_LOG_PAGES_MAX = 50;\n/** Законченные категории CI. */\nexport const CI_FINISHED_STATUSES: readonly CiStatusCategory[] = ['success', 'failed', 'canceled', 'skipped'];\n","// Чистые помощники адаптеров трекеров библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/tracker.lib.ts — дословная копия, импорт типов из среза контракта библиотеки;\n// проверка запросов списков и помощники фильтров — свои (#14).\nimport type { IssuePriority, IssueStatusCategory } from '../contract/contract.types.ts';\nimport { COMMENT_FILTERS, LEGACY_ISSUE_CAPABILITIES } from './tracker.const.ts';\nimport type { CommentCapabilities, CommentQuery, IssueCapabilities, ListCapabilities, ListSort, TrackerDefinition, TrackerFailure } from './tracker.types.ts';\n\n/** Отказ адаптера: потребитель превращает его в ошибку своего контракта (D-353). */\nexport class TrackerError extends Error {\n readonly failure: TrackerFailure;\n constructor(failure: TrackerFailure, message: string) {\n super(message);\n this.name = 'TrackerError';\n this.failure = failure;\n }\n}\n\n/** Время трекера (ISO 8601) в миллисекунды; нет или не разобралось — undefined. */\nexport function toTimestamp(value: unknown): number | undefined {\n if (typeof value !== 'string') return undefined;\n const ms = Date.parse(value);\n return Number.isFinite(ms) && ms >= 0 ? ms : undefined;\n}\n\n/** Поле, которое задано: непустая строка. */\nexport function text(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\nexport function clipText(value: string, max: number): string {\n return value.length <= max ? value : value.slice(0, max);\n}\n\n/** Строки из массива неизвестного вида: непустые строки без дублей. */\nexport function stringList(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return [...new Set(value.filter((item): item is string => typeof item === 'string' && item !== ''))];\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Категория и приоритет по таблице; нет в таблице — запасное значение. */\nexport function lookup<T>(table: Readonly<Record<string, T>>, key: unknown, fallback: T): T {\n return typeof key === 'string' && Object.hasOwn(table, key) ? (table[key] as T) : fallback;\n}\n\nexport function requireTarget(target: string | undefined, hint: string): string {\n if (target === undefined) throw new TrackerError('invalid_request', `Не задан target подключения: ${hint}.`);\n return target;\n}\n\n/** Обратная таблица: категория → первое имя статуса трекера. */\nexport function nameOf(table: Readonly<Record<string, IssueStatusCategory>>, category: IssueStatusCategory): string | undefined {\n return Object.entries(table).find(([, value]) => value === category)?.[0];\n}\n\nexport function priorityName(table: Readonly<Record<string, IssuePriority>>, priority: IssuePriority): string | undefined {\n return Object.entries(table).find(([, value]) => value === priority)?.[0];\n}\n\n/** Фильтры запроса со значением (не undefined и не пустой массив), в порядке names. */\nexport function usedFilters<F extends string>(query: Readonly<Partial<Record<F, unknown>>>, names: readonly F[]): F[] {\n return names.filter((name) => {\n const value = query[name];\n return value !== undefined && !(Array.isArray(value) && value.length === 0);\n });\n}\n\n/**\n * Проверка запроса списка по возможностям (D-004, R-002): фильтр со значением вне filters или sort.field вне sorts —\n * TrackerError('unsupported', `${subject}: фильтр ${name} не поддерживается.`); значение не той формы — invalid_request:\n * время не числом или не целое ≥ 0, пустая строка фильтра, список со строкой-пустышкой. subject — что за список:\n * 'Задачи GitHub', 'PR GitLab', 'Прогоны CI SourceCraft'.\n */\nexport function assertListQuery<F extends string, S extends string>(\n subject: string,\n capabilities: ListCapabilities<F, S>,\n query: Readonly<Partial<Record<F, unknown>>> & { readonly sort?: ListSort<S> | undefined },\n names: readonly F[],\n): void {\n const used = usedFilters(query, names);\n for (const name of used) {\n if (!capabilities.filters.includes(name)) throw new TrackerError('unsupported', `${subject}: фильтр ${name} не поддерживается.`);\n }\n const sort = query.sort;\n if (sort !== undefined && !capabilities.sorts.includes(sort.field)) {\n throw new TrackerError('unsupported', `${subject}: сортировка по ${sort.field} не поддерживается.`);\n }\n if (sort?.direction !== undefined && sort.direction !== 'asc' && sort.direction !== 'desc') {\n throw new TrackerError('invalid_request', `${subject}: направление сортировки — asc или desc.`);\n }\n // limit — поле PageQuery, а не фильтр: проверяется, когда запрос его несёт.\n const limit = (query as { readonly limit?: unknown }).limit;\n if (limit !== undefined && !(typeof limit === 'number' && Number.isSafeInteger(limit) && limit >= 1)) {\n throw new TrackerError('invalid_request', `${subject}: limit — целое число от 1.`);\n }\n for (const name of used) {\n const value = query[name];\n if (isTimeFilter(name)) {\n if (typeof value !== 'number' || !(Number.isSafeInteger(value) && value >= 0)) {\n throw new TrackerError('invalid_request', `${subject}: фильтр ${name} — время в мс, целое число от 0.`);\n }\n continue;\n }\n if (isArrayFilter(name)) {\n if (!Array.isArray(value) || value.some((item) => typeof item !== 'string' || item.trim() === '')) {\n throw new TrackerError('invalid_request', `${subject}: фильтр ${name} — список непустых строк.`);\n }\n continue;\n }\n if (value === null) continue; // null — значение фильтра: assignee null — задачи без исполнителя.\n if (typeof value === 'string') {\n if (value.trim() === '') throw new TrackerError('invalid_request', `${subject}: фильтр ${name} — пустая строка.`);\n continue;\n }\n if (Array.isArray(value)) {\n if (value.some((item) => typeof item !== 'string' || item.trim() === '')) {\n throw new TrackerError('invalid_request', `${subject}: фильтр ${name} — список непустых строк.`);\n }\n continue;\n }\n throw new TrackerError('invalid_request', `${subject}: фильтр ${name} — строка, список строк или null.`);\n }\n}\n\n/** Фильтры времени единой модели называются …After и …Before (createdAfter, updatedBefore). */\nfunction isTimeFilter(name: string): boolean {\n return name.endsWith('After') || name.endsWith('Before');\n}\n\n/** Списковые фильтры единой модели (status, labels): значение — массив строк, скалер здесь — опечатка вызова. */\nfunction isArrayFilter(name: string): boolean {\n return name === 'status' || name === 'labels';\n}\n\n/** Проверка запроса комментариев: updatedAfter вне filters или order вне capabilities.order — unsupported. */\nexport function assertCommentQuery(subject: string, capabilities: CommentCapabilities, query: CommentQuery): void {\n assertListQuery(subject, { filters: capabilities.filters, clientSide: capabilities.clientSide, sorts: [] }, query, COMMENT_FILTERS);\n if (query.order !== undefined && !capabilities.order.includes(query.order)) {\n throw new TrackerError('unsupported', `${subject}: порядок ${query.order} не поддерживается.`);\n }\n}\n\n/** Возможности задач трекера: раздел issues или LEGACY_ISSUE_CAPABILITIES. */\nexport function issueCapabilitiesOf(definition: TrackerDefinition): IssueCapabilities {\n return definition.issues ?? LEGACY_ISSUE_CAPABILITIES;\n}\n\n/** Мс единой модели → ISO 8601 UTC для параметров трекера. */\nexport function isoTime(ms: number): string {\n return new Date(ms).toISOString();\n}\n\n/** Время записи в границах [after, before] включительно; граница задана, а время неизвестно — не проходит. */\nexport function inTimeRange(value: number | undefined, after: number | undefined, before: number | undefined): boolean {\n if (after === undefined && before === undefined) return true;\n if (value === undefined) return false;\n return (after === undefined || value >= after) && (before === undefined || value <= before);\n}\n\n/** Есть ли needle (без учёта регистра) подстрокой в одном из текстов. */\nexport function containsText(texts: readonly (string | undefined)[], needle: string): boolean {\n const lower = needle.toLowerCase();\n return texts.some((value) => value !== undefined && value.toLowerCase().includes(lower));\n}\n\n/** Значение в двойных кавычках для JQL, QL SourceCraft и q поиска GitHub: экранирует \\ и \". */\nexport function quoted(value: string): string {\n return `\"${value.replace(/[\\\\\"]/g, '\\\\$&')}\"`;\n}\n\n/** Ключи таблицы сопоставления, чьё значение — одна из категорий (обратный поиск для фильтров трекера). */\nexport function keysFor<T>(table: Readonly<Record<string, T>>, values: readonly T[]): string[] {\n return Object.entries(table)\n .filter(([, value]) => values.includes(value))\n .map(([key]) => key);\n}\n","// Таблицы сопоставления статусов и приоритетов трекеров библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/mapping.const.ts — дословная копия, импорт типов из среза контракта библиотеки;\n// SOURCECRAFT_STATUS_FILTER — свой (#14); таблицы pull request-ов — свои (#15), таблицы CI — свои (#16).\nimport type { IssuePriority, IssueStatusCategory } from '../contract/contract.types.ts';\nimport type { CiEventCategory, CiStatusCategory } from './ci.schema.ts';\nimport type { PullRequestStatusCategory } from './pull.schema.ts';\n\n// Сопоставление статусов и приоритетов трекеров с единой моделью (D-351). Ключ — слаг или имя у трекера,\n// значение — категория единой модели. Не найденное в таблице: статус → `open`, приоритет не заполняется.\n\n/** SourceCraft: системные статусы. На паузе — ещё не закончено, но и не в работе: `open`. */\nexport const SOURCECRAFT_STATUSES: Readonly<Record<string, IssueStatusCategory>> = {\n open: 'open',\n paused: 'open',\n inProgress: 'in_progress',\n closed: 'done',\n declined: 'declined',\n duplicate: 'declined',\n};\n\n/** Категория → слаг статуса SourceCraft при переводе задачи. */\nexport const SOURCECRAFT_STATUS_SLUGS: Readonly<Record<IssueStatusCategory, string>> = {\n open: 'open',\n in_progress: 'inProgress',\n done: 'closed',\n declined: 'declined',\n};\n\n/** Категория → слаги статусов QL фильтра списка (`status in (…)`); QL принимает только слаги, не имена. */\nexport const SOURCECRAFT_STATUS_FILTER: Readonly<Record<IssueStatusCategory, readonly string[]>> = {\n open: ['open', 'paused'],\n in_progress: ['in_progress'],\n done: ['closed'],\n declined: ['declined', 'duplicate'],\n};\n\n/** Приоритеты SourceCraft совпадают с единой моделью по именам. */\nexport const SOURCECRAFT_PRIORITIES: Readonly<Record<string, IssuePriority>> = {\n trivial: 'trivial',\n minor: 'minor',\n normal: 'normal',\n critical: 'critical',\n blocker: 'blocker',\n};\n\n/** Jira: `statusCategory.key` статуса. */\nexport const JIRA_STATUS_CATEGORIES: Readonly<Record<string, IssueStatusCategory>> = {\n new: 'open',\n indeterminate: 'in_progress',\n done: 'done',\n};\n\n/** Jira: имена приоритетов схемы по умолчанию (регистр не важен, ключи в нижнем). */\nexport const JIRA_PRIORITIES: Readonly<Record<string, IssuePriority>> = {\n lowest: 'trivial',\n low: 'minor',\n medium: 'normal',\n high: 'critical',\n highest: 'blocker',\n};\n\n/** Категория → имя приоритета Jira при создании и правке. */\nexport const JIRA_PRIORITY_NAMES: Readonly<Record<IssuePriority, string>> = {\n trivial: 'Lowest',\n minor: 'Low',\n normal: 'Medium',\n critical: 'High',\n blocker: 'Highest',\n};\n\n/** Тип задачи Jira, который создаёт адаптер. */\nexport const JIRA_ISSUE_TYPE = 'Task';\n\n/** GitHub: причина закрытия `state_reason`. */\nexport const GITHUB_CLOSE_REASONS: Readonly<Record<string, IssueStatusCategory>> = {\n completed: 'done',\n not_planned: 'declined',\n duplicate: 'declined',\n};\n\n/** GitLab: приоритеты нет, но принято помечать задачи метками `priority::<имя>`; метка читается как приоритет. */\nexport const GITLAB_PRIORITY_LABELS: Readonly<Record<string, IssuePriority>> = {\n 'priority::trivial': 'trivial',\n 'priority::minor': 'minor',\n 'priority::normal': 'normal',\n 'priority::critical': 'critical',\n 'priority::blocker': 'blocker',\n};\n\n/** Метка GitLab, которой адаптер отмечает «в работе»: у GitLab только opened и closed. */\nexport const GITLAB_IN_PROGRESS_LABEL = 'status::in-progress';\n\n/** Метка GitHub для «в работе» — по той же причине. */\nexport const GITHUB_IN_PROGRESS_LABEL = 'in progress';\n\n/** Метки GitHub для приоритета: `priority: <имя>`. */\nexport const GITHUB_PRIORITY_LABELS: Readonly<Record<string, IssuePriority>> = {\n 'priority: trivial': 'trivial',\n 'priority: minor': 'minor',\n 'priority: normal': 'normal',\n 'priority: critical': 'critical',\n 'priority: blocker': 'blocker',\n};\n\nexport const ALL_STATUSES: readonly IssueStatusCategory[] = ['open', 'in_progress', 'done', 'declined'];\n\n// Pull request-ы (D-005): состояние у трекера → категория единой модели.\n\n/** GitLab: state MR → категория; черновик — поле draft открытого MR. locked — слияние идёт, MR ещё открыт. */\nexport const GITLAB_MERGE_REQUEST_STATES: Readonly<Record<string, PullRequestStatusCategory>> = {\n opened: 'open',\n locked: 'open',\n merged: 'merged',\n closed: 'closed',\n};\n\n/** GitLab: префикс заголовка, которым адаптер делает MR черновиком. */\nexport const GITLAB_DRAFT_PREFIX = 'Draft: ';\n\n/** GitLab: все формы префикса черновика, которые снимаются при переводе в open. */\nexport const GITLAB_DRAFT_PATTERN = /^\\s*(?:\\[draft\\]|\\(draft\\)|draft:)\\s*/i;\n\n/** SourceCraft: состояния PR. merging — слияние идёт, PR ещё открыт; discarded — закрыт без слияния. */\nexport const SOURCECRAFT_PULL_STATUSES: Readonly<Record<string, PullRequestStatusCategory>> = {\n draft: 'draft',\n open: 'open',\n merging: 'open',\n merged: 'merged',\n discarded: 'closed',\n};\n\n// Сопоставление состояний и событий CI с единой моделью (D-006). Не найденный статус — `running`: не закончено,\n// и тот, кто ждёт конца прогона, продолжает опрос. Законченный прогон GitHub с незнакомым conclusion — `failed`:\n// незнакомое не бывает зелёным.\n\n/** GitHub: status прогона, задания и шага, пока не completed. */\nexport const GITHUB_RUN_STATUSES: Readonly<Record<string, CiStatusCategory>> = {\n queued: 'queued',\n requested: 'queued',\n pending: 'queued',\n waiting: 'waiting',\n in_progress: 'running',\n};\n\n/** GitHub: conclusion при status completed; не найдено — failed. */\nexport const GITHUB_RUN_CONCLUSIONS: Readonly<Record<string, CiStatusCategory>> = {\n success: 'success',\n neutral: 'success',\n failure: 'failed',\n timed_out: 'failed',\n startup_failure: 'failed',\n cancelled: 'canceled',\n stale: 'canceled',\n skipped: 'skipped',\n action_required: 'waiting',\n};\n\n/** GitHub: event прогона; не найдено — other. */\nexport const GITHUB_RUN_EVENTS: Readonly<Record<string, CiEventCategory>> = {\n push: 'push',\n pull_request: 'pull_request',\n pull_request_target: 'pull_request',\n merge_group: 'pull_request',\n workflow_dispatch: 'manual',\n schedule: 'schedule',\n repository_dispatch: 'trigger',\n workflow_run: 'trigger',\n workflow_call: 'trigger',\n};\n\n/** GitLab: status пайплайна и задания; canceling — ещё не закончено. */\nexport const GITLAB_CI_STATUSES: Readonly<Record<string, CiStatusCategory>> = {\n created: 'queued',\n waiting_for_resource: 'queued',\n preparing: 'queued',\n pending: 'queued',\n running: 'running',\n canceling: 'running',\n waiting_for_callback: 'waiting',\n manual: 'waiting',\n scheduled: 'waiting',\n success: 'success',\n failed: 'failed',\n canceled: 'canceled',\n skipped: 'skipped',\n};\n\n/** GitLab: source пайплайна; не найдено — other. */\nexport const GITLAB_PIPELINE_SOURCES: Readonly<Record<string, CiEventCategory>> = {\n push: 'push',\n merge_request_event: 'pull_request',\n external_pull_request_event: 'pull_request',\n web: 'manual',\n api: 'manual',\n chat: 'manual',\n webide: 'manual',\n schedule: 'schedule',\n pipeline_execution_policy_schedule: 'schedule',\n trigger: 'trigger',\n pipeline: 'trigger',\n parent_pipeline: 'trigger',\n};\n\n/** SourceCraft: status прогона, workflow, задачи и куба. */\nexport const SOURCECRAFT_CI_STATUSES: Readonly<Record<string, CiStatusCategory>> = {\n created: 'queued',\n prepared: 'queued',\n processing: 'running',\n awaiting_approval: 'waiting',\n success: 'success',\n failed: 'failed',\n timeout: 'failed',\n canceled: 'canceled',\n rejected: 'canceled',\n skipped: 'skipped',\n};\n\n/** SourceCraft: event_type прогона. */\nexport const SOURCECRAFT_RUN_EVENTS: Readonly<Record<string, CiEventCategory>> = {\n push: 'push',\n pr_update: 'pull_request',\n manual: 'manual',\n restart: 'retry',\n schedule: 'schedule',\n repository_event: 'trigger',\n};\n","// JSON-запросы к REST внешних трекеров библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/http.lib.ts — дословная копия, redactSecretText — из ядра библиотеки\n// (общий redactor ядра, kernel/redact.lib.ts); отказы not_found, conflict и rate_limited — свои (#14),\n// потоковое чтение текста requestText — своё (#16).\nimport { redactSecretText } from '../kernel/redact.lib.ts';\nimport { CI_LOG_READ_MAX_BYTES, CI_LOG_TIMEOUT_MS, TRACKER_ERROR_BODY_MAX, TRACKER_TIMEOUT_MS } from './tracker.const.ts';\nimport { TrackerError } from './tracker.lib.ts';\nimport type { JsonRequest, JsonResponse, TextRequest, TextResponse } from './tracker.types.ts';\n\n// Запрос к REST внешнего трекера: JSON в обе стороны, таймаут, ошибки без токена (D-352, D-353).\n\nexport async function requestJson(url: string, request: JsonRequest): Promise<JsonResponse> {\n let response: Response;\n try {\n response = await request.fetch(url, {\n method: request.method ?? 'GET',\n headers: { accept: 'application/json', ...(request.body === undefined ? {} : { 'content-type': 'application/json' }), ...request.headers },\n ...(request.body === undefined ? {} : { body: JSON.stringify(request.body) }),\n signal: AbortSignal.timeout(TRACKER_TIMEOUT_MS),\n });\n } catch (error) {\n throw notAnswered(url, error);\n }\n const raw = await response.text();\n if (!response.ok) throw failureOf(url, response, raw, request);\n if (raw === '') return { body: undefined, headers: response.headers };\n try {\n return { body: JSON.parse(raw) as unknown, headers: response.headers };\n } catch {\n throw new TrackerError('failed', `Трекер ${hostOf(url)} вернул не JSON.`);\n }\n}\n\n/** Сколько байт тела отказа читается для текста ошибки: в него попадает не больше TRACKER_ERROR_BODY_MAX символов. */\nconst ERROR_BODY_READ_MAX = 16 * 1024;\n\n/**\n * Запрос текста (лог CI): тело читается потоком, в памяти — только окно keep после skip. head — первые keep.bytes,\n * поток отменяется, как только окно набрано; tail — последние keep.bytes в кольцевом буфере. Чтение обрывается\n * на readMax байт тела. Границы окна сдвигаются к целым символам UTF-8: начало — вперёд, конец — назад (и у тела,\n * оборванного посреди символа). Отказ — как у requestJson: missing, rate_limited, failed с телом без секретов.\n * fetch следует редиректам (302 GitHub на подписанный адрес); по спецификации fetch Authorization на чужой origin не уходит.\n */\nexport async function requestText(url: string, request: TextRequest): Promise<TextResponse> {\n const skip = request.skip ?? 0;\n const { bytes, from } = request.keep;\n const readMax = request.readMax ?? CI_LOG_READ_MAX_BYTES;\n if (![skip, bytes, readMax].every((value) => Number.isSafeInteger(value) && value >= 0)) {\n throw new TrackerError('invalid_request', 'Окно чтения текста — целые числа байт не меньше 0.');\n }\n let response: Response;\n try {\n response = await request.fetch(url, {\n method: 'GET',\n headers: { accept: request.accept ?? 'text/plain', ...request.headers },\n signal: AbortSignal.timeout(request.timeoutMs ?? CI_LOG_TIMEOUT_MS),\n });\n } catch (error) {\n throw notAnswered(url, error);\n }\n if (!response.ok) {\n const head = await readBody(url, response, { skip: 0, bytes: ERROR_BODY_READ_MAX, from: 'head', readMax: ERROR_BODY_READ_MAX });\n throw failureOf(url, response, decodeUtf8(head.window), request);\n }\n const body = await readBody(url, response, { skip, bytes, from, readMax });\n let start = Math.min(body.start, body.end);\n let end = body.end;\n let window = body.window;\n // Начало посреди символа: окно начинается со следующего целого.\n const lead = start > 0 ? leadingContinuation(window) : 0;\n // Конец посреди символа: незаконченный символ уходит в следующее окно. Тело, дочитанное до конца, тоже\n // бывает оборвано посреди символа (trace идущего задания): иначе вместо символа вышел бы U+FFFD.\n const tail = trailingPartial(window.subarray(lead));\n if (lead > 0 || tail > 0) {\n window = window.subarray(lead, window.length - tail);\n start += lead;\n end -= tail;\n }\n return { text: decodeUtf8(window), start, end, read: body.read, whole: body.whole, headers: response.headers };\n}\n\n/** Окно тела после чтения: байты [start, end) тела, сколько прочитано и дочитано ли до конца. */\ntype BodyWindow = { window: Uint8Array; start: number; end: number; read: number; whole: boolean };\n\n/**\n * Чтение тела потоком с ограниченной памятью: окно bytes после skip с нужной стороны, не дальше readMax байт тела.\n * head отменяет поток, как только увидит байт за окном; дочитанный readMax тоже отменяет поток.\n */\nasync function readBody(url: string, response: Response, window: { skip: number; bytes: number; from: 'head' | 'tail'; readMax: number }): Promise<BodyWindow> {\n const { skip, bytes, from, readMax } = window;\n const reader = response.body?.getReader();\n const kept = from === 'head' ? headBuffer(bytes) : ringBuffer(bytes);\n let read = 0;\n let whole = true;\n if (reader !== undefined) {\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n const chunk = value.subarray(0, Math.max(0, readMax - read));\n // Байт за readMax — тело длиннее потолка; за окном head — дальше читать незачем.\n const cut = chunk.length < value.length;\n const offset = Math.max(0, skip - read);\n if (offset < chunk.length) kept.push(chunk.subarray(offset));\n read += chunk.length;\n if (cut || kept.full()) {\n whole = false;\n await reader.cancel().catch(() => undefined);\n break;\n }\n }\n } catch (error) {\n await reader.cancel().catch(() => undefined);\n throw notAnswered(url, error);\n }\n }\n const data = kept.bytes();\n const start = from === 'head' ? skip : Math.max(skip, read - data.length);\n return { window: data, start, end: from === 'head' ? skip + data.length : read, read, whole };\n}\n\n/** Буфер окна чтения: push принимает байты после skip, full — окно head набрано и за ним есть байт. */\ntype WindowBuffer = { push(chunk: Uint8Array): void; full(): boolean; bytes(): Uint8Array };\n\n/** Первые capacity байт; full, как только пришёл байт сверх окна. */\nfunction headBuffer(capacity: number): WindowBuffer {\n const buffer = new Uint8Array(capacity);\n let length = 0;\n let overflow = false;\n return {\n push(chunk) {\n const room = capacity - length;\n buffer.set(chunk.subarray(0, room), length);\n length += Math.min(room, chunk.length);\n if (chunk.length > room) overflow = true;\n },\n full: () => overflow,\n bytes: () => buffer.subarray(0, length),\n };\n}\n\n/** Кольцевой буфер последних capacity байт: память не растёт с длиной тела. */\nfunction ringBuffer(capacity: number): WindowBuffer {\n const buffer = new Uint8Array(capacity);\n let next = 0;\n let length = 0;\n return {\n push(chunk) {\n if (capacity === 0) return;\n const part = chunk.subarray(Math.max(0, chunk.length - capacity));\n const first = Math.min(part.length, capacity - next);\n buffer.set(part.subarray(0, first), next);\n buffer.set(part.subarray(first), 0);\n next = (next + part.length) % capacity;\n length = Math.min(capacity, length + part.length);\n },\n full: () => false,\n bytes() {\n if (length < capacity) return buffer.subarray(0, length);\n const ordered = new Uint8Array(capacity);\n ordered.set(buffer.subarray(next), 0);\n ordered.set(buffer.subarray(0, next), capacity - next);\n return ordered;\n },\n };\n}\n\n/** Сколько байт продолжения UTF-8 (10xxxxxx) в начале окна: хвост символа, начатого до окна (не больше 3). */\nfunction leadingContinuation(window: Uint8Array): number {\n let count = 0;\n while (count < 3 && count < window.length && ((window[count] ?? 0) & 0xc0) === 0x80) count += 1;\n return count;\n}\n\n/** Сколько байт в конце окна — начало символа UTF-8, который в окно целиком не вошёл. */\nfunction trailingPartial(window: Uint8Array): number {\n for (let back = 1; back <= Math.min(4, window.length); back += 1) {\n const byte = window[window.length - back] ?? 0;\n if ((byte & 0xc0) === 0x80) continue;\n const length = byte >= 0xf0 ? 4 : byte >= 0xe0 ? 3 : byte >= 0xc0 ? 2 : 1;\n return length > back ? back : 0;\n }\n return 0;\n}\n\nfunction decodeUtf8(bytes: Uint8Array): string {\n return new TextDecoder('utf-8').decode(bytes);\n}\n\n/** Сеть, таймаут или обрыв тела: failed без секретов. */\nfunction notAnswered(url: string, error: unknown): TrackerError {\n return new TrackerError('failed', redactSecretText(`Трекер не ответил (${hostOf(url)}): ${error instanceof Error ? error.message : String(error)}`));\n}\n\n/**\n * Отказ по ответу не 2xx, по порядку: 404 с missing или missingIsIssue, статус из conflictOn — conflict,\n * 429, а также 403 с x-ratelimit-remaining: 0 или retry-after — rate_limited (retry-after без исчерпанного\n * лимита — вторичный лимит частоты GitHub), иначе failed. Тело ответа — без секретов и не длиннее потолка.\n */\nfunction failureOf(url: string, response: Response, raw: string, request: Pick<JsonRequest, 'missing' | 'missingIsIssue' | 'conflictOn'>): TrackerError {\n const status = response.status;\n if (status === 404 && request.missing !== undefined) return new TrackerError(request.missing.failure, request.missing.message);\n if (status === 404 && request.missingIsIssue === true) return new TrackerError('unknown_issue', 'Задача не найдена в трекере.');\n const detail = redactSecretText(raw.replace(/\\s+/g, ' ').trim()).slice(0, TRACKER_ERROR_BODY_MAX);\n const answered = `Трекер ${hostOf(url)} ответил ${String(status)}${detail === '' ? '' : `: ${detail}`}.`;\n if (request.conflictOn?.includes(status) === true) return new TrackerError('conflict', answered);\n const secondaryLimit = status === 403 && (response.headers.get('x-ratelimit-remaining')?.trim() === '0' || retryAfterOf(response.headers.get('retry-after')?.trim(), Date.now()) !== undefined);\n if (status === 429 || secondaryLimit) {\n const delay = retryDelayOf(response.headers);\n return new TrackerError('rate_limited', `Трекер ${hostOf(url)} ограничил частоту запросов${delay === undefined ? '' : `, повтор через ${String(delay)} с`}.`);\n }\n return new TrackerError('failed', answered);\n}\n\n/**\n * Через сколько секунд повторить: retry-after (секунды или HTTP-дата), иначе x-ratelimit-reset (GitHub, epoch секунд),\n * иначе ratelimit-reset (GitLab); не разобралось — undefined.\n */\nfunction retryDelayOf(headers: Headers, now: number = Date.now()): number | undefined {\n const retryAfter = retryAfterOf(headers.get('retry-after')?.trim(), now);\n if (retryAfter !== undefined) return retryAfter;\n for (const name of ['x-ratelimit-reset', 'ratelimit-reset']) {\n const reset = headers.get(name)?.trim();\n if (reset !== undefined && /^\\d+$/.test(reset)) return resetDelay(Number(reset), now);\n }\n return undefined;\n}\n\n/** retry-after — число секунд или HTTP-дата; пустой и неразборчивый — undefined. */\nfunction retryAfterOf(value: string | undefined, now: number): number | undefined {\n if (value === undefined || value === '') return undefined;\n if (/^\\d+$/.test(value)) return Number(value);\n const at = Date.parse(value);\n return Number.isFinite(at) ? Math.max(0, Math.ceil((at - now) / 1000)) : undefined;\n}\n\n/** Сброс лимита: epoch секунд (от 1e9, 2001-09-09) — задержка до него от now; меньшее число — уже задержка в секундах. */\nfunction resetDelay(reset: number, now: number): number {\n return reset >= 1_000_000_000 ? Math.max(0, reset - Math.floor(now / 1000)) : reset;\n}\n\n/** Адрес без пути и параметров: в тексте ошибки секретам неоткуда взяться. */\nfunction hostOf(url: string): string {\n try {\n return new URL(url).host;\n } catch {\n return 'трекер';\n }\n}\n\n/** Базовый адрес без хвостовых слэшей; не http и не https — отказ подключения. */\nexport function baseUrl(value: string | undefined, fallback: string): string {\n const raw = (value ?? fallback).replace(/\\/+$/, '');\n let parsed: URL;\n try {\n parsed = new URL(raw);\n } catch {\n throw new TrackerError('invalid_request', 'Адрес трекера — не URL.');\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') throw new TrackerError('invalid_request', 'Адрес трекера должен быть http или https.');\n return raw;\n}\n","// Модель CI трекеров библиотеки @smwb/onreel-git-mcp: workflow, прогоны, задания и окно лога (#16, D-006).\n// Своя: в onreel CI трекеров нет.\nimport { z } from 'zod';\nimport { issueLinkSchema, timestampSchema } from '../contract/contract.schema.ts';\nimport { CI_LOG_MAX_BYTES } from './tracker.const.ts';\n\n/** Категория состояния прогона, задания и шага CI единой модели (D-006); своё имя трекер отдаёт в status.name. */\nexport const ciStatusCategorySchema = z.enum(['queued', 'running', 'waiting', 'success', 'failed', 'canceled', 'skipped']);\n/** Что запустило прогон; своё имя события трекер отдаёт в event.name. */\nexport const ciEventCategorySchema = z.enum(['push', 'pull_request', 'manual', 'schedule', 'retry', 'trigger', 'other']);\nexport const ciRunFilterSchema = z.enum(['status', 'ref', 'sha', 'event', 'workflow', 'actor', 'pullRequest', 'createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore']);\nexport const ciRunSortFieldSchema = z.enum(['created', 'updated']);\nexport const ciJobFilterSchema = z.enum(['status', 'allAttempts']);\n\nexport const ciStatusSchema = z.object({ category: ciStatusCategorySchema, name: z.string().min(1).max(100) });\n\nexport const ciWorkflowSchema = z.object({\n /** Ключ workflow: GitHub — id строкой; подходит в trigger.workflows и фильтр workflow. */\n key: z.string().min(1).max(200),\n name: z.string().min(1).max(500),\n path: z.string().min(1).max(1000).optional(),\n enabled: z.boolean(),\n});\n\nexport const ciRunSchema = z.object({\n /** Ключ прогона: GitHub run id, GitLab pipeline id, SourceCraft slug-счётчик; непрозрачная строка. */\n key: z.string().min(1).max(200),\n /** Номер для людей: GitHub run_number, GitLab iid, SourceCraft — счётчик. */\n number: z.number().int().nonnegative().optional(),\n /** Workflow прогона: GitHub — один, SourceCraft — все в прогоне, GitLab — имя пайплайна, если задано. */\n workflows: z.array(z.string().min(1).max(500)).max(100),\n status: ciStatusSchema,\n event: z.object({ category: ciEventCategorySchema, name: z.string().min(1).max(100) }).optional(),\n /** Ветка или тег прогона. */\n ref: z.string().min(1).max(500).optional(),\n sha: z\n .string()\n .regex(/^[0-9a-f]{7,64}$/)\n .optional(),\n /** Кто запустил — логин или slug трекера. */\n actor: z.string().min(1).max(200).optional(),\n /** Ключ PR того же трекера, для которого прогон. */\n pullRequest: z.string().min(1).max(200).optional(),\n /** Попытка прогона (GitHub run_attempt). */\n attempt: z.number().int().positive().optional(),\n /** Ошибки прогона от трекера (SourceCraft error_messages). */\n errors: z.array(z.string().min(1).max(4000)).max(20).optional(),\n links: z.array(issueLinkSchema).max(10),\n createdAt: timestampSchema.optional(),\n startedAt: timestampSchema.optional(),\n finishedAt: timestampSchema.optional(),\n updatedAt: timestampSchema.optional(),\n});\n\nexport const ciJobSchema = z.object({\n /** Ключ задания: GitHub и GitLab — job id, SourceCraft — `<run>/<workflow>/<task>/<cube>`, части через encodeURIComponent. */\n key: z.string().min(1).max(1000),\n runKey: z.string().min(1).max(200),\n name: z.string().min(1).max(500),\n /** Группа: GitLab — stage, SourceCraft — `<workflow>/<task>`; у GitHub нет. */\n stage: z.string().min(1).max(1000).optional(),\n status: ciStatusSchema,\n /** Шаги GitHub: где упало; у остальных нет. */\n steps: z\n .array(z.object({ number: z.number().int().nonnegative(), name: z.string().min(1).max(500), status: ciStatusSchema }))\n .max(1000)\n .optional(),\n attempt: z.number().int().positive().optional(),\n links: z.array(issueLinkSchema).max(10),\n createdAt: timestampSchema.optional(),\n startedAt: timestampSchema.optional(),\n finishedAt: timestampSchema.optional(),\n});\n\nexport const ciLogSchema = z.object({\n /** Окно лога: очищено от ANSI (если не raw), секреты замаскированы. */\n text: z.string().max(CI_LOG_MAX_BYTES),\n /** Окно не покрывает весь лог от курсора: срезано спереди (tail), сзади (head) или упёрлись в потолок чтения. */\n truncated: z.boolean(),\n /** Задание закончилось — лог больше не растёт. */\n complete: z.boolean(),\n /** Курсор дочитывания: передайте в log() — придёт текст после этого места. Нет — дальше ничего не будет. */\n nextCursor: z.string().min(1).max(200).optional(),\n /** Размер лога в байтах, если тело прочитано целиком. */\n size: z.number().int().nonnegative().optional(),\n});\n\nexport type CiStatusCategory = z.infer<typeof ciStatusCategorySchema>;\nexport type CiEventCategory = z.infer<typeof ciEventCategorySchema>;\nexport type CiRunFilter = z.infer<typeof ciRunFilterSchema>;\nexport type CiRunSortField = z.infer<typeof ciRunSortFieldSchema>;\nexport type CiJobFilter = z.infer<typeof ciJobFilterSchema>;\nexport type CiStatus = z.infer<typeof ciStatusSchema>;\nexport type CiWorkflow = z.infer<typeof ciWorkflowSchema>;\nexport type CiRun = z.infer<typeof ciRunSchema>;\nexport type CiJob = z.infer<typeof ciJobSchema>;\nexport type CiLog = z.infer<typeof ciLogSchema>;\n","// Общие помощники CI трекеров библиотеки @smwb/onreel-git-mcp: адаптер по определению, окно и курсор лога,\n// очистка текста лога (#16, D-005, D-006). Свои: в onreel CI трекеров нет.\nimport { REDACTED, redactSecretText } from '../kernel/redact.lib.ts';\nimport type { CiLog, CiStatusCategory } from './ci.schema.ts';\nimport type { CiAdapter, CiLogQuery, CiLogWindow } from './ci.types.ts';\nimport { CI_FINISHED_STATUSES, CI_LOG_DEFAULT_BYTES, CI_LOG_MAX_BYTES } from './tracker.const.ts';\nimport { clipText, TrackerError } from './tracker.lib.ts';\nimport type { AdapterContext, TrackerDefinition } from './tracker.types.ts';\n\n/** Адаптер CI трекера (D-005); трекер без раздела ci — TrackerError('unsupported', 'Трекер <title> не ведёт CI.'). */\nexport function ciAdapterOf(definition: TrackerDefinition, context: AdapterContext): CiAdapter {\n if (definition.ci === undefined) throw new TrackerError('unsupported', `Трекер ${definition.descriptor.title} не ведёт CI.`);\n return definition.ci.create(context);\n}\n\n/** Курсор лога: страница и байт в ней — целые без знака в пределах безопасных чисел. */\nconst LOG_CURSOR = /^c:(\\d{1,15}):(\\d{1,15})$/;\n\n/**\n * Окно лога из запроса (D-006): maxBytes 1..CI_LOG_MAX_BYTES (по умолчанию CI_LOG_DEFAULT_BYTES), from по умолчанию tail,\n * курсор `c:<страница>:<байт>` — в resume; иначе TrackerError('invalid_request').\n */\nexport function logWindow(query: CiLogQuery): CiLogWindow {\n const bytes = query.maxBytes ?? CI_LOG_DEFAULT_BYTES;\n if (!Number.isInteger(bytes) || bytes < 1 || bytes > CI_LOG_MAX_BYTES) {\n throw new TrackerError('invalid_request', `Окно лога maxBytes — целое от 1 до ${String(CI_LOG_MAX_BYTES)}.`);\n }\n const from = query.from ?? 'tail';\n if (from !== 'head' && from !== 'tail') throw new TrackerError('invalid_request', 'Начало окна лога from — head или tail.');\n if (query.cursor === undefined) return { bytes, from };\n const match = LOG_CURSOR.exec(query.cursor);\n if (match === null) {\n throw new TrackerError('invalid_request', 'Курсор лога неверен: передайте nextCursor прошлого ответа log() или не передавайте cursor.');\n }\n // С курсором окно читается вперёд от его места: from не читается.\n return { bytes, from: 'head', resume: { page: Number(match[1]), offset: Number(match[2]) } };\n}\n\n/** Курсор дочитывания с места (страница, байт в ней): `c:<page>:<offset>`. */\nexport function logCursor(page: number, offset: number): string {\n return `c:${String(page)}:${String(offset)}`;\n}\n\n/**\n * Лог единой модели из прочитанного окна: окно выравнивается по целым строкам (lineWindow), затем cleanLogText\n * (если не raw), хвост приватного ключа из прошлого окна и redactSecretText — всегда. nextCursor = logCursor(page, end)\n * со сдвигом end назад на отложенный конец окна, если задание не закончилось или окно head оборвалось раньше конца\n * тела; иначе курсора нет. Окно, которое не сдвинулось (пусто при more: потолок чтения, символ шире окна), у законченного\n * задания курсора не даёт — тот же курсор зациклил бы дочитывание. startCut — начало окна отрезано (хвост лога): первая\n * неполная строка отбрасывается; по умолчанию truncated && !more — окно усечено, а дальше читать нечего.\n * end — байт за окном на странице page; на эту страницу приходятся не больше end последних байт окна.\n */\nexport function logOf(input: {\n text: string;\n truncated: boolean;\n complete: boolean;\n page: number;\n end: number;\n more: boolean;\n size?: number | undefined;\n raw: boolean;\n startCut?: boolean | undefined;\n}): CiLog {\n const stalled = input.text === '' && input.more;\n const follow = !input.complete || (input.more && !stalled);\n const window = lineWindow(input.text, { start: input.startCut ?? (input.truncated && !input.more), end: follow, endBytes: input.end });\n const clean = maskKeyTail(input.raw ? window.text : cleanLogText(window.text));\n // Маскирование может удлинить текст на несколько символов: окно не выходит за потолок схемы.\n const text = clipText(redactSecretText(clean), CI_LOG_MAX_BYTES);\n return {\n text,\n truncated: input.truncated,\n complete: input.complete,\n ...(follow ? { nextCursor: logCursor(input.page, input.end - window.held) } : {}),\n ...(input.size === undefined ? {} : { size: input.size }),\n };\n}\n\n// Секрет, разрезанный краем окна, не узнаётся ни в одном из окон, а склеенные окна отдают его целиком (D-006).\n// Поэтому окно с курсором кончается после последнего \\n (курсор — на начале следующей строки), окно с отрезанным\n// началом начинается после первого \\n, а приватный ключ не начинается в окне, которое его не закончит. Строка\n// длиннее окна режется по словам: конец — перед последним словом вместе с ключом присваивания перед ним, начало —\n// после первого пробела; без пробелов — по байту, тогда откладываются незаконченная ANSI-последовательность и \\r.\n\nconst KEY_BEGIN = /-----BEGIN [A-Z ]*PRIVATE KEY-----/g;\nconst KEY_END = /-----END [A-Z ]*PRIVATE KEY-----/;\n/** Целая ANSI-последовательность с начала строки: как ANSI_SEQUENCE, но OSC — только с терминатором, а `ESC [` и `ESC ]` — не целые. */\n// oxlint-disable-next-line no-control-regex -- ESC и BEL — сами искомые управляющие символы.\nconst WHOLE_ANSI_SEQUENCE = /^(?:\\x1b\\[[0-?]*[ -/]*[@-~]|\\x1b\\][^\\x07\\x1b]*(?:\\x07|\\x1b\\\\)|\\x1b[ -/]*(?![[\\]])[0-~])/;\n/** Ключ перед значением в конце текста: `token: `, `PASSWORD=`, `Bearer ` — значение без ключа не узнать. */\nconst VALUE_KEY = /(?:[A-Za-z][\\w.-]{0,63}[\"']?\\s*[=:]|\\b(?:Bearer|Basic|Token))\\s*[\"']?$/i;\n/** Сколько символов перед последним словом ищется ключ: имя ключа короче 64 символов. */\nconst VALUE_KEY_LOOKBACK = 80;\n\n/**\n * Окно по целым строкам: start — отбросить начало до первого \\n включительно, end — отложить конец после последнего\n * \\n (и строку BEGIN незаконченного в окне приватного ключа). held — сколько байт конца отложено; не больше endBytes:\n * у SourceCraft окно собрано из нескольких страниц, курсор не уходит на прошлую — окно кончается на её границе.\n */\nfunction lineWindow(text: string, cut: { start: boolean; end: boolean; endBytes: number }): { text: string; held: number } {\n let to = text.length;\n if (cut.end) {\n const line = text.lastIndexOf('\\n');\n to = keyStart(text, line >= 0 ? line + 1 : wordCut(text, byteCut(text)));\n }\n let held = to === text.length ? 0 : utf8Length(text.slice(to));\n if (held > cut.endBytes) {\n to = suffixStart(text, cut.endBytes);\n held = cut.endBytes;\n }\n let from = 0;\n if (cut.start) {\n const line = text.indexOf('\\n');\n from = Math.min(line >= 0 ? line + 1 : firstWordEnd(text), to);\n }\n return { text: text.slice(from, to), held };\n}\n\n/** Конец окна без \\n: перед незаконченной ANSI-последовательностью и \\r; окно не становится пустым. */\nfunction byteCut(text: string): number {\n let to = text.length;\n const escape = text.lastIndexOf('\\x1b');\n if (escape > 0 && !WHOLE_ANSI_SEQUENCE.test(text.slice(escape))) to = escape;\n if (to > 1 && text[to - 1] === '\\r') to -= 1;\n return to;\n}\n\n/** Конец окна перед последним словом text[0, to) и ключом перед ним; без пробела — to. Окно не становится пустым. */\nfunction wordCut(text: string, to: number): number {\n let space = to - 1;\n while (space >= 0 && !/\\s/.test(text.charAt(space))) space -= 1;\n if (space < 0) return to;\n const word = space + 1;\n const before = text.slice(Math.max(0, word - VALUE_KEY_LOOKBACK), word);\n const key = VALUE_KEY.exec(before);\n const keyed = key === null ? word : word - before.length + key.index;\n return keyed > 0 ? keyed : word;\n}\n\n/** Начало окна без \\n: после первого пробела (обрывок слова отбрасывается); без пробелов — 0. */\nfunction firstWordEnd(text: string): number {\n const space = /\\s+/.exec(text);\n return space === null ? 0 : space.index + space[0].length;\n}\n\n/** Конец окна перед строкой BEGIN приватного ключа, у которого в text[0, to) нет END; ключ с начала окна не трогается. */\nfunction keyStart(text: string, to: number): number {\n const head = text.slice(0, to);\n const begin = [...head.matchAll(KEY_BEGIN)].at(-1);\n if (begin === undefined || KEY_END.test(head.slice(begin.index))) return to;\n const line = head.lastIndexOf('\\n', begin.index) + 1;\n return line > 0 ? line : begin.index > 0 ? begin.index : to;\n}\n\n/**\n * Окно начинается внутри приватного ключа: всё до END без BEGIN перед ним маскируется; ключ длиннее окна — ведущие\n * строки его тела (base64 в обоих регистрах и с цифрами), даже без END в окне.\n */\nfunction maskKeyTail(text: string): string {\n const end = KEY_END.exec(text);\n if (end !== null && [...text.slice(0, end.index).matchAll(KEY_BEGIN)].length === 0) return REDACTED + text.slice(end.index + end[0].length);\n let at = 0;\n for (;;) {\n const next = text.indexOf('\\n', at);\n if (!isKeyBodyLine(text.slice(at, next < 0 ? text.length : next))) break;\n at = next < 0 ? text.length : next + 1;\n if (next < 0) break;\n }\n if (at === 0) return text;\n return REDACTED + (text[at - 1] === '\\n' ? text.slice(at - 1) : '');\n}\n\n/** Строка тела PEM: 16..76 символов base64 с паддингом, есть заглавные, строчные и цифры (не hex-дайджест и не слово). */\nfunction isKeyBodyLine(line: string): boolean {\n const body = line.endsWith('\\r') ? line.slice(0, -1) : line;\n return /^[A-Za-z0-9+/]{16,76}={0,2}$/.test(body) && /[A-Z]/.test(body) && /[a-z]/.test(body) && /\\d/.test(body);\n}\n\nconst utf8 = new TextEncoder();\n\nfunction utf8Length(text: string): number {\n return utf8.encode(text).length;\n}\n\n/** Индекс в text, с которого последние bytes байт UTF-8; граница — между целыми символами. */\nfunction suffixStart(text: string, bytes: number): number {\n let index = text.length;\n let count = 0;\n while (index > 0 && count < bytes) {\n const low = text.charCodeAt(index - 1);\n const pair = index > 1 && low >= 0xdc00 && low <= 0xdfff && text.charCodeAt(index - 2) >= 0xd800 && text.charCodeAt(index - 2) <= 0xdbff;\n count += utf8Length(text.slice(index - (pair ? 2 : 1), index));\n index -= pair ? 2 : 1;\n }\n return index;\n}\n\n// ANSI: CSI (`ESC [ … финальный`), OSC (`ESC ] … BEL | ESC \\`) и прочие ESC-последовательности\n// (`ESC ( B` — набор символов, `ESC =` — режим клавиатуры).\n// oxlint-disable-next-line no-control-regex -- ESC и BEL — сами искомые управляющие символы.\nconst ANSI_SEQUENCE = /\\x1b\\[[0-?]*[ -/]*[@-~]|\\x1b\\][^\\x07\\x1b]*(?:\\x07|\\x1b\\\\|$)|\\x1b[ -/]*[0-~]/g;\n/** Маркеры свёртки GitLab: `section_start:<epoch>:<имя>[опции]\\r` и `section_end:<epoch>:<имя>\\r` (ESC[0K уже снят). */\nconst GITLAB_SECTION_MARKER = /section_(?:start|end):\\d+:[A-Za-z0-9_.-]+(?:\\[[^\\]\\r\\n]*\\])?\\r?/g;\n\n/** Текст лога без ANSI-последовательностей (CSI, OSC), перерисовок строки через \\r и маркеров section_start/section_end GitLab. */\nexport function cleanLogText(text: string): string {\n const plain = text.replace(ANSI_SEQUENCE, '').replace(GITLAB_SECTION_MARKER, '').replace(/\\r+\\n/g, '\\n');\n if (!plain.includes('\\r')) return plain;\n // Перерисовка строки (прогресс): видна последняя непустая версия строки после \\r.\n return plain\n .split('\\n')\n .map((line) => (line.includes('\\r') ? (line.split('\\r').findLast((part) => part !== '') ?? '') : line))\n .join('\\n');\n}\n\n/** Категория законченного состояния: success, failed, canceled, skipped. */\nexport function isFinished(category: CiStatusCategory): boolean {\n return CI_FINISHED_STATUSES.includes(category);\n}\n","// Адаптер CI GitHub библиотеки @smwb/onreel-git-mcp: workflow, прогоны и задания Actions репозитория через\n// REST API на том же подключении, что и задачи (#16, D-005, D-006). Свой: в onreel CI трекеров нет.\nimport { isFinished, logCursor, logOf, logWindow } from './ci.lib.ts';\nimport { ciJobFilterSchema, ciRunFilterSchema } from './ci.schema.ts';\nimport type { CiEventCategory, CiJob, CiRun, CiStatus, CiStatusCategory, CiWorkflow } from './ci.schema.ts';\nimport type { CiAdapter, CiCapabilities, CiDefinition, CiRunQuery } from './ci.types.ts';\nimport { baseUrl, requestJson, requestText } from './http.lib.ts';\nimport { GITHUB_RUN_CONCLUSIONS, GITHUB_RUN_EVENTS, GITHUB_RUN_STATUSES } from './mapping.const.ts';\nimport { TrackerError, assertListQuery, inTimeRange, isRecord, isoTime, keysFor, lookup, requireTarget, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext } from './tracker.types.ts';\n\n// CI GitHub (D-005, D-006): Actions репозитория `owner/repo`. Статус, событие и границы updated проверяются по\n// полученной странице: upstream фильтрует грубее единой модели (у категории pull_request три сырых имени,\n// времени изменения прогона параметром нет). Лог задания появляется только после его конца, дальше читается\n// окном с курсором по байту тела. Запуск — workflow_dispatch ровно одного workflow с не больше чем 25 inputs.\n\nconst DEFAULT_API = 'https://api.github.com';\nconst TARGET = /^[\\w.-]+\\/[\\w.-]+$/;\nconst ID = /^[1-9]\\d{0,19}$/;\nconst SHA = /^[0-9a-f]{7,64}$/;\n/** Потолок inputs workflow_dispatch: больше 25 параметров GitHub не принимает. */\nconst DISPATCH_INPUTS_MAX = 25;\n\n/** Фильтры списков CI — значения схемы; порядок — для текстов отказов. */\nconst RUN_FILTERS = ciRunFilterSchema.options;\nconst JOB_FILTERS = ciJobFilterSchema.options;\n\nconst RUNS_SUBJECT = 'Прогоны CI GitHub';\nconst JOBS_SUBJECT = 'Задания CI GitHub';\nconst WORKFLOWS_SUBJECT = 'Список workflow GitHub';\nconst TRIGGER_SUBJECT = 'Запуск CI GitHub';\n\n/** Возможности CI GitHub (§3.6): список workflow есть, сортировки прогонов нет, лог — только законченного задания. */\nconst CAPABILITIES: CiCapabilities = {\n workflows: true,\n runs: { filters: RUN_FILTERS, clientSide: ['status', 'event', 'updatedAfter', 'updatedBefore'], sorts: [] },\n jobs: { filters: JOB_FILTERS, clientSide: ['status'], sorts: [] },\n log: { live: false, cursor: true },\n trigger: { supported: true, workflows: 'one', inputs: true, tags: true },\n rerun: { all: true, failedOnly: true, job: true, debug: true },\n cancel: { run: true, job: false },\n};\n\nexport function githubCi(): CiDefinition {\n return { capabilities: CAPABILITIES, create: (context) => createGithubCiAdapter(context) };\n}\n\nfunction createGithubCiAdapter({ connection, fetch }: AdapterContext): CiAdapter {\n const target = requireTarget(connection.target, 'owner/repo репозитория GitHub');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target GitHub — owner/repo.');\n const api = baseUrl(connection.url, DEFAULT_API);\n const root = `${api}/repos/${target}`;\n const actions = `${root}/actions`;\n const headers = {\n accept: 'application/vnd.github+json',\n 'x-github-api-version': '2022-11-28',\n ...(connection.token === undefined || connection.token === '' ? {} : { authorization: `Bearer ${connection.token}` }),\n };\n const runKey = (key: string): string => {\n if (!ID.test(key)) throw new TrackerError('not_found', `В GitHub нет прогона ${key}.`);\n return key;\n };\n const jobKey = (key: string): string => {\n if (!ID.test(key)) throw new TrackerError('not_found', `В GitHub нет задания ${key}.`);\n return key;\n };\n const missingRun = (key: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В GitHub нет прогона ${key}.` });\n const missingJob = (key: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В GitHub нет задания ${key}.` });\n const getRun = async (key: string): Promise<CiRun> => runOf((await requestJson(`${actions}/runs/${runKey(key)}`, { fetch, headers, missing: missingRun(key) })).body);\n /**\n * Голова прогона для фильтра: pullRequest читает PR и отдаёт его head_sha — у GitHub прогоны PR иначе\n * как по голове не выбрать. sha и pullRequest вместе задавать нельзя (§3.7 C2).\n */\n const headShaOf = async (query: CiRunQuery): Promise<string | undefined> => {\n if (query.pullRequest === undefined) return query.sha;\n if (query.sha !== undefined) throw new TrackerError('invalid_request', `${RUNS_SUBJECT}: sha и pullRequest задаются по отдельности — прогоны PR берутся по его голове.`);\n const pull = query.pullRequest;\n if (!ID.test(pull)) throw new TrackerError('not_found', `В GitHub нет pull request ${pull}.`);\n const { body } = await requestJson(`${root}/pulls/${pull}`, { fetch, headers, missing: { failure: 'not_found', message: `В GitHub нет pull request ${pull}.` } });\n const head = isRecord(body) && isRecord(body.head) ? text(body.head.sha) : undefined;\n if (head === undefined) throw new TrackerError('failed', 'GitHub не вернул голову pull request.');\n return head;\n };\n return {\n listWorkflows: async (query) => {\n assertListQuery(WORKFLOWS_SUBJECT, { filters: [], clientSide: [], sorts: [] }, query, []);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({ per_page: String(query.limit), page: String(page) });\n const { body, headers: responseHeaders } = await requestJson(`${actions}/workflows?${params.toString()}`, { fetch, headers });\n return { items: rowsOf(body, 'workflows').map(workflowOf), ...nextCursorOf(page, responseHeaders.get('link') ?? '') };\n },\n listRuns: async (query) => {\n assertListQuery(RUNS_SUBJECT, CAPABILITIES.runs, query, RUN_FILTERS);\n const page = pageOf(query.cursor);\n const sha = await headShaOf(query);\n const params = new URLSearchParams({ per_page: String(query.limit), page: String(page) });\n if (query.ref !== undefined) params.set('branch', query.ref);\n if (sha !== undefined) params.set('head_sha', sha);\n if (query.actor !== undefined) params.set('actor', query.actor);\n const status = statusParam(query.status);\n if (status !== undefined) params.set('status', status);\n const event = eventParam(query.event);\n if (event !== undefined) params.set('event', event);\n const created = createdParam(query);\n if (created !== undefined) params.set('created', created);\n // Прогоны одного workflow — свой путь; id и имя файла GitHub принимает одинаково (§3.7 C2).\n const path = query.workflow === undefined ? `${actions}/runs` : `${actions}/workflows/${encodeURIComponent(query.workflow)}/runs`;\n const { body, headers: responseHeaders } = await requestJson(`${path}?${params.toString()}`, { fetch, headers });\n const items = rowsOf(body, 'workflow_runs')\n .map(runOf)\n .filter((run) =>\n (query.status === undefined || query.status.includes(run.status.category)) &&\n (query.event === undefined || (run.event !== undefined && query.event.includes(run.event.category))) &&\n inTimeRange(run.updatedAt, query.updatedAfter, query.updatedBefore),\n );\n return { items, ...nextCursorOf(page, responseHeaders.get('link') ?? '') };\n },\n getRun: getRun,\n listJobs: async (key, query) => {\n const run = runKey(key);\n // allAttempts — переключатель формы списка, а не фильтр значения: проверка запроса идёт без него.\n const { allAttempts, ...rest } = query;\n assertListQuery(JOBS_SUBJECT, CAPABILITIES.jobs, rest, JOB_FILTERS);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({ per_page: String(query.limit), page: String(page), filter: allAttempts === true ? 'all' : 'latest' });\n const { body, headers: responseHeaders } = await requestJson(`${actions}/runs/${run}/jobs?${params.toString()}`, { fetch, headers, missing: missingRun(run) });\n const items = rowsOf(body, 'jobs')\n .map(jobOf)\n .filter((job) => query.status === undefined || query.status.includes(job.status.category));\n return { items, ...nextCursorOf(page, responseHeaders.get('link') ?? '') };\n },\n getJob: async (key) => {\n const id = jobKey(key);\n return jobOf((await requestJson(`${actions}/jobs/${id}`, { fetch, headers, missing: missingJob(id) })).body);\n },\n log: async (key, query) => {\n const id = jobKey(key);\n const window = logWindow(query);\n const job = (await requestJson(`${actions}/jobs/${id}`, { fetch, headers, missing: missingJob(id) })).body;\n const complete = isFinished(statusOf(isRecord(job) ? job : {}).category);\n // Лог у GitHub появляется только после конца задания: идущее — пустой результат без скачивания (§3.5).\n if (!complete) return { text: '', truncated: false, complete: false, nextCursor: logCursor(0, 0) };\n // Логи отдаёт подписанный адрес за 302; fetch идёт за редиректом, Authorization на чужой origin не уходит.\n const response = await requestText(`${actions}/jobs/${id}/logs`, {\n fetch,\n headers,\n skip: window.resume?.offset ?? 0,\n keep: { bytes: window.bytes, from: window.from },\n missing: missingJob(id),\n });\n return logOf({\n text: response.text,\n truncated: window.from === 'tail' ? response.start > 0 : !response.whole,\n complete,\n page: 0,\n end: response.end,\n // Курсор дальше имеет смысл только когда окно head оборвалось раньше конца тела: tail уже читает конец.\n more: window.from === 'head' && !response.whole,\n ...(response.whole ? { size: response.read } : {}),\n raw: query.raw ?? false,\n });\n },\n trigger: async (input) => {\n const workflows = input.workflows ?? [];\n const workflow = workflows[0];\n if (workflows.length !== 1 || workflow === undefined) {\n throw new TrackerError('invalid_request', `${TRIGGER_SUBJECT}: нужен ровно один workflow — id или имя файла.`);\n }\n const inputs = input.inputs ?? {};\n const count = Object.keys(inputs).length;\n if (count > DISPATCH_INPUTS_MAX) throw new TrackerError('invalid_request', `${TRIGGER_SUBJECT}: workflow_dispatch принимает не больше ${String(DISPATCH_INPUTS_MAX)} параметров.`);\n const { body } = await requestJson(`${actions}/workflows/${encodeURIComponent(workflow)}/dispatches`, {\n fetch,\n headers,\n method: 'POST',\n body: { ref: input.ref, ...(count === 0 ? {} : { inputs }), return_run_details: true },\n });\n // return_run_details даёт id созданного прогона; без него трекер принял запуск и ничего не сказал (§3.5).\n const run = runIdOf(isRecord(body) ? body.workflow_run_id : undefined);\n return run === undefined ? {} : { run: await getRun(run) };\n },\n rerun: async (key, input) => {\n const run = runKey(key);\n // Только упавшие задания — отдельный адрес; флаг отладки GitHub читает и при полном перезапуске.\n await requestJson(`${actions}/runs/${run}/${input.failedOnly === true ? 'rerun-failed-jobs' : 'rerun'}`, {\n fetch,\n headers,\n method: 'POST',\n body: { enable_debug_logging: input.debug === true },\n missing: missingRun(run),\n });\n return getRun(run);\n },\n rerunJob: async (key, input) => {\n const id = jobKey(key);\n const job = (await requestJson(`${actions}/jobs/${id}`, { fetch, headers, missing: missingJob(id) })).body;\n const run = runIdOf(isRecord(job) ? job.run_id : undefined);\n if (run === undefined) throw new TrackerError('failed', 'GitHub не вернул прогон задания.');\n await requestJson(`${actions}/jobs/${id}/rerun`, { fetch, headers, method: 'POST', body: { enable_debug_logging: input.debug === true }, missing: missingJob(id) });\n // Задание уходит в тот же прогон: состояние прогона и есть ответ (§3.7 C2).\n return getRun(run);\n },\n cancel: async (key) => {\n const run = runKey(key);\n await requestJson(`${actions}/runs/${run}/cancel`, { fetch, headers, method: 'POST', conflictOn: [409], missing: missingRun(run) });\n return getRun(run);\n },\n cancelJob: async () => {\n throw new TrackerError('unsupported', 'Отмена CI GitHub: задания по отдельности не отменяются, отменяется прогон.');\n },\n };\n}\n\n/** Номер страницы из курсора: курсор GitHub — простой номер страницы, первый — 1. */\nfunction pageOf(cursor: string | undefined): number {\n const page = cursor === undefined ? 1 : Number(cursor);\n return Number.isInteger(page) && page >= 1 ? page : 1;\n}\n\n/** Курсор следующей страницы по заголовку Link: rel=\"next\" — страница номером на один больше. */\nfunction nextCursorOf(page: number, link: string): { nextCursor?: string } {\n return /rel=\"next\"/.test(link) ? { nextCursor: String(page + 1) } : {};\n}\n\n/** Элементы списка: GitHub кладёт их в поле ответа рядом с total_count. */\nfunction rowsOf(body: unknown, field: string): readonly unknown[] {\n const rows = isRecord(body) ? body[field] : undefined;\n return Array.isArray(rows) ? rows : [];\n}\n\n/** Ключ сущности в непрозрачную строку единой модели: id числом или строкой; не разобралось — «?». */\nfunction keyOf(value: unknown): string {\n if (typeof value === 'number' && Number.isSafeInteger(value)) return String(value);\n return typeof value === 'string' && value !== '' ? value : '?';\n}\n\n/** Целое положительное число (номер прогона, попытка): не число или не положительное — undefined. */\nfunction positiveInt(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isSafeInteger(value) && value > 0 ? value : undefined;\n}\n\n/** id прогона в сырых полях (run_id задания, workflow_run_id ответа dispatch): ключ прогона для getRun. */\nfunction runIdOf(value: unknown): string | undefined {\n const id = positiveInt(value);\n return id === undefined ? undefined : String(id);\n}\n\n/**\n * Статус прогона, задания и шага GitHub: заключение читается только когда status completed, незнакомое законченное —\n * failed, незнакомый не законченный — running (§3.6).\n */\nfunction statusOf(item: Record<string, unknown>): CiStatus {\n const raw = text(item.status) ?? 'unknown';\n if (raw !== 'completed') return { category: lookup(GITHUB_RUN_STATUSES, raw, 'running'), name: raw };\n const conclusion = text(item.conclusion);\n return { category: lookup(GITHUB_RUN_CONCLUSIONS, conclusion, 'failed'), name: conclusion ?? raw };\n}\n\n/** Параметр status: completed — когда запрошены только законченные категории, in_progress — только одиночный running. */\nfunction statusParam(status: readonly CiStatusCategory[] | undefined): string | undefined {\n if (status === undefined || status.length === 0) return undefined;\n if (status.every(isFinished)) return 'completed';\n return status.length === 1 && status[0] === 'running' ? 'in_progress' : undefined;\n}\n\n/** Параметр event: одна запрошенная категория с единственным сырым именем (push, manual, schedule). */\nfunction eventParam(event: readonly CiEventCategory[] | undefined): string | undefined {\n if (event === undefined || event.length !== 1) return undefined;\n const raws = keysFor(GITHUB_RUN_EVENTS, event);\n return raws.length === 1 ? raws[0] : undefined;\n}\n\n/** Параметр created: >=A, <=B или диапазон A..B (ISO). Границ updated у GitHub параметра нет — проверка по странице. */\nfunction createdParam(query: CiRunQuery): string | undefined {\n const { createdAfter: after, createdBefore: before } = query;\n if (after !== undefined && before !== undefined) return `${isoTime(after)}..${isoTime(before)}`;\n if (after !== undefined) return `>=${isoTime(after)}`;\n return before !== undefined ? `<=${isoTime(before)}` : undefined;\n}\n\n/** Workflow Actions: включён только активный — inactive и disabled для единой модели выключены. */\nfunction workflowOf(raw: unknown): CiWorkflow {\n const item = isRecord(raw) ? raw : {};\n const key = keyOf(item.id);\n const path = text(item.path);\n return { key, name: text(item.name) ?? key, ...(path === undefined ? {} : { path }), enabled: item.state === 'active' };\n}\n\n/** Прогон Actions → прогон единой модели: время конца — последнее обновление завершённого (§3.7 C2). */\nfunction runOf(raw: unknown): CiRun {\n const item = isRecord(raw) ? raw : {};\n const key = keyOf(item.id);\n const status = statusOf(item);\n const name = text(item.name) ?? text(item.path);\n const branch = text(item.head_branch);\n const sha = text(item.head_sha);\n const actor = isRecord(item.actor) ? text(item.actor.login) : undefined;\n const pull = Array.isArray(item.pull_requests) ? item.pull_requests[0] : undefined;\n const pullNumber = isRecord(pull) && typeof pull.number === 'number' ? String(pull.number) : undefined;\n const number = positiveInt(item.run_number);\n const attempt = positiveInt(item.run_attempt);\n const url = text(item.html_url);\n const createdAt = toTimestamp(item.created_at);\n const startedAt = toTimestamp(item.run_started_at);\n const updatedAt = toTimestamp(item.updated_at);\n const finishedAt = text(item.status) === 'completed' ? updatedAt : undefined;\n const event = text(item.event);\n return {\n key,\n ...(number === undefined ? {} : { number }),\n workflows: name === undefined ? [] : [name],\n status,\n ...(event === undefined ? {} : { event: { category: lookup(GITHUB_RUN_EVENTS, event, 'other'), name: event } }),\n ...(branch === undefined ? {} : { ref: branch }),\n ...(sha === undefined || !SHA.test(sha) ? {} : { sha }),\n ...(actor === undefined ? {} : { actor }),\n ...(pullNumber === undefined ? {} : { pullRequest: pullNumber }),\n ...(attempt === undefined ? {} : { attempt }),\n links: url === undefined ? [] : [{ url, title: 'GitHub Actions' }],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(startedAt === undefined ? {} : { startedAt }),\n ...(finishedAt === undefined ? {} : { finishedAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n };\n}\n\n/** Задание Actions → задание единой модели: прогон берётся из run_id, шаги читаются теми же таблицами. */\nfunction jobOf(raw: unknown): CiJob {\n const item = isRecord(raw) ? raw : {};\n const key = keyOf(item.id);\n const url = text(item.html_url);\n const startedAt = toTimestamp(item.started_at);\n const finishedAt = toTimestamp(item.completed_at);\n const steps = Array.isArray(item.steps) ? item.steps.map(stepOf) : undefined;\n return {\n key,\n runKey: runIdOf(item.run_id) ?? '?',\n name: text(item.name) ?? key,\n status: statusOf(item),\n ...(steps === undefined ? {} : { steps }),\n links: url === undefined ? [] : [{ url, title: 'GitHub Actions' }],\n ...(startedAt === undefined ? {} : { startedAt }),\n ...(finishedAt === undefined ? {} : { finishedAt }),\n };\n}\n\n/** Шаг задания: по его статусу видно, на чём упало задание; времени шага в единой модели нет. */\nfunction stepOf(raw: unknown): { number: number; name: string; status: CiStatus } {\n const item = isRecord(raw) ? raw : {};\n const number = positiveInt(item.number) ?? 0;\n return { number, name: text(item.name) ?? String(number), status: statusOf(item) };\n}\n","// Адаптер CI GitLab библиотеки @smwb/onreel-git-mcp: пайплайны и задания проекта через REST API v4, токен —\n// PRIVATE-TOKEN (#16, D-006). Свой: в onreel CI трекеров нет.\nimport { isFinished, logOf, logWindow } from './ci.lib.ts';\nimport { ciJobFilterSchema, ciRunFilterSchema } from './ci.schema.ts';\nimport type { CiJob, CiRun } from './ci.schema.ts';\nimport type { CiAdapter, CiCapabilities, CiDefinition, CiJobRerunInput, CiRerunInput, CiTriggerInput } from './ci.types.ts';\nimport { baseUrl, requestJson, requestText } from './http.lib.ts';\nimport { GITLAB_CI_STATUSES, GITLAB_PIPELINE_SOURCES } from './mapping.const.ts';\nimport { TrackerError, assertListQuery, inTimeRange, isRecord, isoTime, keysFor, lookup, requireTarget, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext } from './tracker.types.ts';\n\n// CI GitLab (D-006): пайплайны и задания проекта. Workflow у GitLab нет — запуск идёт сразу на ref с\n// переменными. Лог задания (trace) отдаётся, пока задание идёт, и дочитывается по курсору. Статус и событие\n// всегда сверяются со страницей: upstream грубее единой модели (created, preparing и pending — одно).\n\nconst DEFAULT_URL = 'https://gitlab.com';\nconst TARGET = /^(\\d{1,15}|[\\w.-]+(\\/[\\w.-]+)+)$/;\nconst ID = /^[1-9]\\d{0,19}$/;\n\n/** Фильтры списков CI — значения схемы; порядок — для текстов отказов. */\nconst RUN_FILTERS = ciRunFilterSchema.options;\nconst JOB_FILTERS = ciJobFilterSchema.options;\n\n/** Возможности CI GitLab (#16): все фильтры прогонов, сортировка по созданию и обновлению; лог живой, с курсором. */\nconst CAPABILITIES: CiCapabilities = {\n workflows: false,\n runs: { filters: RUN_FILTERS, clientSide: ['status', 'event'], sorts: ['created', 'updated'] },\n jobs: { filters: JOB_FILTERS, clientSide: [], sorts: [] },\n log: { live: true, cursor: true },\n trigger: { supported: true, workflows: 'none', inputs: true, tags: true },\n rerun: { all: false, failedOnly: true, job: true, debug: false },\n cancel: { run: true, job: true },\n};\n\nexport function gitlabCi(): CiDefinition {\n return { capabilities: CAPABILITIES, create: (context) => createGitlabCiAdapter(context) };\n}\n\nfunction createGitlabCiAdapter({ connection, fetch }: AdapterContext): CiAdapter {\n const target = requireTarget(connection.target, 'путь проекта GitLab, group/project, или его id');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target GitLab — group/project или числовой id.');\n const api = `${baseUrl(connection.url, DEFAULT_URL)}/api/v4`;\n const project = `${api}/projects/${encodeURIComponent(target)}`;\n const headers: Record<string, string> = connection.token === undefined || connection.token === '' ? {} : { 'private-token': connection.token };\n // Сырое значение параметра одиночной категории: у категории ровно одно сырое значение — оно, больше —\n // только проверка по странице (upstream грубее единой модели: created, preparing и pending — одно).\n const rawOf = <T extends string>(table: Readonly<Record<string, T>>, categories: readonly T[] | undefined): string | undefined => {\n if (categories === undefined || categories.length !== 1) return undefined;\n const raws = keysFor(table, categories);\n return raws.length === 1 ? raws[0] : undefined;\n };\n const pipelineKey = (key: string): string => {\n if (!ID.test(key)) throw new TrackerError('not_found', `В GitLab нет прогона ${key}.`);\n return key;\n };\n const jobKey = (key: string): string => {\n if (!ID.test(key)) throw new TrackerError('not_found', `В GitLab нет задания ${key}.`);\n return key;\n };\n const missingPipeline = (key: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В GitLab нет прогона ${key}.` });\n const missingJob = (key: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В GitLab нет задания ${key}.` });\n const getPipeline = async (key: string): Promise<CiRun> =>\n runOf((await requestJson(`${project}/pipelines/${pipelineKey(key)}`, { fetch, headers, missing: missingPipeline(key) })).body);\n return {\n listWorkflows: async () => {\n throw new TrackerError('unsupported', 'Прогоны CI GitLab: списка workflow у GitLab нет.');\n },\n listRuns: async (query) => {\n assertListQuery('Прогоны CI GitLab', CAPABILITIES.runs, query, RUN_FILTERS);\n const params = new URLSearchParams({ per_page: String(query.limit), page: String(pageOf(query.cursor)) });\n let body: unknown;\n let responseHeaders: Headers;\n let keep: (run: CiRun) => boolean;\n if (query.pullRequest !== undefined) {\n // Прогоны MR: upstream отдаёт только страницы без фильтров — остальное проверяется по странице;\n // сортировка и фильтры по полям, которых у элементов списка нет, отклоняются до запроса.\n const mr = query.pullRequest;\n if (!ID.test(mr)) throw new TrackerError('not_found', `В GitLab нет merge request ${mr}.`);\n if (query.sort !== undefined) throw new TrackerError('unsupported', 'Прогоны CI GitLab для merge request: сортировка не поддерживается.');\n if (query.actor !== undefined) throw new TrackerError('unsupported', 'Прогоны CI GitLab для merge request: фильтр actor не поддерживается.');\n if (query.workflow !== undefined) throw new TrackerError('unsupported', 'Прогоны CI GitLab для merge request: фильтр workflow не поддерживается.');\n const result = await requestJson(`${project}/merge_requests/${mr}/pipelines?${params.toString()}`, { fetch, headers, missing: { failure: 'not_found', message: `В GitLab нет merge request ${mr}.` } });\n body = result.body;\n responseHeaders = result.headers;\n keep = (run) =>\n (query.status === undefined || query.status.includes(run.status.category)) &&\n (query.event === undefined || (run.event !== undefined && query.event.includes(run.event.category))) &&\n (query.ref === undefined || run.ref === query.ref) &&\n (query.sha === undefined || run.sha === query.sha) &&\n inTimeRange(run.createdAt, query.createdAfter, query.createdBefore) &&\n inTimeRange(run.updatedAt, query.updatedAfter, query.updatedBefore);\n } else {\n if (query.ref !== undefined) params.set('ref', query.ref);\n if (query.sha !== undefined) params.set('sha', query.sha);\n if (query.actor !== undefined) params.set('username', query.actor);\n if (query.workflow !== undefined) params.set('name', query.workflow);\n if (query.status !== undefined && query.status.length > 0) {\n const status = rawOf(GITLAB_CI_STATUSES, query.status);\n if (status !== undefined) params.set('status', status);\n if (status === undefined && query.status.every(isFinished)) params.set('scope', 'finished');\n }\n const source = rawOf(GITLAB_PIPELINE_SOURCES, query.event);\n if (source !== undefined) params.set('source', source);\n if (query.createdAfter !== undefined) params.set('created_after', isoTime(query.createdAfter));\n if (query.createdBefore !== undefined) params.set('created_before', isoTime(query.createdBefore));\n if (query.updatedAfter !== undefined) params.set('updated_after', isoTime(query.updatedAfter));\n if (query.updatedBefore !== undefined) params.set('updated_before', isoTime(query.updatedBefore));\n params.set('order_by', query.sort?.field === 'updated' ? 'updated_at' : 'id');\n params.set('sort', query.sort?.direction ?? 'desc');\n const result = await requestJson(`${project}/pipelines?${params.toString()}`, { fetch, headers });\n body = result.body;\n responseHeaders = result.headers;\n keep = (run) =>\n (query.status === undefined || query.status.includes(run.status.category)) &&\n (query.event === undefined || (run.event !== undefined && query.event.includes(run.event.category)));\n }\n const items = (Array.isArray(body) ? body : []).map(runOf).filter(keep);\n const next = responseHeaders.get('x-next-page');\n return { items, ...(next === null || next === '' ? {} : { nextCursor: next }) };\n },\n getRun: getPipeline,\n listJobs: async (runKey, query) => {\n // allAttempts — переключатель формы списка, а не фильтр значения: проверка запроса идёт без него.\n const { allAttempts, ...rest } = query;\n assertListQuery('Задания CI GitLab', CAPABILITIES.jobs, rest, JOB_FILTERS);\n const params = new URLSearchParams({ per_page: String(query.limit), page: String(pageOf(query.cursor)), include_retried: String(allAttempts ?? false) });\n for (const scope of keysFor(GITLAB_CI_STATUSES, query.status ?? [])) params.append('scope[]', scope);\n const { body, headers: responseHeaders } = await requestJson(`${project}/pipelines/${pipelineKey(runKey)}/jobs?${params.toString()}`, { fetch, headers, missing: missingPipeline(runKey) });\n const items = (Array.isArray(body) ? body : []).map(jobOf);\n const next = responseHeaders.get('x-next-page');\n return { items, ...(next === null || next === '' ? {} : { nextCursor: next }) };\n },\n getJob: async (key) => jobOf((await requestJson(`${project}/jobs/${jobKey(key)}`, { fetch, headers, missing: missingJob(key) })).body),\n log: async (key, query) => {\n const window = logWindow(query);\n const job = (await requestJson(`${project}/jobs/${jobKey(key)}`, { fetch, headers, missing: missingJob(key) })).body;\n const rawStatus = isRecord(job) && typeof job.status === 'string' ? job.status : 'unknown';\n const complete = isFinished(lookup(GITLAB_CI_STATUSES, rawStatus, 'running'));\n // Trace читается целиком с пропуском прочитанного: курсор GitLab — всегда страница 0 и байт в теле.\n const response = await requestText(`${project}/jobs/${jobKey(key)}/trace`, { fetch, headers, skip: window.resume?.offset ?? 0, keep: { bytes: window.bytes, from: window.from }, missing: missingJob(key) });\n return logOf({\n text: response.text,\n truncated: window.from === 'tail' ? response.start > 0 : !response.whole,\n complete,\n page: 0,\n end: response.end,\n more: !response.whole,\n ...(response.whole ? { size: response.read } : {}),\n // Кольцевой буфер отрезал начало хвоста и при потолке чтения (whole=false): там default\n // startCut (truncated && !more) молчит, а первая неполная строка в окне остаётся.\n startCut: window.from === 'tail' && response.start > 0,\n raw: query.raw ?? false,\n });\n },\n trigger: async (input: CiTriggerInput) => {\n if (input.workflows !== undefined && input.workflows.length > 0) {\n throw new TrackerError('unsupported', 'Запуск CI GitLab: workflow не задаётся — только ref и переменные.');\n }\n const variables = Object.entries(input.inputs ?? {}).map(([key, value]) => ({ key, value, variable_type: 'env_var' }));\n const { body } = await requestJson(`${project}/pipeline`, {\n fetch,\n headers,\n method: 'POST',\n body: { ref: input.ref, ...(variables.length === 0 ? {} : { variables }) },\n missing: { failure: 'not_found', message: `В GitLab нет ветки или тега ${input.ref}.` },\n });\n return { run: runOf(body) };\n },\n rerun: async (runKey, input: CiRerunInput) => {\n if (input.failedOnly !== true) throw new TrackerError('unsupported', 'Перезапуск CI GitLab умеет только упавшие задания: задайте failedOnly.');\n if (input.debug === true) throw new TrackerError('unsupported', 'Перезапуск CI GitLab не поддерживает отладочное логирование.');\n return runOf((await requestJson(`${project}/pipelines/${pipelineKey(runKey)}/retry`, { fetch, headers, method: 'POST', missing: missingPipeline(runKey) })).body);\n },\n rerunJob: async (jobKeyValue, input: CiJobRerunInput) => {\n if (input.debug === true) throw new TrackerError('unsupported', 'Перезапуск задания GitLab не поддерживает отладочное логирование.');\n const body = (await requestJson(`${project}/jobs/${jobKey(jobKeyValue)}/retry`, { fetch, headers, method: 'POST', missing: missingJob(jobKeyValue) })).body;\n const pipeline = isRecord(body) && isRecord(body.pipeline) && typeof body.pipeline.id === 'number' ? String(body.pipeline.id) : undefined;\n if (pipeline === undefined) throw new TrackerError('failed', 'GitLab не вернул пайплайн нового задания.');\n return getPipeline(pipeline);\n },\n cancel: async (runKey) =>\n runOf((await requestJson(`${project}/pipelines/${pipelineKey(runKey)}/cancel`, { fetch, headers, method: 'POST', missing: missingPipeline(runKey) })).body),\n cancelJob: async (jobKeyValue) => jobOf((await requestJson(`${project}/jobs/${jobKey(jobKeyValue)}/cancel`, { fetch, headers, method: 'POST', missing: missingJob(jobKeyValue) })).body),\n };\n}\n\nfunction pageOf(cursor: string | undefined): number {\n const page = cursor === undefined ? 1 : Number(cursor);\n return Number.isInteger(page) && page >= 1 ? page : 1;\n}\n\n/** Пайплайн GitLab → прогон единой модели; ref вида refs/merge-requests/<iid>/head читается как PR. */\nfunction runOf(raw: unknown): CiRun {\n const item = isRecord(raw) ? raw : {};\n const key = typeof item.id === 'number' ? String(item.id) : '?';\n const rawStatus = typeof item.status === 'string' ? item.status : 'unknown';\n const rawSource = text(item.source);\n const mr = typeof item.ref === 'string' ? /^refs\\/merge-requests\\/(\\d+)\\/head$/.exec(item.ref) : null;\n const user = isRecord(item.user) ? text(item.user.username) : undefined;\n const url = text(item.web_url);\n const name = text(item.name);\n const createdAt = toTimestamp(item.created_at);\n const startedAt = toTimestamp(item.started_at);\n const finishedAt = toTimestamp(item.finished_at);\n const updatedAt = toTimestamp(item.updated_at);\n return {\n key,\n ...(typeof item.iid === 'number' ? { number: item.iid } : {}),\n workflows: name === undefined ? [] : [name],\n status: { category: lookup(GITLAB_CI_STATUSES, rawStatus, 'running'), name: rawStatus },\n ...(rawSource === undefined ? {} : { event: { category: lookup(GITLAB_PIPELINE_SOURCES, rawSource, 'other'), name: rawSource } }),\n ...(typeof item.ref === 'string' && item.ref !== '' ? { ref: item.ref } : {}),\n ...(typeof item.sha === 'string' && /^[0-9a-f]{7,64}$/.test(item.sha) ? { sha: item.sha } : {}),\n ...(user === undefined ? {} : { actor: user }),\n ...(mr === null ? {} : { pullRequest: mr[1] }),\n links: url === undefined ? [] : [{ url, title: 'GitLab' }],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(startedAt === undefined ? {} : { startedAt }),\n ...(finishedAt === undefined ? {} : { finishedAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n };\n}\n\n/** Задание GitLab → задание единой модели; runKey берётся из пайплайна задания. */\nfunction jobOf(raw: unknown): CiJob {\n const item = isRecord(raw) ? raw : {};\n const key = typeof item.id === 'number' ? String(item.id) : '?';\n const rawStatus = typeof item.status === 'string' ? item.status : 'unknown';\n const pipeline = isRecord(item.pipeline) && typeof item.pipeline.id === 'number' ? String(item.pipeline.id) : '?';\n const url = text(item.web_url);\n const stage = text(item.stage);\n const startedAt = toTimestamp(item.started_at);\n const finishedAt = toTimestamp(item.finished_at);\n return {\n key,\n runKey: pipeline,\n name: text(item.name) ?? key,\n ...(stage === undefined ? {} : { stage }),\n status: { category: lookup(GITLAB_CI_STATUSES, rawStatus, 'running'), name: rawStatus },\n links: url === undefined ? [] : [{ url, title: 'GitLab' }],\n ...(startedAt === undefined ? {} : { startedAt }),\n ...(finishedAt === undefined ? {} : { finishedAt }),\n };\n}\n","// Адаптер CI SourceCraft библиотеки @smwb/onreel-git-mcp: прогоны, задания и логи репозитория через REST API,\n// токен — Bearer (#16, D-006). Свой: в onreel CI трекеров нет.\nimport { logOf, logWindow } from './ci.lib.ts';\nimport { ciJobFilterSchema, ciRunFilterSchema } from './ci.schema.ts';\nimport type { CiJob, CiJobFilter, CiRun } from './ci.schema.ts';\nimport type { CiAdapter, CiCapabilities, CiDefinition, CiRunQuery, CiTriggerInput } from './ci.types.ts';\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { SOURCECRAFT_CI_STATUSES, SOURCECRAFT_RUN_EVENTS } from './mapping.const.ts';\nimport { CI_LOG_PAGES_MAX, CI_LOG_READ_MAX_BYTES, CI_LOG_TIMEOUT_MS } from './tracker.const.ts';\nimport { TrackerError, assertListQuery, inTimeRange, isRecord, lookup, requireTarget, stringList, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext } from './tracker.types.ts';\n\n// CI SourceCraft (D-006): прогоны репозитория. Список отдаёт только page_size и page_token, поэтому каждый\n// фильтр проверяется по полученной странице (§3.6). Заданием считается куб задачи workflow: отдельного списка\n// заданий у площадки нет, страница строится поверх дерева прогона, а ключ задания — путь\n// `<run>/<workflow>/<task>/<cube>`, где каждой части соответствует encodeURIComponent. Логи приходят\n// страницами JSON, а не голым текстом, поэтому окно лога собирается по байтам UTF-8 здесь, а не в requestText.\n// Лог служебного куба (`#git-clone`, …) через API не читается — отказ unsupported без запроса. Фильтр\n// pullRequest идёт через id PR: у прогона pull.id живой, а pull.slug пустой. Перезапуска и отмены в публичном\n// API нет (§1.3), и эти методы отказывают до всякого запроса (§3.6).\n\nconst DEFAULT_API = 'https://api.sourcecraft.tech';\nconst TARGET = /^[\\w.-]+\\/[\\w.-]+$/;\n\n/** Ключ прогона — счётчик запуска (`slug`); иного вида у прогона быть не может. */\nconst RUN_SLUG = /^\\d{1,20}$/;\n\n/** Ключ PR — slug репозитория, как в адаптере задач (§3.7). */\nconst PR_SLUG = /^[\\w-]{1,100}$/;\n\n/** Ключ задания: четыре части через `/`. Слаги кодируются, поэтому `/` внутри слаги разбору не мешает. */\nconst JOB_KEY = /^([^/]+)\\/([^/]+)\\/([^/]+)\\/([^/]+)$/;\n\n/** Значение user.slug пользователя вне площадки: его в единой модели не показывают. */\nconst EXTERNAL_USER = '<external-user>';\n\n/** Фильтр списка заданий — смещение в плоском списке кубов прогона. */\nconst JOB_OFFSET_CURSOR = /^o:(\\d{1,15})$/;\n\n/** Имена фильтров схемы — вселенная отказа; у прогонов действующие — без ref и sha: их в модели прогона нет (§1.3). */\nconst RUN_FILTER_NAMES = ciRunFilterSchema.options;\nconst RUN_FILTERS = RUN_FILTER_NAMES.filter((name) => name !== 'ref' && name !== 'sha');\nconst JOB_FILTER_NAMES = ciJobFilterSchema.options;\nconst JOB_FILTERS: readonly CiJobFilter[] = ['status'];\n\n/** Возможности CI SourceCraft (#16): все фильтры по странице, лог живой с дочитыванием, ни перезапуска, ни отмены. */\nconst CAPABILITIES: CiCapabilities = {\n workflows: false,\n runs: { filters: RUN_FILTERS, clientSide: RUN_FILTERS, sorts: [] },\n jobs: { filters: JOB_FILTERS, clientSide: JOB_FILTERS, sorts: [] },\n log: { live: true, cursor: true },\n trigger: { supported: true, workflows: 'many', inputs: true, tags: true },\n rerun: { all: false, failedOnly: false, job: false, debug: false },\n cancel: { run: false, job: false },\n};\n\nexport function sourcecraftCi(): CiDefinition {\n return { capabilities: CAPABILITIES, create: (context) => createSourceCraftCiAdapter(context) };\n}\n\n/** Части ключа задания: прогон, workflow, задача и куб. */\ntype JobPath = { run: string; workflow: string; task: string; cube: string };\n\nfunction createSourceCraftCiAdapter({ connection, fetch }: AdapterContext): CiAdapter {\n const target = requireTarget(connection.target, 'org/repo репозитория SourceCraft');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target SourceCraft — org/repo.');\n const repo = `${baseUrl(connection.url, DEFAULT_API)}/repos/${target}`;\n const root = `${repo}/cicd`;\n const headers = { authorization: `Bearer ${connection.token ?? ''}` };\n const missingRun = (key: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В SourceCraft нет прогона ${key}.` });\n const missingJob = (key: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В SourceCraft нет задания ${key}.` });\n const missingWorkflow = (run: string, workflow: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В прогоне ${run} SourceCraft нет workflow ${workflow}.` });\n const runKey = (key: string): string => {\n if (!RUN_SLUG.test(key)) throw new TrackerError('not_found', `В SourceCraft нет прогона ${key}.`);\n return key;\n };\n const jobPath = (key: string): JobPath => {\n const match = JOB_KEY.exec(key);\n if (match === null) throw new TrackerError('not_found', `В SourceCraft нет задания ${key}.`);\n const path: JobPath = { run: partOf(match[1], key), workflow: partOf(match[2], key), task: partOf(match[3], key), cube: partOf(match[4], key) };\n runKey(path.run);\n return path;\n };\n const getRun = async (key: string): Promise<CiRun> => runOf((await requestJson(`${root}/runs/${runKey(key)}`, { fetch, headers, missing: missingRun(key) })).body);\n /** Дерево workflow прогона: задачи с кубами. Слаги кодируются — среди них есть `#git-clone`. */\n const getWorkflow = async (run: string, workflow: string): Promise<Record<string, unknown>> => {\n const { body } = await requestJson(`${root}/runs/${runKey(run)}/${encodeURIComponent(workflow)}`, { fetch, headers, missing: missingWorkflow(run, workflow) });\n return isRecord(body) ? body : {};\n };\n /**\n * id PR по его ключу: фильтр pullRequest страницы идёт через run.pull.id, потому что у живого API у прогона\n * pull.id есть, а pull.slug пустой (M4, §3.7 C4). Чужой ключ — not_found, ответ без id — failed.\n */\n const pullIdOf = async (slug: string): Promise<string> => {\n if (!PR_SLUG.test(slug)) throw new TrackerError('invalid_request', `Ключ pull request SourceCraft — slug из букв, цифр, _ и - длиной до 100.`);\n const { body } = await requestJson(`${repo}/pulls/${slug}`, { fetch, headers, missing: { failure: 'not_found', message: `В SourceCraft нет pull request ${slug}.` } });\n const id = isRecord(body) ? text(body.id) : undefined;\n if (id === undefined) throw new TrackerError('failed', `Ответ SourceCraft на /pulls/${slug} не содержит id.`);\n return id;\n };\n /** Плоский список заданий прогона: кубы задач каждого workflow, в порядке прогона (§3.7 C4). */\n const flattenJobs = async (run: string): Promise<CiJob[]> => {\n const jobs: CiJob[] = [];\n for (const workflow of (await getRun(run)).workflows) {\n const tree = await getWorkflow(run, workflow);\n for (const task of recordList(tree.tasks)) {\n const taskSlug = text(task.slug);\n if (taskSlug === undefined) continue;\n for (const cube of recordList(task.cubes)) {\n const cubeSlug = text(cube.slug);\n if (cubeSlug === undefined) continue;\n jobs.push(jobOf(run, workflow, taskSlug, cubeSlug, cube));\n }\n }\n }\n return jobs;\n };\n return {\n listWorkflows: async () => {\n throw new TrackerError('unsupported', 'Прогоны CI SourceCraft: отдельного списка workflow нет, workflow есть у прогона.');\n },\n listRuns: async (query) => {\n assertListQuery('Прогоны CI SourceCraft', CAPABILITIES.runs, query, RUN_FILTER_NAMES);\n const pullId = query.pullRequest === undefined ? undefined : await pullIdOf(query.pullRequest);\n const params = new URLSearchParams({ page_size: String(query.limit) });\n if (query.cursor !== undefined) params.set('page_token', query.cursor);\n const { body } = await requestJson(`${root}/runs?${params.toString()}`, { fetch, headers });\n const record = isRecord(body) ? body : {};\n const items = recordList(record.runs)\n .map((raw) => pullSlugOf(runOf(raw), raw, pullId, query.pullRequest))\n .filter((run) => keepsRun(run, query));\n const token = text(record.next_page_token);\n return { items, ...(token === undefined ? {} : { nextCursor: token }) };\n },\n getRun,\n listJobs: async (runKeyValue, query) => {\n assertListQuery('Задания CI SourceCraft', CAPABILITIES.jobs, query, JOB_FILTER_NAMES);\n const jobs = await flattenJobs(runKey(runKeyValue));\n const from = offsetOf(query.cursor);\n const next = from + query.limit;\n const page = jobs.slice(from, next);\n const items = query.status === undefined ? page : page.filter((job) => query.status?.includes(job.status.category) === true);\n return { items, ...(next < jobs.length ? { nextCursor: `o:${String(next)}` } : {}) };\n },\n getJob: async (key) => {\n const path = jobPath(key);\n const tree = await getWorkflow(path.run, path.workflow);\n for (const task of recordList(tree.tasks)) {\n if (text(task.slug) !== path.task) continue;\n const cube = recordList(task.cubes).find((item) => text(item.slug) === path.cube);\n if (cube !== undefined) return jobOf(path.run, path.workflow, path.task, path.cube, cube);\n }\n throw new TrackerError('not_found', `В SourceCraft нет задания ${key}.`);\n },\n log: async (key, query) => {\n const parsed = jobPath(key);\n // Служебные кубы (`#git-clone`, …) в API логов не читаются: площадка отвечает 400 ValidationError (m2).\n if (parsed.cube.startsWith('#')) {\n throw new TrackerError('unsupported', `Лог задания SourceCraft ${key}: служебный куб, лог через API недоступен.`);\n }\n const window = logWindow(query);\n const path = pathOf(parsed);\n const tail = window.resume === undefined && window.from === 'tail';\n const first = window.resume?.page ?? 1;\n const deadline = Date.now() + CI_LOG_TIMEOUT_MS;\n let page = first;\n let skip = window.resume?.offset ?? 0;\n let kept: Uint8Array<ArrayBufferLike> = new Uint8Array(0);\n let dropped = 0;\n let seen = 0;\n let lastPage = first;\n let lastEnd = 0;\n let done = false;\n let unread = false;\n const encoder = new TextEncoder();\n const decoder = new TextDecoder('utf-8');\n for (;;) {\n // Начало и курсор останавливаются на набранном окне; хвост обязан дочитать страницы до конца, иначе\n // потеряется его конец — там обычно и лежит причина падения.\n if (!tail && kept.length >= window.bytes) {\n unread = true;\n break;\n }\n const { body } = await requestJson(`${root}/logs/${path}?page=${String(page)}`, { fetch, headers, missing: missingJob(key) });\n const record = isRecord(body) ? body : {};\n const data = encoder.encode(text(record.logs) ?? '');\n const rest = skip >= data.length ? new Uint8Array(0) : data.subarray(skip);\n // Хвост режется общим кольцевым буфером ниже: отрезанное начало учитывается в dropped, иначе truncated\n // соврал бы на первой же странице длиннее окна. Начало и курсор останавливаются на набранном bytes.\n let slice = rest;\n if (!tail) {\n const room = rest.subarray(0, Math.min(window.bytes - kept.length, rest.length));\n slice = room.subarray(0, room.length - trailingByte(room));\n }\n const merged = concat(kept, slice);\n if (merged.length > window.bytes) {\n const fitted = merged.subarray(merged.length - window.bytes);\n dropped += merged.length - fitted.length;\n kept = fitted;\n } else {\n kept = merged;\n }\n seen += data.length;\n // Курсор указывает на место сразу за выданным окном: у хвоста это конец прочитанной страницы, у начала\n // и курсора — байт последнего целого символа.\n lastPage = page;\n lastEnd = tail ? data.length : skip + slice.length;\n skip = 0;\n done = record.done === true;\n // Начало и курсор взяли страницу не целиком (край окна упёрся в символ UTF-8 или потолок окна): за\n // курсором остаётся текст, а начало следующей страницы дало бы разрыв в окне — останавливаемся, дочиты-\n // вание идёт с курсора этого места (M1, D-006).\n if (!tail && rest.length > slice.length) {\n unread = true;\n break;\n }\n // Страницу ещё дописывают: запрос следующих страниц площадка отдаёт 404, дальше не читаем (§1.3).\n if (done || record.page_complete === false) break;\n // Пределы чтения (m4, D-006): не больше CI_LOG_PAGES_MAX страниц, CI_LOG_READ_MAX_BYTES байт на лог\n // и CI_LOG_TIMEOUT_MS на вызов; дальше — truncated с курсором, дочитывание следующим вызовом.\n if (page - first + 1 >= CI_LOG_PAGES_MAX || seen >= CI_LOG_READ_MAX_BYTES || Date.now() >= deadline) {\n unread = true;\n break;\n }\n page += 1;\n }\n return logOf({\n text: decoder.decode(kept.subarray(leadingByte(kept))),\n truncated: dropped > 0 || unread,\n complete: done,\n page: lastPage,\n end: lastEnd,\n more: unread,\n // Размер всего лога известен, только если с первой страницы прочитали их все.\n size: window.resume === undefined && !unread ? seen : undefined,\n // Страниц было прочитано больше окна: начало хвоста отрезано кольцевым буфером, и первая неполная\n // строка уходит из окна даже когда за ним ещё есть страницы (default startCut там молчит).\n startCut: tail && dropped > 0,\n raw: query.raw ?? false,\n });\n },\n trigger: async (input: CiTriggerInput) => {\n const workflows = input.workflows ?? [];\n if (workflows.length === 0) throw new TrackerError('invalid_request', 'Запуск CI SourceCraft: нужен хотя бы один workflow.');\n const values = Object.entries(input.inputs ?? {}).map(([name, value]) => ({ name, value }));\n const head = input.refType === 'tag' ? { tag: input.ref } : { branch: input.ref };\n const { body } = await requestJson(`${root}/runs`, { fetch, headers, method: 'POST', body: { head, workflows: workflows.map((name) => ({ name, values })) } });\n return { run: runOf(body) };\n },\n // Публичный API SourceCraft не умеет ни перезапускать, ни отменять (§1.3): отказ без запроса (§3.6).\n rerun: async () => {\n throw new TrackerError('unsupported', 'Перезапуск прогона CI SourceCraft недоступен: у площадки нет такого запроса в API.');\n },\n rerunJob: async () => {\n throw new TrackerError('unsupported', 'Перезапуск задания CI SourceCraft недоступен: у площадки нет такого запроса в API.');\n },\n cancel: async () => {\n throw new TrackerError('unsupported', 'Отмена прогона CI SourceCraft недоступна: у площадки нет такого запроса в API.');\n },\n cancelJob: async () => {\n throw new TrackerError('unsupported', 'Отмена задания CI SourceCraft недоступна: у площадки нет такого запроса в API.');\n },\n };\n}\n\n/** Часть ключа задания: проценты раскрыты; пустая часть или битая процентовка — «нет задания», как и любой чужой ключ. */\nfunction partOf(value: string | undefined, key: string): string {\n const refusal = new TrackerError('not_found', `В SourceCraft нет задания ${key}.`);\n if (value === undefined) throw refusal;\n let decoded: string;\n try {\n decoded = decodeURIComponent(value);\n } catch {\n throw refusal;\n }\n if (decoded === '') throw refusal;\n return decoded;\n}\n\n/** Путь задания в адресе логов: каждая часть через encodeURIComponent, как и в ключе. */\nfunction pathOf(path: JobPath): string {\n return [path.run, path.workflow, path.task, path.cube].map(encodeURIComponent).join('/');\n}\n\n/** Массив записей из поля ответа: не-записи отбрасываются, порядок сохраняется. */\nfunction recordList(value: unknown): Record<string, unknown>[] {\n return Array.isArray(value) ? value.filter(isRecord) : [];\n}\n\n/** Смещение плоского списка заданий; чужой курсор — начало списка. */\nfunction offsetOf(cursor: string | undefined): number {\n if (cursor === undefined) return 0;\n const match = JOB_OFFSET_CURSOR.exec(cursor);\n if (match === null) return 0;\n const from = Number(match[1]);\n return Number.isSafeInteger(from) && from >= 0 ? from : 0;\n}\n\n/** Прогон SourceCraft → CiRun единой модели: ref и sha у прогона нет, ссылку даёт потребитель (Q9). */\nfunction runOf(raw: unknown): CiRun {\n const item = isRecord(raw) ? raw : {};\n const key = text(item.slug) ?? '?';\n const rawStatus = text(item.status) ?? 'unknown';\n const rawEvent = text(item.event_type);\n const user = isRecord(item.user) ? text(item.user.slug) : undefined;\n const pull = isRecord(item.pull) ? text(item.pull.slug) : undefined;\n const dates = isRecord(item.dates) ? item.dates : {};\n const createdAt = toTimestamp(dates.created_at);\n const startedAt = toTimestamp(dates.started_at);\n const finishedAt = toTimestamp(dates.finished_at);\n const updatedAt = toTimestamp(dates.updated_at);\n const errors = stringList(item.error_messages);\n return {\n key,\n ...(RUN_SLUG.test(key) ? { number: Number(key) } : {}),\n workflows: stringList(recordList(item.workflows).map((workflow) => workflow.slug)),\n status: { category: lookup(SOURCECRAFT_CI_STATUSES, rawStatus, 'running'), name: rawStatus },\n ...(rawEvent === undefined ? {} : { event: { category: lookup(SOURCECRAFT_RUN_EVENTS, rawEvent, 'other'), name: rawEvent } }),\n ...(user === undefined || user === EXTERNAL_USER ? {} : { actor: user }),\n ...(pull === undefined ? {} : { pullRequest: pull }),\n ...(errors.length === 0 ? {} : { errors }),\n links: [],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(startedAt === undefined ? {} : { startedAt }),\n ...(finishedAt === undefined ? {} : { finishedAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n };\n}\n\n/** Куб задачи workflow → CiJob: ключ — путь прогона, stage — `<workflow>/<task>` (§3.7 C4). */\nfunction jobOf(run: string, workflow: string, task: string, cubeSlug: string, cube: Record<string, unknown>): CiJob {\n const rawStatus = text(cube.status) ?? 'unknown';\n const dates = isRecord(cube.dates) ? cube.dates : {};\n const createdAt = toTimestamp(dates.created_at);\n const startedAt = toTimestamp(dates.started_at);\n const finishedAt = toTimestamp(dates.finished_at);\n return {\n key: [run, workflow, task, cubeSlug].map(encodeURIComponent).join('/'),\n runKey: run,\n name: cubeSlug,\n stage: `${workflow}/${task}`,\n status: { category: lookup(SOURCECRAFT_CI_STATUSES, rawStatus, 'running'), name: rawStatus },\n links: [],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(startedAt === undefined ? {} : { startedAt }),\n ...(finishedAt === undefined ? {} : { finishedAt }),\n };\n}\n\n/** Проверка прогона фильтрами страницы: status, event, workflow, actor, pullRequest и границы времени. */\nfunction keepsRun(run: CiRun, query: CiRunQuery): boolean {\n return (\n (query.status === undefined || query.status.includes(run.status.category)) &&\n (query.event === undefined || (run.event !== undefined && query.event.includes(run.event.category))) &&\n (query.workflow === undefined || run.workflows.includes(query.workflow)) &&\n (query.actor === undefined || run.actor === query.actor) &&\n (query.pullRequest === undefined || run.pullRequest === query.pullRequest) &&\n inTimeRange(run.createdAt, query.createdAfter, query.createdBefore) &&\n inTimeRange(run.updatedAt, query.updatedAfter, query.updatedBefore)\n );\n}\n\n/**\n * pullRequest прогона для фильтра: slug, если API его отдал; если slug пуст, а фильтр pullRequest разрешён\n * в id PR — ключ из фильтра (M4: у живого API у прогона pull.id есть, а pull.slug пустой, поэтому фильтр\n * и сравнение идут через id, а pullRequest заполняется разрешённым ключом).\n */\nfunction pullSlugOf(run: CiRun, raw: Record<string, unknown>, pullId: string | undefined, slug: string | undefined): CiRun {\n if (run.pullRequest !== undefined || pullId === undefined || slug === undefined) return run;\n const id = isRecord(raw.pull) ? text(raw.pull.id) : undefined;\n return id === pullId ? { ...run, pullRequest: slug } : run;\n}\n\n/** Сколько байт в начале окна — продолжение символа UTF-8, начатого до окна: окно начинается со следующего целого. */\nfunction leadingByte(window: Uint8Array): number {\n let count = 0;\n while (count < 3 && count < window.length && ((window[count] ?? 0) & 0xc0) === 0x80) count += 1;\n return count;\n}\n\n/** Сколько байт в конце окна — начало символа UTF-8, который в окно целиком не вошёл: он уходит в следующее. */\nfunction trailingByte(window: Uint8Array): number {\n for (let back = 1; back <= Math.min(4, window.length); back += 1) {\n const byte = window[window.length - back] ?? 0;\n if ((byte & 0xc0) === 0x80) continue;\n const size = byte >= 0xf0 ? 4 : byte >= 0xe0 ? 3 : byte >= 0xc0 ? 2 : 1;\n return size > back ? back : 0;\n }\n return 0;\n}\n\nfunction concat(head: Uint8Array, tail: Uint8Array): Uint8Array {\n if (head.length === 0) return tail;\n if (tail.length === 0) return head;\n const merged = new Uint8Array(head.length + tail.length);\n merged.set(head, 0);\n merged.set(tail, head.length);\n return merged;\n}\n","// Реестр трекеров библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/registry.lib.ts — дословная копия. Побочных эффектов при импорте нет:\n// реестр пуст, наполняется только явными вызовами registerTracker/registerBuiltinTrackers (R-001).\nimport type { TrackerDefinition } from './tracker.types.ts';\n\n// Реестр трекеров (D-350): вид подключения → определение. Потребитель работает только через него;\n// новый трекер — модуль с `TrackerDefinition` и одна строка регистрации в `builtin.lib.ts`.\n\nconst definitions = new Map<string, TrackerDefinition>();\n\n/** Регистрирует трекер; повтор того же вида — ошибка сборки, а не замена. */\nexport function registerTracker(definition: TrackerDefinition): void {\n const kind = definition.descriptor.tracker;\n if (definitions.has(kind)) throw new Error(`Трекер ${kind} уже зарегистрирован.`);\n definitions.set(kind, definition);\n}\n\nexport function findTracker(kind: string): TrackerDefinition | undefined {\n return definitions.get(kind);\n}\n\nexport function listTrackers(): TrackerDefinition[] {\n return [...definitions.values()];\n}\n","// Схемы zod pull request-ов единой модели библиотеки @smwb/onreel-git-mcp — свои (#15).\n// Выведенные типы — здесь же (фасет schema, pet:D-037).\nimport { z } from 'zod';\nimport { issueLinkSchema, timestampSchema } from '../contract/contract.schema.ts';\n\n/** Категория состояния PR единой модели (D-005); своё имя трекер отдаёт в status.name. */\nexport const pullRequestStatusCategorySchema = z.enum(['draft', 'open', 'merged', 'closed']);\nexport const pullRequestFilterSchema = z.enum(['status', 'author', 'source', 'target', 'labels', 'search', 'createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore']);\nexport const pullRequestSortFieldSchema = z.enum(['created', 'updated', 'title']);\nexport const mergeMethodSchema = z.enum(['merge', 'squash', 'rebase']);\n\nexport const pullRequestSchema = z.object({\n /** Номер PR в своём трекере: GitHub number, GitLab iid, SourceCraft slug; для клиента непрозрачная строка. */\n key: z.string().min(1).max(200),\n title: z.string().min(1).max(1024),\n description: z.string().max(1_048_576).optional(),\n status: z.object({ category: pullRequestStatusCategorySchema, name: z.string().min(1).max(200) }),\n /** Автор — логин или slug трекера. */\n author: z.string().min(1).max(200).optional(),\n /** Ветка-источник и целевая ветка — имя без refs/heads/. */\n source: z.string().min(1).max(500),\n target: z.string().min(1).max(500),\n /** Коммит головы источника. */\n headSha: z.string().regex(/^[0-9a-f]{7,64}$/).optional(),\n labels: z.array(z.string().min(1).max(200)).max(100),\n /** Запрошенные ревьюеры; нет — трекер их в PR не отдаёт. */\n reviewers: z.array(z.string().min(1).max(200)).max(100).optional(),\n links: z.array(issueLinkSchema).max(100),\n createdAt: timestampSchema.optional(),\n updatedAt: timestampSchema.optional(),\n mergedAt: timestampSchema.optional(),\n closedAt: timestampSchema.optional(),\n});\n\nexport type PullRequestStatusCategory = z.infer<typeof pullRequestStatusCategorySchema>;\nexport type PullRequestFilter = z.infer<typeof pullRequestFilterSchema>;\nexport type PullRequestSortField = z.infer<typeof pullRequestSortFieldSchema>;\nexport type MergeMethod = z.infer<typeof mergeMethodSchema>;\nexport type PullRequest = z.infer<typeof pullRequestSchema>;\n","// Адаптер pull request-ов GitHub библиотеки @smwb/onreel-git-mcp — свой (#15): раздел pulls определения\n// трекера (D-005) на том же подключении, что и задачи; PR репозитория `owner/repo` через REST API.\nimport type { IssueComment } from '../contract/contract.types.ts';\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { pullRequestFilterSchema, pullRequestStatusCategorySchema } from './pull.schema.ts';\nimport type { PullRequest, PullRequestStatusCategory } from './pull.schema.ts';\nimport type { MergeInput, NewPullRequestInput, PullRequestAdapter, PullRequestCapabilities, PullRequestDefinition, PullRequestPatchInput, PullRequestQuery } from './pull.types.ts';\nimport { COMMENT_FILTERS } from './tracker.const.ts';\nimport { TrackerError, assertCommentQuery, assertListQuery, containsText, inTimeRange, isRecord, isoTime, requireTarget, stringList, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext } from './tracker.types.ts';\n\n// Список PR идёт через `/pulls`: параметров автора, меток, поиска и времени у него нет, поэтому эти фильтры\n// проверяются по полученной странице (D-004). Черновик и «готов» переводятся только GraphQL, а ветка-источник\n// при слиянии не удаляется — отказы по capability до записи, снятие черновика — после чтения PR. Комментарии PR лежат под\n// задачиным `/issues/{n}/comments`, а не под `/pulls`.\n\nconst DEFAULT_API = 'https://api.github.com';\nconst TARGET = /^[\\w.-]+\\/[\\w.-]+$/;\nconst NUMBER = /^[1-9]\\d{0,19}$/;\nconst SHA = /^[0-9a-f]{7,64}$/;\nconst LIST_SUBJECT = 'PR GitHub';\nconst COMMENTS_SUBJECT = 'Комментарии PR GitHub';\n\n/** Возможности PR GitHub (§3.6): автор, метки, поиск и время — по странице; сортировка — created и updated. */\nconst PULL_CAPABILITIES: PullRequestCapabilities = {\n list: {\n filters: pullRequestFilterSchema.options,\n clientSide: ['status', 'author', 'labels', 'search', 'createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore'],\n sorts: ['created', 'updated'],\n },\n comments: { filters: COMMENT_FILTERS, clientSide: [], order: ['asc'] },\n create: true,\n createDraft: true,\n update: ['title', 'description', 'target'],\n statuses: ['open', 'closed'],\n comment: true,\n merge: ['merge', 'squash', 'rebase'],\n deleteSourceOnMerge: false,\n};\n\nexport function githubPulls(): PullRequestDefinition {\n return {\n capabilities: PULL_CAPABILITIES,\n create: (context) => createGithubPullAdapter(context),\n };\n}\n\nfunction createGithubPullAdapter({ connection, fetch }: AdapterContext): PullRequestAdapter {\n const target = requireTarget(connection.target, 'owner/repo репозитория GitHub');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target GitHub — owner/repo.');\n const api = baseUrl(connection.url, DEFAULT_API);\n const root = `${api}/repos/${target}/pulls`;\n const issues = `${api}/repos/${target}/issues`;\n // `head` списка — `owner:ветка`: источник ищется в том же владельце, что и целевой репозиторий.\n const owner = target.split('/')[0] ?? target;\n const headers = {\n accept: 'application/vnd.github+json',\n 'x-github-api-version': '2022-11-28',\n ...(connection.token === undefined || connection.token === '' ? {} : { authorization: `Bearer ${connection.token}` }),\n };\n const missing = (key: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В GitHub нет PR ${key}.` });\n const number = (key: string): string => {\n if (!NUMBER.test(key)) throw new TrackerError('not_found', `В GitHub нет PR ${key}.`);\n return key;\n };\n const getPull = async (key: string): Promise<PullRequest> =>\n pullOf((await requestJson(`${root}/${number(key)}`, { fetch, headers, missing: missing(key) })).body);\n return {\n list: async (query) => {\n assertListQuery(LIST_SUBJECT, PULL_CAPABILITIES.list, query, pullRequestFilterSchema.options);\n const status = usedStatuses(query.status);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({ state: stateFilter(status), per_page: String(query.limit), page: String(page) });\n if (query.source !== undefined) params.set('head', `${owner}:${query.source}`);\n if (query.target !== undefined) params.set('base', query.target);\n if (query.sort !== undefined) {\n params.set('sort', query.sort.field);\n params.set('direction', query.sort.direction ?? 'desc');\n }\n const { body, headers: responseHeaders } = await requestJson(`${root}?${params.toString()}`, { fetch, headers });\n const items = (Array.isArray(body) ? body : []).map(pullOf).filter((pull) => matchesPage(pull, query, status));\n return { items, ...nextOf(responseHeaders.get('link'), page) };\n },\n get: (key) => getPull(key),\n create: async (input) => pullOf((await requestJson(root, { fetch, headers, method: 'POST', body: createBody(input) })).body),\n update: async (key, patch) => {\n // Черновик через REST не ставится; снятие черновика — тем более, и оно требует текущего состояния PR.\n if (patch.status === 'draft') throw new TrackerError('unsupported', 'PR GitHub: перевод в черновик недоступен через REST.');\n const current = patch.status === 'open' ? await getPull(key) : undefined;\n if (current?.status.category === 'draft') throw new TrackerError('unsupported', 'PR GitHub: снятие черновика недоступно через REST.');\n // Переход «в то же состояние» без других правок не пишет повторно: open на открытом PR — только GET.\n if (current !== undefined && current.status.category === 'open' && patch.title === undefined && patch.description === undefined && patch.target === undefined) return current;\n return pullOf((await requestJson(`${root}/${number(key)}`, { fetch, headers, method: 'PATCH', body: patchBody(patch), missing: missing(key) })).body);\n },\n merge: async (key, input) => {\n if (input.deleteSource === true) throw new TrackerError('unsupported', 'PR GitHub: удаление ветки-источника при слиянии недоступно.');\n if (input.method !== undefined && !PULL_CAPABILITIES.merge.includes(input.method)) {\n throw new TrackerError('unsupported', `PR GitHub: слияние способом ${input.method} не поддерживается.`);\n }\n // Ответ `/merge` — про слияние, а не про PR: состояние перечитывается get-ом.\n await requestJson(`${root}/${number(key)}/merge`, { fetch, headers, method: 'PUT', body: mergeBody(input), conflictOn: [405, 409], missing: missing(key) });\n return getPull(key);\n },\n comments: async (key, query) => {\n assertCommentQuery(COMMENTS_SUBJECT, PULL_CAPABILITIES.comments, query);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({ per_page: String(query.limit), page: String(page) });\n // `since` — изменения не раньше момента; порядок у GitHub один, по id (§3.7 B2).\n if (query.updatedAfter !== undefined) params.set('since', isoTime(query.updatedAfter));\n const { body, headers: responseHeaders } = await requestJson(`${issues}/${number(key)}/comments?${params.toString()}`, { fetch, headers, missing: missing(key) });\n return { items: (Array.isArray(body) ? body : []).map(commentOf), ...nextOf(responseHeaders.get('link'), page) };\n },\n comment: async (key, body) => commentOf((await requestJson(`${issues}/${number(key)}/comments`, { fetch, headers, method: 'POST', body: { body }, missing: missing(key) })).body),\n };\n}\n\nfunction pageOf(cursor: string | undefined): number {\n const page = cursor === undefined ? 1 : Number(cursor);\n return Number.isInteger(page) && page >= 1 ? page : 1;\n}\n\n/** Следующая страница по `Link`; курсор — номер страницы (§1.1). */\nfunction nextOf(link: string | null, page: number): { nextCursor?: string } {\n return link !== null && /rel=\"next\"/.test(link) ? { nextCursor: String(page + 1) } : {};\n}\n\n/** Категории состояния → `state` списка: черновик и открытый — open, слитый и закрытый — closed;\n * смешанный запрос — all, лишнее отсеет страница. */\nfunction stateFilter(status: readonly PullRequestStatusCategory[] | undefined): string {\n if (status === undefined) return 'all';\n if (status.every((item) => item === 'draft' || item === 'open')) return 'open';\n if (status.every((item) => item === 'merged' || item === 'closed')) return 'closed';\n return 'all';\n}\n\n/** Фильтры, которых нет в параметрах `/pulls`: категория (черновик и слитый видны только по полям PR),\n * автор, метки, поиск и границы времени — по полученной странице (D-004, §3.7 B2). */\nfunction matchesPage(pull: PullRequest, query: PullRequestQuery, status: readonly PullRequestStatusCategory[] | undefined): boolean {\n if (status !== undefined && !status.includes(pull.status.category)) return false;\n if (query.author !== undefined && pull.author !== query.author) return false;\n if (query.labels !== undefined && !query.labels.every((label) => pull.labels.includes(label))) return false;\n if (query.search !== undefined && !containsText([pull.title, pull.description], query.search)) return false;\n return inTimeRange(pull.createdAt, query.createdAfter, query.createdBefore) && inTimeRange(pull.updatedAt, query.updatedAfter, query.updatedBefore);\n}\n\n/** Статусы списка: пустой массив — без фильтра; неизвестная категория — invalid_request до запроса. */\nfunction usedStatuses(status: readonly PullRequestStatusCategory[] | undefined): readonly PullRequestStatusCategory[] | undefined {\n if (status === undefined || status.length === 0) return undefined;\n for (const item of status) {\n if (!pullRequestStatusCategorySchema.options.includes(item)) {\n throw new TrackerError('invalid_request', `PR GitHub: неизвестная категория статуса ${String(item)}.`);\n }\n }\n return status;\n}\n\n/** Тело создания PR: `head` — ветка источника своего репозитория, черновик ставится только когда запрошен. */\nfunction createBody(input: NewPullRequestInput): Record<string, unknown> {\n return {\n title: input.title,\n head: input.source,\n base: input.target,\n ...(input.description === undefined ? {} : { body: input.description }),\n ...(input.draft === true ? { draft: true } : {}),\n };\n}\n\n/** Тело PATCH: поля правки плюс переход состояния — open или closed, черновик отсекается выше. */\nfunction patchBody(patch: PullRequestPatchInput): Record<string, unknown> {\n return {\n ...(patch.title === undefined ? {} : { title: patch.title }),\n ...(patch.description === undefined ? {} : { body: patch.description }),\n ...(patch.target === undefined ? {} : { base: patch.target }),\n ...(patch.status === undefined ? {} : { state: patch.status === 'closed' ? 'closed' : 'open' }),\n };\n}\n\n/** Тело слияния: способ, ожидаемая голова и сообщение коммита — первая строка заголовок, остальное текст. */\nfunction mergeBody(input: MergeInput): Record<string, unknown> {\n const lines = input.message?.split('\\n') ?? [];\n return {\n ...(input.method === undefined ? {} : { merge_method: input.method }),\n ...(input.headSha === undefined ? {} : { sha: input.headSha }),\n ...(input.message === undefined ? {} : { commit_title: lines[0] ?? '' }),\n ...(lines.length > 1 ? { commit_message: lines.slice(1).join('\\n') } : {}),\n };\n}\n\nfunction pullOf(raw: unknown): PullRequest {\n const item = isRecord(raw) ? raw : {};\n const head = isRecord(item.head) ? item.head : {};\n const base = isRecord(item.base) ? item.base : {};\n const key = typeof item.number === 'number' ? String(item.number) : '?';\n const description = text(item.body);\n const author = isRecord(item.user) ? text(item.user.login) : undefined;\n const sha = text(head.sha);\n const url = text(item.html_url);\n const createdAt = toTimestamp(item.created_at);\n const updatedAt = toTimestamp(item.updated_at);\n const mergedAt = toTimestamp(item.merged_at);\n const closedAt = toTimestamp(item.closed_at);\n const closed = item.state === 'closed';\n const merged = item.merged_at !== undefined && item.merged_at !== null;\n // Состояние PR: слитый закрыт вместе с merged_at, черновик — открытый со своим флагом.\n const category: PullRequestStatusCategory = closed ? merged ? 'merged' : 'closed' : item.draft === true ? 'draft' : 'open';\n return {\n key,\n title: text(item.title) ?? key,\n ...(description === undefined ? {} : { description }),\n status: { category, name: category },\n ...(author === undefined ? {} : { author }),\n source: text(head.ref) ?? '?',\n target: text(base.ref) ?? '?',\n ...(sha !== undefined && SHA.test(sha) ? { headSha: sha } : {}),\n labels: Array.isArray(item.labels) ? stringList(item.labels.map((label) => (isRecord(label) ? label.name : label))) : [],\n reviewers: logins(item.requested_reviewers),\n links: url === undefined ? [] : [{ url, title: 'GitHub' }],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n ...(mergedAt === undefined ? {} : { mergedAt }),\n ...(closedAt === undefined ? {} : { closedAt }),\n };\n}\n\n/** Логины запрошенных ревьюеров: GitHub отдаёт их массивом объектов. */\nfunction logins(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n const names = value.map((item) => (isRecord(item) ? text(item.login) : undefined));\n return [...new Set(names.filter((name): name is string => name !== undefined))];\n}\n\nfunction commentOf(raw: unknown): IssueComment {\n const item = isRecord(raw) ? raw : {};\n const author = isRecord(item.user) ? text(item.user.login) : undefined;\n const createdAt = toTimestamp(item.created_at);\n return { id: typeof item.id === 'number' ? String(item.id) : '?', ...(author === undefined ? {} : { author }), body: typeof item.body === 'string' ? item.body : '', ...(createdAt === undefined ? {} : { createdAt }) };\n}\n","// Адаптер GitHub библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/github.lib.ts — дословная копия, импорт типов из среза контракта библиотеки;\n// возможности фильтров, маршрутизация /issues ↔ Search API и since комментариев — свои (#14).\nimport type { Issue, IssueComment, IssuePriority, IssueStatusCategory } from '../contract/contract.types.ts';\nimport { githubCi } from './github-ci.lib.ts';\nimport { githubPulls } from './github-pull.lib.ts';\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { GITHUB_CLOSE_REASONS, GITHUB_IN_PROGRESS_LABEL, GITHUB_PRIORITY_LABELS } from './mapping.const.ts';\nimport { ISSUE_FILTERS } from './tracker.const.ts';\nimport { TrackerError, assertCommentQuery, assertListQuery, isRecord, isoTime, lookup, priorityName, quoted, requireTarget, stringList, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext, IssueCapabilities, IssuePatchInput, IssueQuery, TrackerAdapter, TrackerDefinition, TrackerPage } from './tracker.types.ts';\n\n// Трекер GitHub (D-350): задачи репозитория `owner/repo` через REST API. У GitHub статус — open или closed\n// с причиной: «в работе» держится меткой `in progress`, приоритет — меткой `priority: <имя>`; обе метки\n// читаются в поля единой модели и из `labels` убираются. Pull request-ы в списке задач пропускаются.\n// Список идёт через `/issues`, а поиск по тексту и границы created/updated-before есть только в Search API (#14).\n\nconst DEFAULT_API = 'https://api.github.com';\nconst TARGET = /^[\\w.-]+\\/[\\w.-]+$/;\nconst NUMBER = /^[1-9]\\d{0,14}$/;\nconst LIST_SUBJECT = 'Задачи GitHub';\nconst COMMENTS_SUBJECT = 'Комментарии GitHub';\n\nexport function githubTracker(): TrackerDefinition {\n // Возможности по задачам (§3.6): статус GitHub не фильтрует, поэтому проверяется по полученной странице;\n // комментарии — только по времени изменения и только в порядке asc.\n const issues: IssueCapabilities = {\n list: { filters: ISSUE_FILTERS, clientSide: ['status'], sorts: ['created', 'updated', 'comments'] },\n comments: { filters: ['updatedAfter'], clientSide: [], order: ['asc'] },\n };\n return {\n descriptor: {\n tracker: 'github',\n title: 'GitHub',\n fields: [\n { name: 'target', required: true, secret: false },\n { name: 'token', required: true, secret: true },\n { name: 'url', required: false, secret: false },\n ],\n features: { create: true, update: true, comment: true, priority: true, labels: true, assignee: true, statuses: ['open', 'in_progress', 'done', 'declined'] },\n },\n create: (context) => createGithubAdapter(context, issues),\n issues,\n pulls: githubPulls(),\n ci: githubCi(),\n };\n}\n\nfunction createGithubAdapter({ connection, fetch }: AdapterContext, capabilities: IssueCapabilities): TrackerAdapter {\n const target = requireTarget(connection.target, 'owner/repo репозитория GitHub');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target GitHub — owner/repo.');\n const api = baseUrl(connection.url, DEFAULT_API);\n const root = `${api}/repos/${target}/issues`;\n const headers = {\n accept: 'application/vnd.github+json',\n 'x-github-api-version': '2022-11-28',\n ...(connection.token === undefined || connection.token === '' ? {} : { authorization: `Bearer ${connection.token}` }),\n };\n const number = (key: string): string => {\n if (!NUMBER.test(key)) throw new TrackerError('unknown_issue', `В GitHub нет задачи ${key}.`);\n return key;\n };\n const rawOf = async (key: string): Promise<Record<string, unknown>> => {\n const { body } = await requestJson(`${root}/${number(key)}`, { fetch, headers, missingIsIssue: true });\n return isRecord(body) ? body : {};\n };\n return {\n list: async (query) => {\n assertListQuery(LIST_SUBJECT, capabilities.list, query, ISSUE_FILTERS);\n assertCsvLabels(query.labels);\n const page = pageOf(query.cursor);\n // Search API нужен, когда запрошено то, чего `/issues` не умеет: текст поиска и границы created/updated-before (§3.7 A2).\n const search = needsSearch(query);\n const params = search ? searchParams(target, query, page) : issuesParams(query, page);\n const { body, headers: responseHeaders } = await requestJson(`${search ? `${api}/search/issues` : root}?${params.toString()}`, { fetch, headers });\n return issuePageOf(rowsOf(body, search), query, responseHeaders.get('link') ?? '', page);\n },\n get: async (key) => issueOf(await rawOf(key)),\n create: async (input) => {\n const labels = composeLabels(input.labels ?? [], input.priority, undefined);\n const body = {\n title: input.title,\n ...(input.description === undefined ? {} : { body: input.description }),\n ...(labels.length === 0 ? {} : { labels }),\n ...(input.assignee === undefined ? {} : { assignees: [input.assignee] }),\n };\n return issueOf((await requestJson(root, { fetch, headers, method: 'POST', body })).body);\n },\n update: async (key, patch) => {\n const current = patch.labels === undefined && patch.priority === undefined && patch.status === undefined ? undefined : issueOf(await rawOf(key));\n const response = await requestJson(`${root}/${number(key)}`, { fetch, headers, method: 'PATCH', body: patchBody(patch, current), missingIsIssue: true });\n return issueOf(response.body);\n },\n comments: async (key, query) => {\n assertCommentQuery(COMMENTS_SUBJECT, capabilities.comments, query);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({ per_page: String(query.limit), page: String(page) });\n // `since` — изменения не раньше момента; порядок у GitHub один, по id (§3.7 A2).\n if (query.updatedAfter !== undefined) params.set('since', isoTime(query.updatedAfter));\n const { body, headers: responseHeaders } = await requestJson(`${root}/${number(key)}/comments?${params.toString()}`, { fetch, headers, missingIsIssue: true });\n return { items: (Array.isArray(body) ? body : []).map(commentOf), ...(/rel=\"next\"/.test(responseHeaders.get('link') ?? '') ? { nextCursor: String(page + 1) } : {}) };\n },\n comment: async (key, body) => commentOf((await requestJson(`${root}/${number(key)}/comments`, { fetch, headers, method: 'POST', body: { body }, missingIsIssue: true })).body),\n };\n}\n\nfunction pageOf(cursor: string | undefined): number {\n const page = cursor === undefined ? 1 : Number(cursor);\n return Number.isInteger(page) && page >= 1 ? page : 1;\n}\n\n/** Параметр `state` по запрошенным категориям; смешанный запрос — все, лишнее отсеет клиент. */\nfunction stateFilter(status: readonly IssueStatusCategory[] | undefined): string {\n if (status === undefined) return 'all';\n if (status.every((item) => item === 'open' || item === 'in_progress')) return 'open';\n if (status.every((item) => item === 'done' || item === 'declined')) return 'closed';\n return 'all';\n}\n\n/** Поиск по тексту и границы created/updated-before есть только в Search API — он и выбирает endpoint (§3.7 A2). */\nfunction needsSearch(query: IssueQuery): boolean {\n return query.search !== undefined || query.createdAfter !== undefined || query.createdBefore !== undefined || query.updatedBefore !== undefined;\n}\n\n/** CSV-параметр labels: запятая внутри метки читалась бы как разделитель списка — отказ до запроса (§3.2 R1). */\nfunction assertCsvLabels(labels: readonly string[] | undefined): void {\n if (labels?.some((label) => label.includes(',')) === true) throw new TrackerError('invalid_request', `${LIST_SUBJECT}: метка не должна содержать запятую.`);\n}\n\n/** Параметры `/issues`: сегодняшние плюс фильтры и сортировка, которые GitHub применяет сам. */\nfunction issuesParams(query: IssueQuery, page: number): URLSearchParams {\n const params = new URLSearchParams({ state: stateFilter(query.status), per_page: String(query.limit), page: String(page) });\n if (query.labels !== undefined && query.labels.length > 0) params.set('labels', query.labels.join(','));\n if (query.assignee !== undefined) params.set('assignee', query.assignee ?? 'none');\n if (query.author !== undefined) params.set('creator', query.author);\n if (query.updatedAfter !== undefined) params.set('since', isoTime(query.updatedAfter));\n if (query.sort !== undefined) {\n params.set('sort', query.sort.field);\n params.set('direction', query.sort.direction ?? 'desc');\n }\n return params;\n}\n\n/** Параметры поиска: `q` плюс страницы и сортировка с `order` вместо `direction`; без sort — created desc,\n * иначе GitHub сортирует по релевантности, а порядок по умолчанию у списка — новые первыми (§3.2 R4, §3.7 A2). */\nfunction searchParams(target: string, query: IssueQuery, page: number): URLSearchParams {\n const params = new URLSearchParams({ q: searchQuery(target, query), per_page: String(query.limit), page: String(page) });\n const sort = query.sort;\n params.set('sort', sort?.field ?? 'created');\n params.set('order', sort?.direction ?? 'desc');\n return params;\n}\n\n/** `q` поиска: репозиторий и тип, затем фильтры; свободный текст — одна фраза в кавычках (§3.2 R6). */\nfunction searchQuery(target: string, query: IssueQuery): string {\n const parts: string[] = [`repo:${target}`, 'is:issue'];\n const state = searchStateFilter(query.status);\n if (state !== undefined) parts.push(state);\n for (const label of query.labels ?? []) parts.push(`label:${quoted(label)}`);\n if (query.assignee !== undefined) parts.push(query.assignee === null ? 'no:assignee' : `assignee:${quoted(query.assignee)}`);\n if (query.author !== undefined) parts.push(`author:${quoted(query.author)}`);\n const created = timeRangeQualifier('created', query.createdAfter, query.createdBefore);\n if (created !== undefined) parts.push(created);\n const updated = timeRangeQualifier('updated', query.updatedAfter, query.updatedBefore);\n if (updated !== undefined) parts.push(updated);\n if (query.search !== undefined) parts.push(quoted(query.search));\n return parts.join(' ');\n}\n\n/** Границы поля времени в q: обе — один квалификатор-диапазон (два квалификатора GitHub объединяет через OR),\n * одна — >= / <=. ISO без кавычек: значение машинное ([0-9TZ:.-]), квалификатор из него не вставить (§3.2 R6). */\nfunction timeRangeQualifier(field: 'created' | 'updated', after: number | undefined, before: number | undefined): string | undefined {\n if (after !== undefined && before !== undefined) return `${field}:${isoTime(after)}..${isoTime(before)}`;\n if (after !== undefined) return `${field}:>=${isoTime(after)}`;\n if (before !== undefined) return `${field}:<=${isoTime(before)}`;\n return undefined;\n}\n\n/** Элементы ответа: `/issues` отдаёт массив, поиск — объект с `items` (§3.7 A2). */\nfunction rowsOf(body: unknown, search: boolean): readonly unknown[] {\n if (!search) return Array.isArray(body) ? body : [];\n return isRecord(body) && Array.isArray(body.items) ? body.items : [];\n}\n\n/** `is:open`/`is:closed` по запрошенным категориям; смешанный запрос — без него, лишнее отсеет страница. */\nfunction searchStateFilter(status: readonly IssueStatusCategory[] | undefined): string | undefined {\n if (status === undefined) return undefined;\n if (status.every((item) => item === 'open' || item === 'in_progress')) return 'is:open';\n if (status.every((item) => item === 'done' || item === 'declined')) return 'is:closed';\n return undefined;\n}\n\n/** Страница задач: pull request-ы пропускаются, статус сверяется с полученной страницей (§3.2 R5). */\nfunction issuePageOf(rows: readonly unknown[], query: IssueQuery, link: string, page: number): TrackerPage<Issue> {\n const items = rows.filter((row) => isRecord(row) && row.pull_request === undefined).map(issueOf);\n return {\n items: query.status === undefined ? items : items.filter((issue) => query.status?.includes(issue.status.category) === true),\n ...(/rel=\"next\"/.test(link) ? { nextCursor: String(page + 1) } : {}),\n };\n}\n\n/** Метки записи: пользовательские плюс служебные для приоритета и «в работе». */\nfunction composeLabels(plain: readonly string[], priority: IssuePriority | undefined, status: IssueStatusCategory | undefined): string[] {\n const priorityLabel = priority === undefined ? undefined : priorityName(GITHUB_PRIORITY_LABELS, priority);\n return [...plain, ...(priorityLabel === undefined ? [] : [priorityLabel]), ...(status === 'in_progress' ? [GITHUB_IN_PROGRESS_LABEL] : [])];\n}\n\nfunction patchBody(patch: IssuePatchInput, current: Issue | undefined): Record<string, unknown> {\n const status = patch.status ?? current?.status.category;\n const touchesLabels = patch.labels !== undefined || patch.priority !== undefined || patch.status !== undefined;\n return {\n ...(patch.title === undefined ? {} : { title: patch.title }),\n ...(patch.description === undefined ? {} : { body: patch.description }),\n ...(patch.status === undefined ? {} : { state: patch.status === 'done' || patch.status === 'declined' ? 'closed' : 'open', ...(patch.status === 'declined' ? { state_reason: 'not_planned' } : patch.status === 'done' ? { state_reason: 'completed' } : { state_reason: 'reopened' }) }),\n ...(touchesLabels ? { labels: composeLabels(patch.labels ?? current?.labels ?? [], patch.priority ?? current?.priority, status) } : {}),\n ...(patch.assignee === undefined ? {} : { assignees: patch.assignee === null ? [] : [patch.assignee] }),\n };\n}\n\nfunction issueOf(raw: unknown): Issue {\n const item = isRecord(raw) ? raw : {};\n const names = Array.isArray(item.labels) ? stringList(item.labels.map((label) => (isRecord(label) ? label.name : label))) : [];\n const closed = item.state === 'closed';\n const category: IssueStatusCategory = closed ? lookup(GITHUB_CLOSE_REASONS, item.state_reason, 'done') : names.includes(GITHUB_IN_PROGRESS_LABEL) ? 'in_progress' : 'open';\n const priority = names.map((name) => lookup<IssuePriority | undefined>(GITHUB_PRIORITY_LABELS, name, undefined)).find((value) => value !== undefined);\n const description = text(item.body);\n const assignee = isRecord(item.assignee) ? text(item.assignee.login) : undefined;\n const url = text(item.html_url);\n const createdAt = toTimestamp(item.created_at);\n const updatedAt = toTimestamp(item.updated_at);\n const number = typeof item.number === 'number' ? String(item.number) : '?';\n return {\n key: number,\n title: text(item.title) ?? number,\n ...(description === undefined ? {} : { description }),\n status: { category, name: closed ? `closed${typeof item.state_reason === 'string' ? ` (${item.state_reason})` : ''}` : category === 'in_progress' ? 'in progress' : 'open' },\n ...(priority === undefined ? {} : { priority }),\n labels: names.filter((name) => name !== GITHUB_IN_PROGRESS_LABEL && !Object.hasOwn(GITHUB_PRIORITY_LABELS, name)),\n ...(assignee === undefined ? {} : { assignee }),\n links: url === undefined ? [] : [{ url, title: 'GitHub' }],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n };\n}\n\nfunction commentOf(raw: unknown): IssueComment {\n const item = isRecord(raw) ? raw : {};\n const author = isRecord(item.user) ? text(item.user.login) : undefined;\n const createdAt = toTimestamp(item.created_at);\n return { id: typeof item.id === 'number' ? String(item.id) : '?', ...(author === undefined ? {} : { author }), body: typeof item.body === 'string' ? item.body : '', ...(createdAt === undefined ? {} : { createdAt }) };\n}\n","// Адаптер merge request-ов GitLab библиотеки @smwb/onreel-git-mcp — свой (#15): раздел pulls\n// определения трекера (D-005) на том же подключении, что и задачи; MR проекта через REST API v4.\nimport type { IssueComment } from '../contract/contract.types.ts';\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { GITLAB_DRAFT_PATTERN, GITLAB_DRAFT_PREFIX, GITLAB_MERGE_REQUEST_STATES } from './mapping.const.ts';\nimport { pullRequestFilterSchema, pullRequestStatusCategorySchema } from './pull.schema.ts';\nimport type { PullRequest, PullRequestStatusCategory } from './pull.schema.ts';\nimport type { PullRequestAdapter, PullRequestCapabilities, PullRequestDefinition, PullRequestPatchInput } from './pull.types.ts';\nimport { COMMENT_FILTERS } from './tracker.const.ts';\nimport { TrackerError, assertCommentQuery, assertListQuery, inTimeRange, isRecord, isoTime, lookup, requireTarget, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext } from './tracker.types.ts';\n\n// Черновик у GitLab — префикс заголовка (`Draft: ` и прочие формы), а не поле: draft открытого MR адаптер\n// читает из поля draft, а ставит и снимает правкой заголовка. Слияние rebase — отдельный эндпоинт, которого\n// в единой модели нет.\n\nconst DEFAULT_URL = 'https://gitlab.com';\nconst TARGET = /^(\\d{1,15}|[\\w.-]+(\\/[\\w.-]+)+)$/;\nconst IID = /^[1-9]\\d{0,19}$/;\nconst SHA = /^[0-9a-f]{7,64}$/;\n\n/** Возможности PR GitLab (#15): все фильтры единой модели, статус (включая черновик) проверяется по странице. */\nconst PULL_CAPABILITIES: PullRequestCapabilities = {\n list: { filters: pullRequestFilterSchema.options, clientSide: ['status'], sorts: ['created', 'updated', 'title'] },\n comments: { filters: COMMENT_FILTERS, clientSide: COMMENT_FILTERS, order: ['asc', 'desc'] },\n create: true,\n createDraft: true,\n update: ['title', 'description', 'target'],\n statuses: ['draft', 'open', 'closed'],\n comment: true,\n merge: ['merge', 'squash'],\n deleteSourceOnMerge: true,\n};\n\n/** Поле сортировки единой модели → order_by GitLab. */\nconst ORDER_BY: Readonly<Record<string, string>> = { created: 'created_at', updated: 'updated_at', title: 'title' };\n\nexport function gitlabPulls(): PullRequestDefinition {\n return {\n capabilities: PULL_CAPABILITIES,\n create: (context) => createGitlabPullAdapter(context),\n };\n}\n\nfunction createGitlabPullAdapter({ connection, fetch }: AdapterContext): PullRequestAdapter {\n const target = requireTarget(connection.target, 'путь проекта GitLab, group/project, или его id');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target GitLab — group/project или числовой id.');\n const root = `${baseUrl(connection.url, DEFAULT_URL)}/api/v4/projects/${encodeURIComponent(target)}/merge_requests`;\n const headers: Record<string, string> = connection.token === undefined || connection.token === '' ? {} : { 'private-token': connection.token };\n const iid = (key: string): string => {\n if (!IID.test(key)) throw new TrackerError('not_found', `В GitLab нет MR ${key}.`);\n return key;\n };\n const currentOf = async (key: string): Promise<PullRequest> => pullOf((await requestJson(`${root}/${iid(key)}`, { fetch, headers, missing: { failure: 'not_found', message: `В GitLab нет MR ${key}.` } })).body);\n return {\n list: async (query) => {\n assertListQuery('PR GitLab', PULL_CAPABILITIES.list, query, pullRequestFilterSchema.options);\n const status = usedStatuses(query.status);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({\n state: stateFilter(status),\n per_page: String(query.limit),\n page: String(page),\n order_by: query.sort === undefined ? 'created_at' : (ORDER_BY[query.sort.field] ?? 'created_at'),\n sort: query.sort?.direction ?? 'desc',\n });\n if (query.labels !== undefined && query.labels.length > 0) {\n if (query.labels.some((label) => label.includes(','))) throw new TrackerError('invalid_request', 'PR GitLab: метка не должна содержать запятую.');\n params.set('labels', query.labels.join(','));\n }\n if (query.author !== undefined) params.set('author_username', query.author);\n if (query.source !== undefined) params.set('source_branch', query.source);\n if (query.target !== undefined) params.set('target_branch', query.target);\n if (query.search !== undefined) params.set('search', query.search);\n if (query.createdAfter !== undefined) params.set('created_after', isoTime(query.createdAfter));\n if (query.createdBefore !== undefined) params.set('created_before', isoTime(query.createdBefore));\n if (query.updatedAfter !== undefined) params.set('updated_after', isoTime(query.updatedAfter));\n if (query.updatedBefore !== undefined) params.set('updated_before', isoTime(query.updatedBefore));\n const { body, headers: responseHeaders } = await requestJson(`${root}?${params.toString()}`, { fetch, headers });\n const next = responseHeaders.get('x-next-page');\n const items = (Array.isArray(body) ? body : []).map(pullOf);\n // Черновик против открытого адаптер различает по полю draft на странице: страница бывает короче limit.\n return {\n items: status === undefined ? items : items.filter((pr) => status.includes(pr.status.category) === true),\n ...(next === null || next === '' ? {} : { nextCursor: next }),\n };\n },\n get: currentOf,\n create: async (input) => {\n const body = {\n source_branch: input.source,\n target_branch: input.target,\n title: (input.draft === true ? GITLAB_DRAFT_PREFIX : '') + input.title,\n ...(input.description === undefined ? {} : { description: input.description }),\n };\n return pullOf((await requestJson(root, { fetch, headers, method: 'POST', body, conflictOn: [409] })).body);\n },\n update: async (key, patch) => {\n const current = patch.status === undefined ? undefined : await currentOf(key);\n if (patch.status === 'draft' && current?.status.category === 'closed') {\n throw new TrackerError('unsupported', 'PR GitLab: перевод закрытого MR в черновик недоступен.');\n }\n const body = patchBody(patch, current);\n // Пустое тело GitLab отклоняет (400): неизменный запрос — без PUT, ответ — текущий MR.\n if (Object.keys(body).length === 0) return current ?? pullOf((await requestJson(`${root}/${iid(key)}`, { fetch, headers, missing: { failure: 'not_found', message: `В GitLab нет MR ${key}.` } })).body);\n return pullOf((await requestJson(`${root}/${iid(key)}`, { fetch, headers, method: 'PUT', body, missing: { failure: 'not_found', message: `В GitLab нет MR ${key}.` } })).body);\n },\n merge: async (key, input) => {\n if (input.method !== undefined && !PULL_CAPABILITIES.merge.includes(input.method)) {\n throw new TrackerError('unsupported', `PR GitLab: слияние способом ${input.method} не поддерживается.`);\n }\n const body = {\n // squash: true ставит squash; false GitLab игнорирует — при method 'merge' действует настройка MR/проекта.\n ...(input.method === 'squash' ? { squash: true } : {}),\n ...(input.message === undefined ? {} : input.method === 'squash' ? { squash_commit_message: input.message } : { merge_commit_message: input.message }),\n ...(input.deleteSource === undefined ? {} : { should_remove_source_branch: input.deleteSource }),\n ...(input.headSha === undefined ? {} : { sha: input.headSha }),\n };\n return pullOf((await requestJson(`${root}/${iid(key)}/merge`, { fetch, headers, method: 'PUT', body, conflictOn: [405, 409, 422], missing: { failure: 'not_found', message: `В GitLab нет MR ${key}.` } })).body);\n },\n comments: async (key, query) => {\n assertCommentQuery('Комментарии GitLab', PULL_CAPABILITIES.comments, query);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({ sort: query.order ?? 'asc', order_by: 'created_at', per_page: String(query.limit), page: String(page) });\n const { body, headers: responseHeaders } = await requestJson(`${root}/${iid(key)}/notes?${params.toString()}`, { fetch, headers, missing: { failure: 'not_found', message: `В GitLab нет MR ${key}.` } });\n const next = responseHeaders.get('x-next-page');\n // Системные заметки («изменил метку») — не комментарии; updatedAfter сверяется с сырым updated_at заметки.\n const items = (Array.isArray(body) ? body : [])\n .filter((note) => isRecord(note) && note.system !== true && inTimeRange(toTimestamp(note.updated_at), query.updatedAfter, undefined))\n .map(commentOf);\n return { items, ...(next === null || next === '' ? {} : { nextCursor: next }) };\n },\n comment: async (key, body) => commentOf((await requestJson(`${root}/${iid(key)}/notes`, { fetch, headers, method: 'POST', body: { body }, missing: { failure: 'not_found', message: `В GitLab нет MR ${key}.` } })).body),\n };\n}\n\nfunction pageOf(cursor: string | undefined): number {\n const page = cursor === undefined ? 1 : Number(cursor);\n return Number.isInteger(page) && page >= 1 ? page : 1;\n}\n\n/** Категории состояния → state списка: только черновики и открытые — opened, смешанный набор — all. */\nfunction stateFilter(status: readonly PullRequestStatusCategory[] | undefined): string {\n if (status === undefined) return 'all';\n if (status.every((item) => item === 'draft' || item === 'open')) return 'opened';\n if (status.every((item) => item === 'merged')) return 'merged';\n if (status.every((item) => item === 'closed')) return 'closed';\n return 'all';\n}\n\n/** Тело PUT: поля правки и переход состояния; черновик правится префиксом заголовка, что требует текущего MR.\n * Переход «в то же состояние» не пишет повторно: повторный close и неизменный заголовок опускаются. */\nfunction patchBody(patch: PullRequestPatchInput, current: PullRequest | undefined): Record<string, unknown> {\n const body: Record<string, unknown> = {};\n if (patch.description !== undefined) body.description = patch.description;\n if (patch.target !== undefined) body.target_branch = patch.target;\n if (patch.status === 'closed' && current?.status.category !== 'closed') body.state_event = 'close';\n if (patch.status === 'open' && current?.status.category === 'closed') body.state_event = 'reopen';\n if (patch.status === 'draft' || patch.status === 'open') {\n // Перевод в черновик или снятие черновика: прежние формы префикса снимаются, при черновике — свой префикс;\n // open на закрытом черновике снимает префикс вместе с reopen, чтобы результат был open, а не draft.\n const title = patch.title ?? current?.title ?? '';\n const base = title.replace(GITLAB_DRAFT_PATTERN, '');\n // Неизменный заголовок (draft на черновике, open на открытом) сверяется с текущим MR и не отправляется повторно.\n const next = patch.status === 'draft' ? GITLAB_DRAFT_PREFIX + base : current?.status.category === 'draft' || title !== base ? base : patch.title;\n if (next !== undefined && next !== current?.title) body.title = next;\n } else if (patch.title !== undefined && patch.title !== current?.title) {\n body.title = patch.title;\n }\n return body;\n}\n\n/** Статусы списка: пустой массив — без фильтра; неизвестная категория — invalid_request до запроса. */\nfunction usedStatuses(status: readonly PullRequestStatusCategory[] | undefined): readonly PullRequestStatusCategory[] | undefined {\n if (status === undefined || status.length === 0) return undefined;\n for (const item of status) {\n if (!pullRequestStatusCategorySchema.options.includes(item)) {\n throw new TrackerError('invalid_request', `PR GitLab: неизвестная категория статуса ${String(item)}.`);\n }\n }\n return status;\n}\n\n/** Метки MR: GitLab отдаёт и строки, и объекты с name. */\nfunction labelNames(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n const names = value.map((item) => (typeof item === 'string' ? item : isRecord(item) ? text(item.name) : undefined));\n return [...new Set(names.filter((name): name is string => name !== undefined && name !== ''))];\n}\n\nfunction usernames(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n const names = value.map((item) => (isRecord(item) ? text(item.username) : undefined));\n return [...new Set(names.filter((name): name is string => name !== undefined && name !== ''))];\n}\n\nfunction pullOf(raw: unknown): PullRequest {\n const item = isRecord(raw) ? raw : {};\n const state = text(item.state) ?? 'opened';\n const draft = item.draft === true;\n const category = lookup<PullRequestStatusCategory>(GITLAB_MERGE_REQUEST_STATES, state, 'open');\n const key = typeof item.iid === 'number' ? String(item.iid) : '?';\n const description = text(item.description);\n const author = isRecord(item.author) ? text(item.author.username) : undefined;\n const sha = text(item.sha);\n const url = text(item.web_url);\n const createdAt = toTimestamp(item.created_at);\n const updatedAt = toTimestamp(item.updated_at);\n const mergedAt = toTimestamp(item.merged_at);\n const closedAt = toTimestamp(item.closed_at);\n return {\n key,\n title: text(item.title) ?? key,\n ...(description === undefined ? {} : { description }),\n status: { category: draft && category === 'open' ? 'draft' : category, name: draft && category === 'open' ? 'draft' : state },\n ...(author === undefined ? {} : { author }),\n source: text(item.source_branch) ?? '?',\n target: text(item.target_branch) ?? '?',\n ...(sha !== undefined && SHA.test(sha) ? { headSha: sha } : {}),\n labels: labelNames(item.labels),\n reviewers: usernames(item.reviewers),\n links: url === undefined ? [] : [{ url, title: 'GitLab' }],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n ...(mergedAt === undefined ? {} : { mergedAt }),\n ...(closedAt === undefined ? {} : { closedAt }),\n };\n}\n\nfunction commentOf(raw: unknown): IssueComment {\n const item = isRecord(raw) ? raw : {};\n const author = isRecord(item.author) ? text(item.author.username) : undefined;\n const createdAt = toTimestamp(item.created_at);\n return { id: typeof item.id === 'number' ? String(item.id) : '?', ...(author === undefined ? {} : { author }), body: typeof item.body === 'string' ? item.body : '', ...(createdAt === undefined ? {} : { createdAt }) };\n}\n","// Адаптер GitLab библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/gitlab.lib.ts — дословная копия, импорт типов из среза контракта библиотеки.\nimport type { Issue, IssueComment, IssuePriority, IssueStatusCategory } from '../contract/contract.types.ts';\nimport { gitlabPulls } from './gitlab-pull.lib.ts';\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { gitlabCi } from './gitlab-ci.lib.ts';\nimport { GITLAB_IN_PROGRESS_LABEL, GITLAB_PRIORITY_LABELS } from './mapping.const.ts';\nimport { COMMENT_FILTERS, ISSUE_FILTERS } from './tracker.const.ts';\nimport type { IssueSortField } from './tracker.const.ts';\nimport { TrackerError, assertCommentQuery, assertListQuery, inTimeRange, isRecord, isoTime, lookup, priorityName, requireTarget, stringList, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext, IssueCapabilities, IssuePatchInput, TrackerAdapter, TrackerDefinition } from './tracker.types.ts';\n\n// Трекер GitLab (D-350): задачи проекта (`group/project` или числовой id) через REST API v4, токен — PRIVATE-TOKEN.\n// У GitLab статус — opened или closed: «в работе» держится меткой `status::in-progress`, приоритет —\n// меткой `priority::<имя>`; служебные метки читаются в поля единой модели и из `labels` убираются. «Отклонена»\n// у GitLab нет. Исполнитель у GitLab задаётся по id пользователя, поэтому только показывается.\n\nconst DEFAULT_URL = 'https://gitlab.com';\nconst TARGET = /^(\\d{1,15}|[\\w.-]+(\\/[\\w.-]+)+)$/;\nconst IID = /^[1-9]\\d{0,14}$/;\n\n/** Возможности списков GitLab (#14): все фильтры единой модели, статус проверяется по странице; comments не сортируется. */\nconst ISSUE_CAPABILITIES: IssueCapabilities = {\n list: { filters: ISSUE_FILTERS, clientSide: ['status'], sorts: ['created', 'updated', 'priority', 'title'] },\n comments: { filters: COMMENT_FILTERS, clientSide: COMMENT_FILTERS, order: ['asc', 'desc'] },\n};\n\n/** Поле сортировки единой модели → order_by GitLab; comments GitLab не сортирует, до сюда не доходит. */\nconst ORDER_BY: Readonly<Partial<Record<IssueSortField, string>>> = {\n created: 'created_at',\n updated: 'updated_at',\n priority: 'priority',\n title: 'title',\n};\n\nexport function gitlabTracker(): TrackerDefinition {\n return {\n descriptor: {\n tracker: 'gitlab',\n title: 'GitLab',\n fields: [\n { name: 'target', required: true, secret: false },\n { name: 'token', required: true, secret: true },\n { name: 'url', required: false, secret: false },\n ],\n features: { create: true, update: true, comment: true, priority: true, labels: true, assignee: false, statuses: ['open', 'in_progress', 'done'] },\n },\n create: (context) => createGitlabAdapter(context),\n issues: ISSUE_CAPABILITIES,\n pulls: gitlabPulls(),\n ci: gitlabCi(),\n };\n}\n\nfunction createGitlabAdapter({ connection, fetch }: AdapterContext): TrackerAdapter {\n const target = requireTarget(connection.target, 'путь проекта GitLab, group/project, или его id');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target GitLab — group/project или числовой id.');\n const root = `${baseUrl(connection.url, DEFAULT_URL)}/api/v4/projects/${encodeURIComponent(target)}/issues`;\n const headers: Record<string, string> = connection.token === undefined || connection.token === '' ? {} : { 'private-token': connection.token };\n const iid = (key: string): string => {\n if (!IID.test(key)) throw new TrackerError('unknown_issue', `В GitLab нет задачи ${key}.`);\n return key;\n };\n const currentOf = async (key: string): Promise<Issue> => issueOf((await requestJson(`${root}/${iid(key)}`, { fetch, headers, missingIsIssue: true })).body);\n return {\n list: async (query) => {\n assertListQuery('Задачи GitLab', ISSUE_CAPABILITIES.list, query, ISSUE_FILTERS);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({\n state: stateFilter(query.status),\n per_page: String(query.limit),\n page: String(page),\n order_by: query.sort === undefined ? 'created_at' : (ORDER_BY[query.sort.field] ?? 'created_at'),\n sort: query.sort?.direction ?? 'desc',\n });\n if (query.labels !== undefined && query.labels.length > 0) {\n if (query.labels.some((label) => label.includes(','))) throw new TrackerError('invalid_request', 'Задачи GitLab: метка не должна содержать запятую.');\n params.set('labels', query.labels.join(','));\n }\n if (query.assignee !== undefined) params.set(query.assignee === null ? 'assignee_id' : 'assignee_username', query.assignee === null ? 'None' : query.assignee);\n if (query.author !== undefined) params.set('author_username', query.author);\n if (query.search !== undefined) params.set('search', query.search);\n if (query.createdAfter !== undefined) params.set('created_after', isoTime(query.createdAfter));\n if (query.createdBefore !== undefined) params.set('created_before', isoTime(query.createdBefore));\n if (query.updatedAfter !== undefined) params.set('updated_after', isoTime(query.updatedAfter));\n if (query.updatedBefore !== undefined) params.set('updated_before', isoTime(query.updatedBefore));\n const { body, headers: responseHeaders } = await requestJson(`${root}?${params.toString()}`, { fetch, headers });\n const items = (Array.isArray(body) ? body : []).map(issueOf);\n const next = responseHeaders.get('x-next-page');\n return {\n items: query.status === undefined ? items : items.filter((issue) => query.status?.includes(issue.status.category) === true),\n ...(next === null || next === '' ? {} : { nextCursor: next }),\n };\n },\n get: currentOf,\n create: async (input) => {\n const labels = composeLabels(input.labels ?? [], input.priority, undefined);\n const body = { title: input.title, ...(input.description === undefined ? {} : { description: input.description }), ...(labels.length === 0 ? {} : { labels: labels.join(',') }) };\n return issueOf((await requestJson(root, { fetch, headers, method: 'POST', body })).body);\n },\n update: async (key, patch) => {\n const current = patch.labels === undefined && patch.priority === undefined && patch.status === undefined ? undefined : await currentOf(key);\n return issueOf((await requestJson(`${root}/${iid(key)}`, { fetch, headers, method: 'PUT', body: patchBody(patch, current), missingIsIssue: true })).body);\n },\n comments: async (key, query) => {\n assertCommentQuery('Комментарии GitLab', ISSUE_CAPABILITIES.comments, query);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({ sort: query.order ?? 'asc', order_by: 'created_at', per_page: String(query.limit), page: String(page) });\n const { body, headers: responseHeaders } = await requestJson(`${root}/${iid(key)}/notes?${params.toString()}`, { fetch, headers, missingIsIssue: true });\n const next = responseHeaders.get('x-next-page');\n // Системные заметки («изменил метку») — не комментарии; updatedAfter сверяется с сырым updated_at заметки.\n const items = (Array.isArray(body) ? body : [])\n .filter((note) => isRecord(note) && note.system !== true && inTimeRange(toTimestamp(note.updated_at), query.updatedAfter, undefined))\n .map(commentOf);\n return { items, ...(next === null || next === '' ? {} : { nextCursor: next }) };\n },\n comment: async (key, body) => commentOf((await requestJson(`${root}/${iid(key)}/notes`, { fetch, headers, method: 'POST', body: { body }, missingIsIssue: true })).body),\n };\n}\n\nfunction pageOf(cursor: string | undefined): number {\n const page = cursor === undefined ? 1 : Number(cursor);\n return Number.isInteger(page) && page >= 1 ? page : 1;\n}\n\nfunction stateFilter(status: readonly IssueStatusCategory[] | undefined): string {\n if (status === undefined) return 'all';\n if (status.every((item) => item === 'open' || item === 'in_progress')) return 'opened';\n if (status.every((item) => item === 'done' || item === 'declined')) return 'closed';\n return 'all';\n}\n\nfunction composeLabels(plain: readonly string[], priority: IssuePriority | undefined, status: IssueStatusCategory | undefined): string[] {\n const priorityLabel = priority === undefined ? undefined : priorityName(GITLAB_PRIORITY_LABELS, priority);\n return [...plain, ...(priorityLabel === undefined ? [] : [priorityLabel]), ...(status === 'in_progress' ? [GITLAB_IN_PROGRESS_LABEL] : [])];\n}\n\nfunction patchBody(patch: IssuePatchInput, current: Issue | undefined): Record<string, unknown> {\n const status = patch.status ?? current?.status.category;\n const touchesLabels = patch.labels !== undefined || patch.priority !== undefined || patch.status !== undefined;\n if (patch.status === 'declined') throw new TrackerError('invalid_request', 'В GitLab нет статуса «отклонена».');\n return {\n ...(patch.title === undefined ? {} : { title: patch.title }),\n ...(patch.description === undefined ? {} : { description: patch.description }),\n ...(patch.status === undefined ? {} : { state_event: patch.status === 'done' ? 'close' : 'reopen' }),\n ...(touchesLabels ? { labels: composeLabels(patch.labels ?? current?.labels ?? [], patch.priority ?? current?.priority, status).join(',') } : {}),\n };\n}\n\nfunction issueOf(raw: unknown): Issue {\n const item = isRecord(raw) ? raw : {};\n const names = stringList(item.labels);\n const closed = item.state === 'closed';\n const category: IssueStatusCategory = closed ? 'done' : names.includes(GITLAB_IN_PROGRESS_LABEL) ? 'in_progress' : 'open';\n const priority = names.map((name) => lookup<IssuePriority | undefined>(GITLAB_PRIORITY_LABELS, name, undefined)).find((value) => value !== undefined);\n const description = text(item.description);\n const assignees = Array.isArray(item.assignees) ? item.assignees : [];\n const first = assignees[0];\n const assignee = isRecord(first) ? text(first.username) : undefined;\n const url = text(item.web_url);\n const createdAt = toTimestamp(item.created_at);\n const updatedAt = toTimestamp(item.updated_at);\n const key = typeof item.iid === 'number' ? String(item.iid) : '?';\n return {\n key,\n title: text(item.title) ?? key,\n ...(description === undefined ? {} : { description }),\n status: { category, name: closed ? 'closed' : category === 'in_progress' ? 'in progress' : 'opened' },\n ...(priority === undefined ? {} : { priority }),\n labels: names.filter((name) => name !== GITLAB_IN_PROGRESS_LABEL && !Object.hasOwn(GITLAB_PRIORITY_LABELS, name)),\n ...(assignee === undefined ? {} : { assignee }),\n links: url === undefined ? [] : [{ url, title: 'GitLab' }],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n };\n}\n\nfunction commentOf(raw: unknown): IssueComment {\n const item = isRecord(raw) ? raw : {};\n const author = isRecord(item.author) ? text(item.author.username) : undefined;\n const createdAt = toTimestamp(item.created_at);\n return { id: typeof item.id === 'number' ? String(item.id) : '?', ...(author === undefined ? {} : { author }), body: typeof item.body === 'string' ? item.body : '', ...(createdAt === undefined ? {} : { createdAt }) };\n}\n","// Адаптер Jira библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/jira.lib.ts — дословная копия, импорт типов из среза контракта библиотеки;\n// фильтры и сортировка списков — свои (#14).\nimport type { Issue, IssueComment, IssuePriority, IssueStatusCategory } from '../contract/contract.types.ts';\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { JIRA_ISSUE_TYPE, JIRA_PRIORITIES, JIRA_PRIORITY_NAMES, JIRA_STATUS_CATEGORIES } from './mapping.const.ts';\nimport { COMMENT_FILTERS, ISSUE_FILTERS } from './tracker.const.ts';\nimport type { IssueSortField } from './tracker.const.ts';\nimport { TrackerError, assertCommentQuery, assertListQuery, inTimeRange, isRecord, lookup, quoted, requireTarget, stringList, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext, IssueCapabilities, IssuePatchInput, IssueQuery, TrackerAdapter, TrackerDefinition } from './tracker.types.ts';\n\n// Трекер Jira (D-350): проект по ключу, REST API v2 (описание — обычный текст). Есть `user` — Basic (email и\n// API-токен Cloud), нет — Bearer (персональный токен Server и Data Center). Список — `/search/jql` Cloud, на\n// 404 — классический `/search` Server с курсором `s:<startAt>`. Статус — по `statusCategory`, меняется\n// переходом (transition) в нужную категорию; «отклонена» у Jira нет. Исполнитель у Cloud — accountId, поэтому\n// только показывается.\n\nconst PROJECT_KEY = /^[A-Z][A-Z0-9_]{0,49}$/;\nconst ISSUE_KEY = /^[A-Z][A-Z0-9_]{0,49}-[1-9]\\d{0,14}$/;\nconst FIELDS = 'summary,description,status,priority,labels,assignee,created,updated';\nconst CATEGORY_JQL: Readonly<Partial<Record<IssueStatusCategory, string>>> = { open: '\"To Do\"', in_progress: '\"In Progress\"', done: 'Done' };\n\n/** Возможности списков задач Jira (#14): все фильтры — в JQL на стороне Jira, порядок комментариев asc и desc. */\nconst ISSUE_CAPABILITIES: IssueCapabilities = {\n list: { filters: ISSUE_FILTERS, clientSide: [], sorts: ['created', 'updated', 'priority', 'title'] },\n comments: { filters: COMMENT_FILTERS, clientSide: COMMENT_FILTERS, order: ['asc', 'desc'] },\n};\n\n/** Поле сортировки единой модели → поле ORDER BY JQL; без сортировки — created DESC, как раньше. */\nconst JIRA_SORT_FIELDS: Readonly<Record<Exclude<IssueSortField, 'comments'>, string>> = { created: 'created', updated: 'updated', priority: 'priority', title: 'summary' };\n\nexport function jiraTracker(): TrackerDefinition {\n return {\n descriptor: {\n tracker: 'jira',\n title: 'Jira',\n fields: [\n { name: 'url', required: true, secret: false },\n { name: 'target', required: true, secret: false },\n { name: 'user', required: false, secret: false },\n { name: 'token', required: true, secret: true },\n ],\n features: { create: true, update: true, comment: true, priority: true, labels: true, assignee: false, statuses: ['open', 'in_progress', 'done'] },\n },\n create: (context) => createJiraAdapter(context),\n issues: ISSUE_CAPABILITIES,\n };\n}\n\nfunction createJiraAdapter({ connection, fetch }: AdapterContext): TrackerAdapter {\n if (connection.url === undefined) throw new TrackerError('invalid_request', 'Не задан адрес Jira.');\n const project = requireTarget(connection.target, 'ключ проекта Jira, например PROJ');\n if (!PROJECT_KEY.test(project)) throw new TrackerError('invalid_request', 'target Jira — ключ проекта: заглавные буквы и цифры.');\n const site = baseUrl(connection.url, connection.url);\n const api = `${site}/rest/api/2`;\n const token = connection.token ?? '';\n const headers = { authorization: connection.user === undefined ? `Bearer ${token}` : `Basic ${Buffer.from(`${connection.user}:${token}`).toString('base64')}` };\n const key = (value: string): string => {\n if (!ISSUE_KEY.test(value)) throw new TrackerError('unknown_issue', `В Jira нет задачи ${value}.`);\n return value;\n };\n const toIssue = (raw: unknown): Issue => issueOf(raw, site);\n const load = async (value: string): Promise<Issue> => toIssue((await requestJson(`${api}/issue/${key(value)}?fields=${FIELDS}`, { fetch, headers, missingIsIssue: true })).body);\n return {\n list: async (query) => {\n assertListQuery('Задачи Jira', ISSUE_CAPABILITIES.list, query, ISSUE_FILTERS);\n const jql = listJql(project, query);\n if (jql === undefined) return { items: [] };\n if (query.cursor?.startsWith('s:') !== true) {\n const params = new URLSearchParams({ jql, fields: FIELDS, maxResults: String(query.limit) });\n if (query.cursor !== undefined) params.set('nextPageToken', query.cursor);\n try {\n const { body } = await requestJson(`${api}/search/jql?${params.toString()}`, { fetch, headers });\n const record = isRecord(body) ? body : {};\n const next = text(record.nextPageToken);\n return { items: (Array.isArray(record.issues) ? record.issues : []).map(toIssue), ...(next === undefined || record.isLast === true ? {} : { nextCursor: next }) };\n } catch (error) {\n if (!(error instanceof TrackerError) || !error.message.includes(' 404')) throw error;\n }\n }\n const startAt = query.cursor?.startsWith('s:') === true ? Number(query.cursor.slice(2)) : 0;\n const params = new URLSearchParams({ jql, fields: FIELDS, maxResults: String(query.limit), startAt: String(Number.isInteger(startAt) && startAt >= 0 ? startAt : 0) });\n const { body } = await requestJson(`${api}/search?${params.toString()}`, { fetch, headers });\n const record = isRecord(body) ? body : {};\n const issues = Array.isArray(record.issues) ? record.issues : [];\n const total = typeof record.total === 'number' ? record.total : 0;\n const at = typeof record.startAt === 'number' ? record.startAt : 0;\n return { items: issues.map(toIssue), ...(at + issues.length < total && issues.length > 0 ? { nextCursor: `s:${String(at + issues.length)}` } : {}) };\n },\n get: load,\n create: async (input) => {\n const fields = {\n project: { key: project },\n summary: input.title,\n issuetype: { name: JIRA_ISSUE_TYPE },\n ...(input.description === undefined ? {} : { description: input.description }),\n ...(input.priority === undefined ? {} : { priority: { name: JIRA_PRIORITY_NAMES[input.priority] } }),\n ...(input.labels === undefined ? {} : { labels: input.labels.map((label) => label.replace(/\\s+/g, '-')) }),\n };\n const { body } = await requestJson(`${api}/issue`, { fetch, headers, method: 'POST', body: { fields } });\n const created = isRecord(body) ? text(body.key) : undefined;\n if (created === undefined) throw new TrackerError('failed', 'Jira создала задачу, но не вернула её ключ.');\n return load(created);\n },\n update: async (value, patch) => {\n const fields = fieldsOf(patch);\n if (Object.keys(fields).length > 0) await requestJson(`${api}/issue/${key(value)}`, { fetch, headers, method: 'PUT', body: { fields }, missingIsIssue: true });\n if (patch.status !== undefined) await transition(api, key(value), patch.status, fetch, headers);\n return load(value);\n },\n comments: async (value, query) => {\n assertCommentQuery('Комментарии Jira', ISSUE_CAPABILITIES.comments, query);\n const startAt = query.cursor === undefined ? 0 : Number(query.cursor);\n const params = new URLSearchParams({ startAt: String(Number.isInteger(startAt) && startAt >= 0 ? startAt : 0), maxResults: String(query.limit), orderBy: query.order === 'desc' ? '-created' : 'created' });\n const { body } = await requestJson(`${api}/issue/${key(value)}/comment?${params.toString()}`, { fetch, headers, missingIsIssue: true });\n const record = isRecord(body) ? body : {};\n const raw = Array.isArray(record.comments) ? record.comments : [];\n // Курсор считается по сырой странице: после дофильтровки updatedAfter остаток бывает пуст, а листание продолжается (§3.2 R5).\n const items = raw.filter((item) => inTimeRange(toTimestamp(isRecord(item) ? item.updated : undefined), query.updatedAfter, undefined));\n const total = typeof record.total === 'number' ? record.total : 0;\n const at = typeof record.startAt === 'number' ? record.startAt : 0;\n return { items: items.map(commentOf), ...(at + raw.length < total && raw.length > 0 ? { nextCursor: String(at + raw.length) } : {}) };\n },\n comment: async (value, body) => commentOf((await requestJson(`${api}/issue/${key(value)}/comment`, { fetch, headers, method: 'POST', body: { body }, missingIsIssue: true })).body),\n };\n}\n\n/** JQL списка (#14): project и дальше каждый фильтр через AND; undefined — статусов нет или Jira запрошенные\n * категории не знает (результат пуст, запроса нет, как раньше). */\nfunction listJql(project: string, query: IssueQuery): string | undefined {\n const clauses: string[] = [];\n if (query.status !== undefined) {\n const names = query.status.flatMap((item) => CATEGORY_JQL[item] ?? []);\n if (names.length === 0) return undefined;\n clauses.push(`statusCategory in (${names.join(', ')})`);\n }\n for (const label of query.labels ?? []) clauses.push(`labels = ${quoted(label.replace(/\\s+/g, '-'))}`);\n if (query.assignee !== undefined) clauses.push(query.assignee === null ? 'assignee is EMPTY' : `assignee = ${quoted(query.assignee)}`);\n if (query.author !== undefined) clauses.push(`reporter = ${quoted(query.author)}`);\n if (query.search !== undefined) clauses.push(`text ~ ${quoted(query.search)}`);\n if (query.createdAfter !== undefined) clauses.push(`created >= ${quoted(jiraTime(query.createdAfter, 'down'))}`);\n if (query.createdBefore !== undefined) clauses.push(`created <= ${quoted(jiraTime(query.createdBefore, 'up'))}`);\n if (query.updatedAfter !== undefined) clauses.push(`updated >= ${quoted(jiraTime(query.updatedAfter, 'down'))}`);\n if (query.updatedBefore !== undefined) clauses.push(`updated <= ${quoted(jiraTime(query.updatedBefore, 'up'))}`);\n const sort = query.sort;\n // 'comments' сюда не доходит: assertListQuery отказал раньше — в sorts Jira его нет.\n const field = (sort === undefined ? 'created' : sort.field) as Exclude<IssueSortField, 'comments'>;\n const direction = sort?.direction ?? 'desc';\n return `${[`project = ${quoted(project)}`, ...clauses].join(' AND ')} ORDER BY ${JIRA_SORT_FIELDS[field]} ${direction.toUpperCase()}`;\n}\n\n/** Время JQL: UTC, «yyyy/MM/dd HH:mm»; нижняя граница вниз к минуте, верхняя — вверх, чтобы границы были включительны (#14, R2). */\nfunction jiraTime(ms: number, outward: 'down' | 'up'): string {\n const at = new Date(outward === 'down' ? Math.floor(ms / 60000) * 60000 : Math.ceil(ms / 60000) * 60000);\n const pad = (value: number): string => String(value).padStart(2, '0');\n return `${String(at.getUTCFullYear())}/${pad(at.getUTCMonth() + 1)}/${pad(at.getUTCDate())} ${pad(at.getUTCHours())}:${pad(at.getUTCMinutes())}`;\n}\n\nfunction fieldsOf(patch: IssuePatchInput): Record<string, unknown> {\n return {\n ...(patch.title === undefined ? {} : { summary: patch.title }),\n ...(patch.description === undefined ? {} : { description: patch.description }),\n ...(patch.priority === undefined ? {} : { priority: { name: JIRA_PRIORITY_NAMES[patch.priority] } }),\n ...(patch.labels === undefined ? {} : { labels: patch.labels.map((label) => label.replace(/\\s+/g, '-')) }),\n };\n}\n\n/** Переводит задачу в категорию: берёт первый доступный переход, чей статус назначения лежит в ней. */\nasync function transition(api: string, key: string, category: IssueStatusCategory, fetch: AdapterContext['fetch'], headers: Record<string, string>): Promise<void> {\n const { body } = await requestJson(`${api}/issue/${key}/transitions`, { fetch, headers, missingIsIssue: true });\n const list = isRecord(body) && Array.isArray(body.transitions) ? body.transitions : [];\n const match = list.find((item) => {\n if (!isRecord(item) || !isRecord(item.to) || !isRecord(item.to.statusCategory)) return false;\n return lookup<IssueStatusCategory | undefined>(JIRA_STATUS_CATEGORIES, item.to.statusCategory.key, undefined) === category;\n });\n const id = isRecord(match) ? text(match.id) : undefined;\n if (id === undefined) throw new TrackerError('invalid_request', `Из текущего статуса Jira нет перехода в категорию ${category}.`);\n await requestJson(`${api}/issue/${key}/transitions`, { fetch, headers, method: 'POST', body: { transition: { id } }, missingIsIssue: true });\n}\n\nfunction issueOf(raw: unknown, site: string): Issue {\n const item = isRecord(raw) ? raw : {};\n const fields = isRecord(item.fields) ? item.fields : {};\n const status = isRecord(fields.status) ? fields.status : {};\n const category = isRecord(status.statusCategory) ? status.statusCategory.key : undefined;\n const priorityName = isRecord(fields.priority) && typeof fields.priority.name === 'string' ? fields.priority.name.toLowerCase() : undefined;\n const priority = lookup<IssuePriority | undefined>(JIRA_PRIORITIES, priorityName, undefined);\n const assignee = isRecord(fields.assignee) ? (text(fields.assignee.displayName) ?? text(fields.assignee.name)) : undefined;\n const description = text(fields.description);\n const createdAt = toTimestamp(fields.created);\n const updatedAt = toTimestamp(fields.updated);\n const key = text(item.key) ?? '?';\n return {\n key,\n title: text(fields.summary) ?? key,\n ...(description === undefined ? {} : { description }),\n status: { category: lookup(JIRA_STATUS_CATEGORIES, category, 'open'), name: text(status.name) ?? 'To Do' },\n ...(priority === undefined ? {} : { priority }),\n labels: stringList(fields.labels),\n ...(assignee === undefined ? {} : { assignee }),\n links: [{ url: `${site}/browse/${key}`, title: 'Jira' }],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n };\n}\n\nfunction commentOf(raw: unknown): IssueComment {\n const item = isRecord(raw) ? raw : {};\n const author = isRecord(item.author) ? text(item.author.displayName) : undefined;\n const createdAt = toTimestamp(item.created);\n return { id: text(item.id) ?? '?', ...(author === undefined ? {} : { author }), body: typeof item.body === 'string' ? item.body : '', ...(createdAt === undefined ? {} : { createdAt }) };\n}\n","// Локальный трекер библиотеки @smwb/onreel-git-mcp (часть E выделения, D-003).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/local.lib.ts — CRUD через функции ledger заменён на порт LocalIssueStore ядра\n// (kernel/store.types.ts): хранилище пишет потребитель (в onreel — поверх ledger), эталонная\n// реализация в памяти — в тестах библиотеки (test/helpers/tracker-fixtures.lib.ts).\n// Фильтры единой модели (#14): хранилище умеет только статус и keyset-страницы, остальные фильтры\n// адаптер проверяет по полученной странице — порт LocalIssueStore не меняется (D-003).\nimport type { Issue } from '../contract/contract.types.ts';\nimport type { LocalCommentRow, LocalIssueRow } from '../kernel/store.types.ts';\nimport { ALL_STATUSES } from './mapping.const.ts';\nimport { COMMENT_FILTERS, ISSUE_FILTERS } from './tracker.const.ts';\nimport { TrackerError, assertCommentQuery, assertListQuery, containsText, inTimeRange } from './tracker.lib.ts';\nimport type { AdapterContext, IssueCapabilities, IssueQuery, TrackerAdapter, TrackerDefinition } from './tracker.types.ts';\n\n// Локальный трекер (D-350): задачи в хранилище потребителя, без внешних сервисов. Номер задачи — её ключ.\n\nconst STATUS_NAMES = { open: 'Open', in_progress: 'In progress', done: 'Done', declined: 'Declined' } as const;\n\n/** Возможности списков локального трекера (#14, §3.6): из фильтров запроса хранилище знает только\n * статус, остальное проверяется по странице (D-004). Автора у локальной задачи нет и сортировки нет:\n * store отдаёт порядок ledger — новые первыми. */\nconst ISSUE_CAPABILITIES: IssueCapabilities = {\n list: {\n filters: ['status', 'labels', 'assignee', 'search', 'createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore'],\n clientSide: ['labels', 'assignee', 'search', 'createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore'],\n sorts: [],\n },\n comments: { filters: COMMENT_FILTERS, clientSide: COMMENT_FILTERS, order: ['asc'] },\n};\n\nexport function localTracker(): TrackerDefinition {\n return {\n descriptor: {\n tracker: 'local',\n title: 'Local',\n fields: [],\n features: { create: true, update: true, comment: true, priority: true, labels: true, assignee: true, statuses: [...ALL_STATUSES] },\n },\n issues: ISSUE_CAPABILITIES,\n create: (context) => createLocalAdapter(context),\n };\n}\n\nfunction createLocalAdapter({ store, projectId, author }: AdapterContext): TrackerAdapter {\n const number = (key: string): number => {\n if (!/^[1-9]\\d{0,14}$/.test(key)) throw new TrackerError('unknown_issue', `В локальном трекере нет задачи ${key}.`);\n return Number(key);\n };\n const mustGet = (key: string): LocalIssueRow => {\n const row = store.getLocalIssue(projectId, number(key));\n if (row === undefined) throw new TrackerError('unknown_issue', `В локальном трекере нет задачи ${key}.`);\n return row;\n };\n return {\n // list и comments async: отказ проверки запроса — rejected promise, как у остальных адаптеров.\n list: async (query) => {\n assertListQuery('Задачи Local', ISSUE_CAPABILITIES.list, query, ISSUE_FILTERS);\n const page = store.listLocalIssues(projectId, { limit: query.limit, ...(query.cursor === undefined ? {} : { cursor: query.cursor }), ...(query.status === undefined ? {} : { status: query.status }) });\n return { items: page.items.filter((row) => matchesIssueQuery(row, query)).map(toIssue), ...(page.nextCursor === undefined ? {} : { nextCursor: page.nextCursor }) };\n },\n get: (key) => Promise.resolve(toIssue(mustGet(key))),\n create: (input) => Promise.resolve(toIssue(store.createLocalIssue(projectId, input))),\n update: (key, patch) => {\n const row = store.updateLocalIssue(projectId, mustGet(key).number, patch);\n if (row === undefined) throw new TrackerError('unknown_issue', `В локальном трекере нет задачи ${key}.`);\n return Promise.resolve(toIssue(row));\n },\n comments: async (key, query) => {\n assertCommentQuery('Комментарии Local', ISSUE_CAPABILITIES.comments, query);\n const page = store.listLocalComments(projectId, mustGet(key).number, { limit: query.limit, ...(query.cursor === undefined ? {} : { cursor: query.cursor }) });\n // Локальные комментарии не правятся, поэтому updatedAfter сверяется с createdAt; порядок — только asc (§3.7 A6).\n const items = query.updatedAfter === undefined ? page.items : page.items.filter((row) => inTimeRange(row.createdAt, query.updatedAfter, undefined));\n return { items: items.map(toComment), ...(page.nextCursor === undefined ? {} : { nextCursor: page.nextCursor }) };\n },\n comment: (key, body) => Promise.resolve(toComment(store.addLocalComment(projectId, mustGet(key).number, body, author))),\n };\n}\n\n/** Фильтры единой модели, которые локальный трекер проверяет по странице (D-004): метки — все сразу (И),\n * assignee null — задачи без исполнителя, search — подстрока заголовка или описания без учёта регистра,\n * время — включительно с обеих сторон (R2, R3). */\nfunction matchesIssueQuery(row: LocalIssueRow, query: IssueQuery): boolean {\n if (query.labels !== undefined && !query.labels.every((label) => row.labels.includes(label))) return false;\n const assignee = query.assignee;\n if (assignee !== undefined && (assignee === null ? row.assignee !== undefined : row.assignee !== assignee)) return false;\n if (query.search !== undefined && !containsText([row.title, row.description], query.search)) return false;\n return inTimeRange(row.createdAt, query.createdAfter, query.createdBefore) && inTimeRange(row.updatedAt, query.updatedAfter, query.updatedBefore);\n}\n\nfunction toIssue(row: LocalIssueRow): Issue {\n return {\n key: String(row.number),\n title: row.title,\n ...(row.description === undefined ? {} : { description: row.description }),\n status: { category: row.status, name: STATUS_NAMES[row.status] },\n ...(row.priority === undefined ? {} : { priority: row.priority }),\n labels: row.labels,\n ...(row.assignee === undefined ? {} : { assignee: row.assignee }),\n links: [],\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\nfunction toComment(row: LocalCommentRow): { id: string; author?: string; body: string; createdAt: number } {\n return { id: String(row.id), ...(row.author === undefined ? {} : { author: row.author }), body: row.body, createdAt: row.createdAt };\n}\n","// Адаптер pull request-ов SourceCraft библиотеки @smwb/onreel-git-mcp — свой (#15).\n// Раздел pulls (D-005) на том же подключении, что и задачи: QL filter списка, отдельные\n// конечные точки состояний, асинхронное слияние (202 → get; failed/cancel — conflict).\nimport type { IssueComment } from '../contract/contract.types.ts';\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { redactSecretText } from '../kernel/redact.lib.ts';\nimport { SOURCECRAFT_PULL_STATUSES } from './mapping.const.ts';\nimport type { PullRequest, PullRequestSortField, PullRequestStatusCategory } from './pull.schema.ts';\nimport { pullRequestFilterSchema, pullRequestStatusCategorySchema } from './pull.schema.ts';\nimport type { MergeInput, NewPullRequestInput, PullRequestAdapter, PullRequestCapabilities, PullRequestDefinition, PullRequestQuery } from './pull.types.ts';\nimport { COMMENT_FILTERS } from './tracker.const.ts';\nimport { TrackerError, assertCommentQuery, assertListQuery, containsText, inTimeRange, isRecord, keysFor, lookup, quoted, requireTarget, stringList, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext, CommentQuery } from './tracker.types.ts';\n\nconst DEFAULT_API = 'https://api.sourcecraft.tech';\nconst TARGET = /^[\\w.-]+\\/[\\w.-]+$/;\nconst SLUG = /^[\\w-]{1,100}$/;\nconst SHA = /^[0-9a-f]{7,64}$/;\n\n/** Поля сортировки единой модели → поля sort_by SourceCraft. */\nconst PULL_SORT_FIELDS_UPSTREAM: Readonly<Record<PullRequestSortField, string>> = {\n created: 'created_at',\n updated: 'updated_at',\n title: 'title',\n};\n\n/** Возможности PR SourceCraft (§3.6): QL фильтрует статус, автора и ветки сервером; метки, поиск и время — по странице. */\nconst PULL_CAPABILITIES: PullRequestCapabilities = {\n list: {\n filters: pullRequestFilterSchema.options,\n clientSide: ['labels', 'search', 'createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore'],\n sorts: ['created', 'updated', 'title'],\n },\n comments: { filters: COMMENT_FILTERS, clientSide: COMMENT_FILTERS, order: ['asc', 'desc'] },\n create: true,\n createDraft: true,\n update: ['title', 'description', 'target'],\n statuses: ['draft', 'open', 'closed'],\n comment: true,\n merge: ['merge', 'squash', 'rebase'],\n deleteSourceOnMerge: true,\n};\n\nexport function sourcecraftPulls(): PullRequestDefinition {\n return { capabilities: PULL_CAPABILITIES, create: (context) => createPullAdapter(context) };\n}\n\nfunction createPullAdapter({ connection, fetch }: AdapterContext): PullRequestAdapter {\n const target = requireTarget(connection.target, 'org/repo репозитория SourceCraft');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target SourceCraft — org/repo.');\n const api = baseUrl(connection.url, DEFAULT_API);\n const root = `${api}/repos/${target}/pulls`;\n const headers = { authorization: `Bearer ${connection.token ?? ''}` };\n const missing = (key: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В SourceCraft нет PR ${key}.` });\n const slug = (key: string): string => {\n if (!SLUG.test(key)) throw new TrackerError('not_found', `В SourceCraft нет PR ${key}.`);\n return key;\n };\n const getPull = async (key: string): Promise<PullRequest> =>\n pullOf((await requestJson(`${root}/${slug(key)}`, { fetch, headers, missing: missing(key) })).body);\n return {\n list: async (query) => {\n assertListQuery('PR SourceCraft', PULL_CAPABILITIES.list, query, pullRequestFilterSchema.options);\n const status = usedStatuses(query.status);\n const params = new URLSearchParams({ page_size: String(query.limit) });\n if (query.cursor !== undefined) params.set('page_token', query.cursor);\n const filter = pullFilterOf(query, status);\n if (filter !== undefined) params.set('filter', filter);\n if (query.sort !== undefined) params.set('sort_by', `${query.sort.direction === 'asc' ? '' : '-'}${PULL_SORT_FIELDS_UPSTREAM[query.sort.field]}`);\n const { body } = await requestJson(`${root}?${params.toString()}`, { fetch, headers });\n const record = isRecord(body) ? body : {};\n const pulls = (Array.isArray(record.pull_requests) ? record.pull_requests : []).map(pullOf).filter((pull) => matchesPage(pull, query));\n return { items: pulls, ...nextOf(record.next_page_token) };\n },\n get: (key) => getPull(key),\n create: async (input) => pullOf((await requestJson(root, { fetch, headers, method: 'POST', body: createBody(input) })).body),\n update: async (key, patch) => {\n const id = slug(key);\n let updated: unknown;\n if (patch.title !== undefined || patch.description !== undefined || patch.target !== undefined) {\n const body = {\n ...(patch.title === undefined ? {} : { title: patch.title }),\n ...(patch.description === undefined ? {} : { description: patch.description }),\n ...(patch.target === undefined ? {} : { target_branch: patch.target }),\n };\n updated = (await requestJson(`${root}/${id}`, { fetch, headers, method: 'PATCH', body, missing: missing(key) })).body;\n }\n if (patch.status !== undefined) {\n const action = statusActionOf(patch.status, (await getPull(key)).status.category);\n if (action !== undefined) await requestJson(`${root}/${id}/${action}`, { fetch, headers, method: 'POST', missing: missing(key) });\n return getPull(key);\n }\n return pullOf(updated ?? (await requestJson(`${root}/${id}`, { fetch, headers, missing: missing(key) })).body);\n },\n merge: async (key, input: MergeInput) => {\n const id = slug(key);\n if (input.message !== undefined) throw new TrackerError('unsupported', 'PR SourceCraft: сообщение коммита слияния не поддерживается.');\n if (input.method !== undefined && !PULL_CAPABILITIES.merge.includes(input.method)) {\n throw new TrackerError('unsupported', `PR SourceCraft: слияние способом ${input.method} не поддерживается.`);\n }\n if (input.headSha !== undefined) {\n const current = await getPull(key);\n // Проверка на клиенте, а не атомарная: push между чтением и POST /merge не отсекается; сравниваем в нижнем регистре.\n if ((current.headSha ?? '').toLowerCase() !== input.headSha.toLowerCase()) {\n throw new TrackerError('conflict', `Голова PR ${key} изменилась: ожидался ${input.headSha}, сейчас ${current.headSha ?? 'неизвестен'}.`);\n }\n }\n const { body } = await requestJson(`${root}/${id}/merge`, {\n fetch,\n headers,\n method: 'POST',\n // squash/rebase по умолчанию наследуются из настройки репозитория — без method не шлём явно false.\n body: {\n ...(input.method === undefined ? {} : { squash: input.method === 'squash', rebase: input.method === 'rebase' }),\n ...(input.deleteSource === undefined ? {} : { delete_branch: input.deleteSource }),\n },\n missing: missing(key),\n });\n const operation = isRecord(body) ? body : {};\n if (operation.status === 'failed' || operation.status === 'cancel') {\n const errorMessage = isRecord(operation.error) ? text(operation.error.message) : undefined;\n throw new TrackerError('conflict', `Слияние PR ${key} не запущено: ${redactSecretText(errorMessage ?? String(operation.status))}.`);\n }\n return getPull(key);\n },\n comments: async (key, query: CommentQuery) => {\n const id = slug(key);\n assertCommentQuery('Комментарии PR SourceCraft', PULL_CAPABILITIES.comments, query);\n const params = new URLSearchParams({ page_size: String(query.limit) });\n if (query.cursor !== undefined) params.set('page_token', query.cursor);\n if (query.order !== undefined) params.set('sort_by', query.order === 'asc' ? 'created_at' : '-created_at');\n const { body } = await requestJson(`${root}/${id}/comments?${params.toString()}`, { fetch, headers, missing: missing(key) });\n const record = isRecord(body) ? body : {};\n const rawComments = Array.isArray(record.pull_request_comments) ? record.pull_request_comments : [];\n const visible = rawComments.filter((raw) => !(isRecord(raw) && raw.is_deleted === true));\n const filtered = query.updatedAfter === undefined ? visible : visible.filter((raw) => inTimeRange(toTimestamp(isRecord(raw) ? raw.updated_at : undefined), query.updatedAfter, undefined));\n return { items: filtered.map(commentOf), ...nextOf(record.next_page_token) };\n },\n comment: async (key, body) => commentOf((await requestJson(`${root}/${slug(key)}/comments`, { fetch, headers, method: 'POST', body: { body }, missing: missing(key) })).body),\n };\n}\n\n/** Тело создания PR: publish по умолчанию false у трекера — открытый PR шлём явно. */\nfunction createBody(input: NewPullRequestInput): Record<string, unknown> {\n return {\n title: input.title,\n source_branch: input.source,\n target_branch: input.target,\n ...(input.description === undefined ? {} : { description: input.description }),\n publish: input.draft !== true,\n };\n}\n\n/** Конечная точка перехода состояния из текущего; переход «в то же состояние» — без запроса. */\nfunction statusActionOf(requested: Exclude<PullRequestStatusCategory, 'merged'>, current: PullRequestStatusCategory): string | undefined {\n if (current === requested) return undefined;\n if (requested === 'draft') return 'draft';\n if (requested === 'open') return current === 'draft' ? 'publish' : 'reopen';\n return 'discard';\n}\n\n/** Статусы списка: пустой массив — без фильтра; неизвестная категория — invalid_request до запроса. */\nfunction usedStatuses(status: readonly PullRequestStatusCategory[] | undefined): readonly PullRequestStatusCategory[] | undefined {\n if (status === undefined || status.length === 0) return undefined;\n for (const item of status) {\n if (!pullRequestStatusCategorySchema.options.includes(item)) {\n throw new TrackerError('invalid_request', `PR SourceCraft: неизвестная категория статуса ${String(item)}.`);\n }\n }\n return status;\n}\n\n/** Фильтры, которые QL SourceCraft не умеет, — по полученной странице (D-004). */\nfunction matchesPage(pull: PullRequest, query: PullRequestQuery): boolean {\n if (query.labels !== undefined && !query.labels.every((label) => pull.labels.includes(label))) return false;\n if (query.search !== undefined && !containsText([pull.title, pull.description], query.search)) return false;\n return inTimeRange(pull.createdAt, query.createdAfter, query.createdBefore) && inTimeRange(pull.updatedAt, query.updatedAfter, query.updatedBefore);\n}\n\n/** QL фильтр списка PR: статус — слаги через обратную таблицу; метки, поиск и время — на странице. */\nfunction pullFilterOf(query: PullRequestQuery, status: readonly PullRequestStatusCategory[] | undefined): string | undefined {\n const clauses: string[] = [];\n if (status !== undefined) {\n const slugs = [...new Set(keysFor(SOURCECRAFT_PULL_STATUSES, status))];\n clauses.push(`status in (${slugs.join(', ')})`);\n }\n if (query.author !== undefined) clauses.push(`author_slug=${quoted(query.author)}`);\n if (query.source !== undefined) clauses.push(`source_branch=${quoted(query.source)}`);\n if (query.target !== undefined) clauses.push(`target_branch=${quoted(query.target)}`);\n return clauses.length === 0 ? undefined : clauses.join(' and ');\n}\n\n/** Токен следующей страницы; пустая строка — последняя страница. */\nfunction nextOf(token: unknown): { nextCursor?: string } {\n const value = text(token);\n return value === undefined ? {} : { nextCursor: value };\n}\n\n/** PR единой модели из ответа трекера; веб-адрес PR не подтверждён (Q9) — ссылки пустые. */\nfunction pullOf(raw: unknown): PullRequest {\n const item = isRecord(raw) ? raw : {};\n const source = isRecord(item.source) ? item.source : {};\n const target = isRecord(item.target) ? item.target : {};\n const headSha = text(source.sha);\n const description = text(item.description);\n const author = isRecord(item.author) ? text(item.author.slug) : undefined;\n const createdAt = toTimestamp(item.created_at);\n const updatedAt = toTimestamp(item.updated_at);\n const mergedAt = toTimestamp(item.merged_at);\n const closedAt = toTimestamp(item.closed_at);\n const key = text(item.slug) ?? '?';\n const statusName = text(item.status) ?? 'open';\n return {\n key,\n title: text(item.title) ?? key,\n ...(description === undefined ? {} : { description }),\n status: { category: lookup(SOURCECRAFT_PULL_STATUSES, statusName, 'open'), name: statusName },\n ...(author === undefined ? {} : { author }),\n source: text(source.ref) ?? text(item.source_branch) ?? '?',\n target: text(target.ref) ?? text(item.target_branch) ?? '?',\n ...(headSha !== undefined && SHA.test(headSha) ? { headSha } : {}),\n labels: Array.isArray(item.labels) ? stringList(item.labels.map((label) => (isRecord(label) ? label.name : undefined))) : [],\n links: [],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n ...(mergedAt === undefined ? {} : { mergedAt }),\n ...(closedAt === undefined ? {} : { closedAt }),\n };\n}\n\nfunction commentOf(raw: unknown): IssueComment {\n const item = isRecord(raw) ? raw : {};\n const author = isRecord(item.author) ? text(item.author.slug) : undefined;\n const createdAt = toTimestamp(item.created_at);\n return { id: text(item.id) ?? '?', ...(author === undefined ? {} : { author }), body: typeof item.body === 'string' ? item.body : '', ...(createdAt === undefined ? {} : { createdAt }) };\n}\n","// Адаптер SourceCraft библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/sourcecraft.lib.ts — дословная копия, импорт типов из среза контракта библиотеки;\n// фильтры и сортировка списков — свои (#14): QL filter, sort_by, проверка по возможностям.\nimport type { Issue, IssueComment } from '../contract/contract.types.ts';\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { sourcecraftCi } from './sourcecraft-ci.lib.ts';\nimport { ALL_STATUSES, SOURCECRAFT_PRIORITIES, SOURCECRAFT_STATUSES, SOURCECRAFT_STATUS_FILTER, SOURCECRAFT_STATUS_SLUGS } from './mapping.const.ts';\nimport { COMMENT_FILTERS, ISSUE_FILTERS } from './tracker.const.ts';\nimport type { IssueSortField } from './tracker.const.ts';\nimport { TrackerError, assertCommentQuery, assertListQuery, inTimeRange, isRecord, isoTime, lookup, quoted, requireTarget, stringList, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext, IssueCapabilities, IssuePatchInput, IssueQuery, TrackerAdapter, TrackerDefinition } from './tracker.types.ts';\nimport { sourcecraftPulls } from './sourcecraft-pull.lib.ts';\n\n// Трекер SourceCraft (D-350): задачи репозитория `org/repo` через REST API, токен — Bearer. Исполнитель и метки\n// у SourceCraft задаются по id, а не по имени: адаптер их показывает, но не меняет.\n\nconst DEFAULT_API = 'https://api.sourcecraft.tech';\nconst DEFAULT_WEB = 'https://sourcecraft.dev';\nconst TARGET = /^[\\w.-]+\\/[\\w.-]+$/;\nconst SLUG = /^[\\w-]{1,100}$/;\n\n/** Поля сортировки единой модели → поля sort_by SourceCraft; comments адаптер не поддерживает (отказ в assertListQuery). */\nconst ISSUE_SORT_FIELDS_UPSTREAM: Readonly<Partial<Record<IssueSortField, string>>> = {\n created: 'created_at',\n updated: 'updated_at',\n priority: 'priority',\n title: 'title',\n};\n\n/** Возможности списков SourceCraft: QL фильтрует сервером; null исполнителя в списке и updatedAfter\n * комментариев проверяются по полученной странице (D-004). */\nconst ISSUE_CAPABILITIES: IssueCapabilities = {\n list: { filters: ISSUE_FILTERS, clientSide: ['assignee'], sorts: ['created', 'updated', 'priority', 'title'] },\n comments: { filters: COMMENT_FILTERS, clientSide: COMMENT_FILTERS, order: ['asc', 'desc'] },\n};\n\nexport function sourcecraftTracker(): TrackerDefinition {\n return {\n descriptor: {\n tracker: 'sourcecraft',\n title: 'SourceCraft',\n fields: [\n { name: 'target', required: true, secret: false },\n { name: 'token', required: true, secret: true },\n { name: 'url', required: false, secret: false },\n ],\n features: { create: true, update: true, comment: true, priority: true, labels: false, assignee: false, statuses: [...ALL_STATUSES] },\n },\n issues: ISSUE_CAPABILITIES,\n create: (context) => createSourceCraftAdapter(context),\n pulls: sourcecraftPulls(),\n ci: sourcecraftCi(),\n };\n}\n\nfunction createSourceCraftAdapter({ connection, fetch }: AdapterContext): TrackerAdapter {\n const target = requireTarget(connection.target, 'org/repo репозитория SourceCraft');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target SourceCraft — org/repo.');\n const api = baseUrl(connection.url, DEFAULT_API);\n const root = `${api}/repos/${target}/issues`;\n const headers = { authorization: `Bearer ${connection.token ?? ''}` };\n const web = connection.url === undefined ? `${DEFAULT_WEB}/${target}/issues` : undefined;\n const slug = (key: string): string => {\n if (!SLUG.test(key)) throw new TrackerError('unknown_issue', `В SourceCraft нет задачи ${key}.`);\n return key;\n };\n const toIssue = (raw: unknown): Issue => issueOf(raw, web);\n return {\n list: async (query) => {\n assertListQuery('Задачи SourceCraft', ISSUE_CAPABILITIES.list, query, ISSUE_FILTERS);\n const params = new URLSearchParams({ page_size: String(query.limit) });\n if (query.cursor !== undefined) params.set('page_token', query.cursor);\n const filter = issueFilterOf(query);\n if (filter !== undefined) params.set('filter', filter);\n if (query.sort !== undefined) params.set('sort_by', `${query.sort.direction === 'asc' ? '' : '-'}${issueSortFieldOf(query.sort.field)}`);\n const { body } = await requestJson(`${root}?${params.toString()}`, { fetch, headers });\n const record = isRecord(body) ? body : {};\n let issues = (Array.isArray(record.issues) ? record.issues : []).map(toIssue);\n if (query.status !== undefined) issues = issues.filter((issue) => query.status?.includes(issue.status.category) === true);\n if (query.assignee === null) issues = issues.filter((issue) => issue.assignee === undefined);\n return { items: issues, ...nextOf(record.next_page_token) };\n },\n get: async (key) => toIssue((await requestJson(`${root}/${slug(key)}`, { fetch, headers, missingIsIssue: true })).body),\n create: async (input) => {\n const body = { title: input.title, ...(input.description === undefined ? {} : { description: input.description }), ...(input.priority === undefined ? {} : { priority: input.priority }) };\n return toIssue((await requestJson(root, { fetch, headers, method: 'POST', body })).body);\n },\n update: async (key, patch) => toIssue((await requestJson(`${root}/${slug(key)}`, { fetch, headers, method: 'PATCH', body: patchBody(patch), missingIsIssue: true })).body),\n comments: async (key, query) => {\n assertCommentQuery('Комментарии SourceCraft', ISSUE_CAPABILITIES.comments, query);\n const params = new URLSearchParams({ page_size: String(query.limit) });\n if (query.cursor !== undefined) params.set('page_token', query.cursor);\n if (query.order !== undefined) params.set('sort_by', query.order === 'asc' ? 'created_at' : '-created_at');\n const { body } = await requestJson(`${root}/${slug(key)}/comments?${params.toString()}`, { fetch, headers, missingIsIssue: true });\n const record = isRecord(body) ? body : {};\n const rawComments = Array.isArray(record.issue_comments) ? record.issue_comments : [];\n const filtered = query.updatedAfter === undefined ? rawComments : rawComments.filter((raw) => inTimeRange(toTimestamp(isRecord(raw) ? raw.updated_at : undefined), query.updatedAfter, undefined));\n return { items: filtered.map(commentOf), ...nextOf(record.next_page_token) };\n },\n comment: async (key, body) => commentOf((await requestJson(`${root}/${slug(key)}/comments`, { fetch, headers, method: 'POST', body: { body }, missingIsIssue: true })).body),\n };\n}\n\nfunction patchBody(patch: IssuePatchInput): Record<string, unknown> {\n return {\n ...(patch.title === undefined ? {} : { title: patch.title }),\n ...(patch.description === undefined ? {} : { description: patch.description }),\n ...(patch.status === undefined ? {} : { status_slug: SOURCECRAFT_STATUS_SLUGS[patch.status] }),\n ...(patch.priority === undefined ? {} : { priority: patch.priority }),\n };\n}\n\n/** Токен следующей страницы; пустая строка — последняя страница. */\nfunction nextOf(token: unknown): { nextCursor?: string } {\n const value = text(token);\n return value === undefined ? {} : { nextCursor: value };\n}\n\n/** Поле сортировки единой модели → поле sort_by SourceCraft; неподдерживаемое поле — отказ (R-002). */\nfunction issueSortFieldOf(field: IssueSortField): string {\n const upstream = ISSUE_SORT_FIELDS_UPSTREAM[field];\n if (upstream === undefined) throw new TrackerError('unsupported', `Задачи SourceCraft: сортировка по ${field} не поддерживается.`);\n return upstream;\n}\n\n/** QL фильтр списка задач: предложения через ` and `; исполнитель null — на странице, а не в QL (assignee_id=null даёт 500). */\nfunction issueFilterOf(query: IssueQuery): string | undefined {\n const clauses: string[] = [];\n if (query.status !== undefined && query.status.length > 0) {\n const slugs = [...new Set(query.status.flatMap((category) => SOURCECRAFT_STATUS_FILTER[category]))];\n clauses.push(`status in (${slugs.join(', ')})`);\n }\n for (const label of query.labels ?? []) clauses.push(`label_slug=${quoted(label)}`);\n if (typeof query.assignee === 'string') clauses.push(`assignee_slug=${quoted(query.assignee)}`);\n if (query.author !== undefined) clauses.push(`author_slug=${quoted(query.author)}`);\n if (query.search !== undefined) clauses.push(`title=${quoted(query.search)}`);\n if (query.createdAfter !== undefined) clauses.push(`created_at>=${quoted(isoTime(query.createdAfter))}`);\n if (query.createdBefore !== undefined) clauses.push(`created_at<=${quoted(isoTime(query.createdBefore))}`);\n if (query.updatedAfter !== undefined) clauses.push(`updated_at>=${quoted(isoTime(query.updatedAfter))}`);\n if (query.updatedBefore !== undefined) clauses.push(`updated_at<=${quoted(isoTime(query.updatedBefore))}`);\n return clauses.length === 0 ? undefined : clauses.join(' and ');\n}\n\nfunction issueOf(raw: unknown, web: string | undefined): Issue {\n const item = isRecord(raw) ? raw : {};\n const status = isRecord(item.status) ? item.status : {};\n const slug = text(item.slug) ?? '?';\n const statusSlug = text(status.slug) ?? 'open';\n const priority = lookup<Issue['priority']>(SOURCECRAFT_PRIORITIES, item.priority, undefined);\n const assignee = isRecord(item.assignee) ? text(item.assignee.slug) : undefined;\n const labels = Array.isArray(item.labels) ? stringList(item.labels.map((label) => (isRecord(label) ? label.name : undefined))) : [];\n const description = text(item.description);\n const createdAt = toTimestamp(item.created_at);\n const updatedAt = toTimestamp(item.updated_at);\n return {\n key: slug,\n title: text(item.title) ?? slug,\n ...(description === undefined ? {} : { description }),\n status: { category: lookup(SOURCECRAFT_STATUSES, statusSlug, 'open'), name: text(status.name) ?? statusSlug },\n ...(priority === undefined ? {} : { priority }),\n labels,\n ...(assignee === undefined ? {} : { assignee }),\n links: web === undefined ? [] : [{ url: `${web}/${slug}`, title: 'SourceCraft' }],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n };\n}\n\nfunction commentOf(raw: unknown): IssueComment {\n const item = isRecord(raw) ? raw : {};\n const author = isRecord(item.author) ? text(item.author.slug) : undefined;\n const createdAt = toTimestamp(item.created_at);\n return { id: text(item.id) ?? '?', ...(author === undefined ? {} : { author }), body: typeof item.body === 'string' ? item.body : '', ...(createdAt === undefined ? {} : { createdAt }) };\n}\n","// Встроенные трекеры библиотеки @smwb/onreel-git-mcp (часть E выделения, R-001).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/builtin.lib.ts — дословная копия. Регистрация была побочным эффектом импорта\n// guard.lib (onreel); в библиотеке она — только явный вызов registerBuiltinTrackers(), идемпотентный.\nimport { githubTracker } from './github.lib.ts';\nimport { gitlabTracker } from './gitlab.lib.ts';\nimport { jiraTracker } from './jira.lib.ts';\nimport { localTracker } from './local.lib.ts';\nimport { registerTracker } from './registry.lib.ts';\nimport { sourcecraftTracker } from './sourcecraft.lib.ts';\n\n// Трекеры, которые библиотека поставляет сама (D-350). Новый трекер добавляется модулем с\n// `TrackerDefinition` и строкой здесь: реестр и адаптеры не меняются.\n\nlet registered = false;\n\nexport function registerBuiltinTrackers(): void {\n if (registered) return;\n registered = true;\n for (const definition of [localTracker(), sourcecraftTracker(), githubTracker(), gitlabTracker(), jiraTracker()]) registerTracker(definition);\n}\n","// Хранение токенов подключений трекеров библиотеки @smwb/onreel-git-mcp (часть E выделения, D-352).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/secrets.lib.ts — копия; шов журнала host заменён на SecretSink ядра\n// (kernel/log.types.ts): по умолчанию defaultSecretSink общего redactor'а ядра (kernel/redact.lib.ts),\n// потребитель со своим журналом подставляет свой приёмник. Регистрация секрета не обязательна\n// для работы хранилища — это подсказка для маскирования текстов ошибок и журналов.\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { defaultSecretSink } from '../kernel/redact.lib.ts';\nimport type { SecretSink } from '../kernel/log.types.ts';\nimport { TRACKER_SECRETS_FILE } from './tracker.const.ts';\nimport { isRecord } from './tracker.lib.ts';\n\n// Секреты подключений (D-352): токены по projectId в файле 0600 каталога данных потребителя. В хранилище\n// задач, ответы и журналы они не попадают: наружу идёт только признак «токен есть», а значение при чтении\n// и записи регистрируется в приёмнике секретов как известный секрет (D-194).\n\n/** Записи идут по одной: чтение-правка-запись двух подключений не затирает друг друга. */\nlet queue: Promise<unknown> = Promise.resolve();\n\nfunction exclusive<T>(task: () => Promise<T>): Promise<T> {\n const run = queue.then(task, task);\n queue = run.catch(() => undefined);\n return run;\n}\n\nasync function readAll(dataDir: string): Promise<Record<string, string>> {\n let raw: string;\n try {\n raw = await readFile(join(dataDir, TRACKER_SECRETS_FILE), 'utf8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return {};\n throw error;\n }\n const parsed: unknown = JSON.parse(raw);\n if (!isRecord(parsed)) return {};\n return Object.fromEntries(Object.entries(parsed).filter((entry): entry is [string, string] => typeof entry[1] === 'string'));\n}\n\nasync function writeAll(dataDir: string, secrets: Record<string, string>): Promise<void> {\n await mkdir(dataDir, { recursive: true, mode: 0o700 });\n const target = join(dataDir, TRACKER_SECRETS_FILE);\n const temp = `${target}.${String(process.pid)}.tmp`;\n await writeFile(temp, JSON.stringify(secrets), { mode: 0o600 });\n await rename(temp, target);\n}\n\n/** Токен проекта; undefined — не задан. Значение регистрируется в приёмнике секретов. */\nexport async function readTrackerToken(dataDir: string, projectId: string, sink: SecretSink = defaultSecretSink): Promise<string | undefined> {\n const token = (await readAll(dataDir))[projectId];\n if (token !== undefined) sink.register(token);\n return token;\n}\n\nexport function hasTrackerToken(dataDir: string, projectId: string): Promise<boolean> {\n return readAll(dataDir).then((secrets) => secrets[projectId] !== undefined);\n}\n\n/** Задаёт токен проекта; пустая строка убирает. */\nexport function writeTrackerToken(dataDir: string, projectId: string, token: string, sink: SecretSink = defaultSecretSink): Promise<void> {\n if (token !== '') sink.register(token);\n return exclusive(async () => {\n const secrets = await readAll(dataDir);\n if (token === '') delete secrets[projectId];\n else secrets[projectId] = token;\n await writeAll(dataDir, secrets);\n });\n}\n\nexport function deleteTrackerToken(dataDir: string, projectId: string, sink: SecretSink = defaultSecretSink): Promise<void> {\n return writeTrackerToken(dataDir, projectId, '', sink);\n}\n","// Помощники pull request-ов библиотеки @smwb/onreel-git-mcp — свои (#15).\nimport type { PullRequestAdapter } from './pull.types.ts';\nimport { TrackerError } from './tracker.lib.ts';\nimport type { AdapterContext, TrackerDefinition } from './tracker.types.ts';\n\n/** Адаптер PR трекера (D-005); трекер без раздела pulls — TrackerError('unsupported', 'Трекер <title> не ведёт pull request-ы.'). */\nexport function pullRequestAdapterOf(definition: TrackerDefinition, context: AdapterContext): PullRequestAdapter {\n if (definition.pulls === undefined) throw new TrackerError('unsupported', `Трекер ${definition.descriptor.title} не ведёт pull request-ы.`);\n return definition.pulls.create(context);\n}\n"],"mappings":"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","names":["text","TARGET","ID","RUN_FILTERS","JOB_FILTERS","CAPABILITIES","runOf","pageOf","jobOf","DEFAULT_API","TARGET","RUN_FILTERS","JOB_FILTERS","CAPABILITIES","runOf","jobOf","z","z","DEFAULT_API","TARGET","SHA","pageOf","DEFAULT_API","TARGET","NUMBER","LIST_SUBJECT","COMMENTS_SUBJECT","pageOf","rowsOf","patchBody","commentOf","stateFilter","DEFAULT_URL","TARGET","SHA","PULL_CAPABILITIES","pullOf","usedStatuses","pageOf","stateFilter","patchBody","commentOf","DEFAULT_URL","TARGET","IID","ORDER_BY","issueOf","pageOf","stateFilter","composeLabels","patchBody","commentOf","ISSUE_CAPABILITIES","toIssue","issueOf","params","body","record","commentOf","priorityName","ISSUE_CAPABILITIES","DEFAULT_API","TARGET","SHA","PULL_CAPABILITIES","pullOf","usedStatuses","matchesPage","nextOf","createBody","commentOf","DEFAULT_API","TARGET","SLUG","ISSUE_CAPABILITIES","toIssue","issueOf","nextOf","patchBody","commentOf"]}
1
+ {"version":3,"sources":["../../src/tracker/tracker.const.ts","../../src/tracker/tracker.lib.ts","../../src/tracker/mapping.const.ts","../../src/tracker/http.lib.ts","../../src/tracker/ci.schema.ts","../../src/tracker/ci.lib.ts","../../src/tracker/github-ci.lib.ts","../../src/tracker/gitlab-ci.lib.ts","../../src/tracker/sourcecraft-ci.lib.ts","../../src/tracker/registry.lib.ts","../../src/tracker/pull.schema.ts","../../src/tracker/github-pull.lib.ts","../../src/tracker/repo.schema.ts","../../src/tracker/github-repo.lib.ts","../../src/tracker/github.lib.ts","../../src/tracker/gitlab-pull.lib.ts","../../src/tracker/gitlab-repo.lib.ts","../../src/tracker/gitlab.lib.ts","../../src/tracker/jira.lib.ts","../../src/tracker/local.lib.ts","../../src/tracker/sourcecraft-pull.lib.ts","../../src/tracker/sourcecraft-repo.lib.ts","../../src/tracker/sourcecraft.lib.ts","../../src/tracker/builtin.lib.ts","../../src/tracker/secrets.lib.ts","../../src/tracker/pull.lib.ts","../../src/tracker/repo.lib.ts"],"sourcesContent":["// Константы адаптеров трекеров библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/tracker.const.ts — дословная копия; фильтры и возможности списков — свои (#14),\n// пределы лога CI — свои (#16).\nimport type { CiStatusCategory } from './ci.schema.ts';\nimport type { IssueCapabilities } from './tracker.types.ts';\n\n/** Потолок ожидания ответа внешнего трекера, мс. */\nexport const TRACKER_TIMEOUT_MS = 15_000;\n\n/** Размер страницы списка задач по умолчанию; потолок — 500 по контракту. */\nexport const TRACKER_PAGE_LIMIT_DEFAULT = 50;\n\n/** Сколько символов тела ответа трекера попадает в текст ошибки. */\nexport const TRACKER_ERROR_BODY_MAX = 300;\n\n/** Файл секретов подключений в каталоге данных host: токены трекеров по projectId, права 0600 (D-352). */\nexport const TRACKER_SECRETS_FILE = 'tracker-secrets.json';\n\n/** Автор комментариев, которые пользователь пишет в локальном трекере. */\nexport const TRACKER_LOCAL_AUTHOR = 'owner';\n\n/** Фильтры списка задач — имена полей IssueQuery; порядок — для текстов отказов. */\nexport const ISSUE_FILTERS = ['status', 'labels', 'assignee', 'author', 'search', 'createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore'] as const;\nexport type IssueFilter = (typeof ISSUE_FILTERS)[number];\n\n/** Поля сортировки задач единой модели. */\nexport const ISSUE_SORT_FIELDS = ['created', 'updated', 'priority', 'title', 'comments'] as const;\nexport type IssueSortField = (typeof ISSUE_SORT_FIELDS)[number];\n\n/** Фильтры списка комментариев — имена полей CommentQuery. */\nexport const COMMENT_FILTERS = ['updatedAfter'] as const;\nexport type CommentFilter = (typeof COMMENT_FILTERS)[number];\n\n/** Возможности трекера без раздела issues (свои трекеры потребителя): статус и страницы, комментарии по порядку. */\nexport const LEGACY_ISSUE_CAPABILITIES: IssueCapabilities = {\n list: { filters: ['status'], clientSide: ['status'], sorts: [] },\n comments: { filters: [], clientSide: [], order: ['asc'] },\n};\n\n/** Окно лога CI по умолчанию и потолок окна одного вызова, байт (D-006). */\nexport const CI_LOG_DEFAULT_BYTES = 16 * 1024;\nexport const CI_LOG_MAX_BYTES = 1024 * 1024;\n/** Потолок чтения тела лога: дальше поток обрывается, лог — truncated. */\nexport const CI_LOG_READ_MAX_BYTES = 64 * 1024 * 1024;\n/** Сколько редиректов проходит один запрос к трекеру; следующий — отказ failed. */\nexport const TRACKER_REDIRECT_MAX = 5;\n/** Таймаут загрузки лога, мс: логи больше ответов API. */\nexport const CI_LOG_TIMEOUT_MS = 60_000;\n/** Сколько страниц лога SourceCraft читается за один вызов log(). */\nexport const CI_LOG_PAGES_MAX = 50;\n/** Законченные категории CI. */\nexport const CI_FINISHED_STATUSES: readonly CiStatusCategory[] = ['success', 'failed', 'canceled', 'skipped'];\n","// Чистые помощники адаптеров трекеров библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/tracker.lib.ts — дословная копия, импорт типов из среза контракта библиотеки;\n// проверка запросов списков и помощники фильтров — свои (#14).\nimport type { IssuePriority, IssueStatusCategory } from '../contract/contract.types.ts';\nimport { COMMENT_FILTERS, LEGACY_ISSUE_CAPABILITIES } from './tracker.const.ts';\nimport type { CommentCapabilities, CommentQuery, IssueCapabilities, ListCapabilities, ListSort, TrackerDefinition, TrackerFailure } from './tracker.types.ts';\n\n/** Отказ адаптера: потребитель превращает его в ошибку своего контракта (D-353). */\nexport class TrackerError extends Error {\n readonly failure: TrackerFailure;\n constructor(failure: TrackerFailure, message: string) {\n super(message);\n this.name = 'TrackerError';\n this.failure = failure;\n }\n}\n\n/** Время трекера (ISO 8601) в миллисекунды; нет или не разобралось — undefined. */\nexport function toTimestamp(value: unknown): number | undefined {\n if (typeof value !== 'string') return undefined;\n const ms = Date.parse(value);\n return Number.isFinite(ms) && ms >= 0 ? ms : undefined;\n}\n\n/** Поле, которое задано: непустая строка. */\nexport function text(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\nexport function clipText(value: string, max: number): string {\n return value.length <= max ? value : value.slice(0, max);\n}\n\n/** Строки из массива неизвестного вида: непустые строки без дублей. */\nexport function stringList(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return [...new Set(value.filter((item): item is string => typeof item === 'string' && item !== ''))];\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Категория и приоритет по таблице; нет в таблице — запасное значение. */\nexport function lookup<T>(table: Readonly<Record<string, T>>, key: unknown, fallback: T): T {\n return typeof key === 'string' && Object.hasOwn(table, key) ? (table[key] as T) : fallback;\n}\n\nexport function requireTarget(target: string | undefined, hint: string): string {\n if (target === undefined) throw new TrackerError('invalid_request', `Не задан target подключения: ${hint}.`);\n return target;\n}\n\n/** Обратная таблица: категория → первое имя статуса трекера. */\nexport function nameOf(table: Readonly<Record<string, IssueStatusCategory>>, category: IssueStatusCategory): string | undefined {\n return Object.entries(table).find(([, value]) => value === category)?.[0];\n}\n\nexport function priorityName(table: Readonly<Record<string, IssuePriority>>, priority: IssuePriority): string | undefined {\n return Object.entries(table).find(([, value]) => value === priority)?.[0];\n}\n\n/** Фильтры запроса со значением (не undefined и не пустой массив), в порядке names. */\nexport function usedFilters<F extends string>(query: Readonly<Partial<Record<F, unknown>>>, names: readonly F[]): F[] {\n return names.filter((name) => {\n const value = query[name];\n return value !== undefined && !(Array.isArray(value) && value.length === 0);\n });\n}\n\n/**\n * Проверка запроса списка по возможностям (D-004, R-002): фильтр со значением вне filters или sort.field вне sorts —\n * TrackerError('unsupported', `${subject}: фильтр ${name} не поддерживается.`); значение не той формы — invalid_request:\n * время не числом или не целое ≥ 0, пустая строка фильтра, список со строкой-пустышкой. subject — что за список:\n * 'Задачи GitHub', 'PR GitLab', 'Прогоны CI SourceCraft'.\n */\nexport function assertListQuery<F extends string, S extends string>(\n subject: string,\n capabilities: ListCapabilities<F, S>,\n query: Readonly<Partial<Record<F, unknown>>> & { readonly sort?: ListSort<S> | undefined },\n names: readonly F[],\n): void {\n const used = usedFilters(query, names);\n for (const name of used) {\n if (!capabilities.filters.includes(name)) throw new TrackerError('unsupported', `${subject}: фильтр ${name} не поддерживается.`);\n }\n const sort = query.sort;\n if (sort !== undefined && !capabilities.sorts.includes(sort.field)) {\n throw new TrackerError('unsupported', `${subject}: сортировка по ${sort.field} не поддерживается.`);\n }\n if (sort?.direction !== undefined && sort.direction !== 'asc' && sort.direction !== 'desc') {\n throw new TrackerError('invalid_request', `${subject}: направление сортировки — asc или desc.`);\n }\n // limit — поле PageQuery, а не фильтр: проверяется, когда запрос его несёт.\n const limit = (query as { readonly limit?: unknown }).limit;\n if (limit !== undefined && !(typeof limit === 'number' && Number.isSafeInteger(limit) && limit >= 1)) {\n throw new TrackerError('invalid_request', `${subject}: limit — целое число от 1.`);\n }\n for (const name of used) {\n const value = query[name];\n if (isTimeFilter(name)) {\n if (typeof value !== 'number' || !(Number.isSafeInteger(value) && value >= 0)) {\n throw new TrackerError('invalid_request', `${subject}: фильтр ${name} — время в мс, целое число от 0.`);\n }\n continue;\n }\n if (isArrayFilter(name)) {\n if (!Array.isArray(value) || value.some((item) => typeof item !== 'string' || item.trim() === '')) {\n throw new TrackerError('invalid_request', `${subject}: фильтр ${name} — список непустых строк.`);\n }\n continue;\n }\n if (value === null) continue; // null — значение фильтра: assignee null — задачи без исполнителя.\n if (typeof value === 'string') {\n if (value.trim() === '') throw new TrackerError('invalid_request', `${subject}: фильтр ${name} — пустая строка.`);\n continue;\n }\n if (Array.isArray(value)) {\n if (value.some((item) => typeof item !== 'string' || item.trim() === '')) {\n throw new TrackerError('invalid_request', `${subject}: фильтр ${name} — список непустых строк.`);\n }\n continue;\n }\n throw new TrackerError('invalid_request', `${subject}: фильтр ${name} — строка, список строк или null.`);\n }\n}\n\n/** Фильтры времени единой модели называются …After и …Before (createdAfter, updatedBefore). */\nfunction isTimeFilter(name: string): boolean {\n return name.endsWith('After') || name.endsWith('Before');\n}\n\n/** Списковые фильтры единой модели (status, labels): значение — массив строк, скалер здесь — опечатка вызова. */\nfunction isArrayFilter(name: string): boolean {\n return name === 'status' || name === 'labels';\n}\n\n/** Проверка запроса комментариев: updatedAfter вне filters или order вне capabilities.order — unsupported. */\nexport function assertCommentQuery(subject: string, capabilities: CommentCapabilities, query: CommentQuery): void {\n assertListQuery(subject, { filters: capabilities.filters, clientSide: capabilities.clientSide, sorts: [] }, query, COMMENT_FILTERS);\n if (query.order !== undefined && !capabilities.order.includes(query.order)) {\n throw new TrackerError('unsupported', `${subject}: порядок ${query.order} не поддерживается.`);\n }\n}\n\n/** Возможности задач трекера: раздел issues или LEGACY_ISSUE_CAPABILITIES. */\nexport function issueCapabilitiesOf(definition: TrackerDefinition): IssueCapabilities {\n return definition.issues ?? LEGACY_ISSUE_CAPABILITIES;\n}\n\n/** Мс единой модели → ISO 8601 UTC для параметров трекера. */\nexport function isoTime(ms: number): string {\n return new Date(ms).toISOString();\n}\n\n/** Время записи в границах [after, before] включительно; граница задана, а время неизвестно — не проходит. */\nexport function inTimeRange(value: number | undefined, after: number | undefined, before: number | undefined): boolean {\n if (after === undefined && before === undefined) return true;\n if (value === undefined) return false;\n return (after === undefined || value >= after) && (before === undefined || value <= before);\n}\n\n/** Есть ли needle (без учёта регистра) подстрокой в одном из текстов. */\nexport function containsText(texts: readonly (string | undefined)[], needle: string): boolean {\n const lower = needle.toLowerCase();\n return texts.some((value) => value !== undefined && value.toLowerCase().includes(lower));\n}\n\n/** Значение в двойных кавычках для JQL, QL SourceCraft и q поиска GitHub: экранирует \\ и \". */\nexport function quoted(value: string): string {\n return `\"${value.replace(/[\\\\\"]/g, '\\\\$&')}\"`;\n}\n\n/** Ключи таблицы сопоставления, чьё значение — одна из категорий (обратный поиск для фильтров трекера). */\nexport function keysFor<T>(table: Readonly<Record<string, T>>, values: readonly T[]): string[] {\n return Object.entries(table)\n .filter(([, value]) => values.includes(value))\n .map(([key]) => key);\n}\n","// Таблицы сопоставления статусов и приоритетов трекеров библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/mapping.const.ts — дословная копия, импорт типов из среза контракта библиотеки;\n// SOURCECRAFT_STATUS_FILTER — свой (#14); таблицы pull request-ов — свои (#15), таблицы CI — свои (#16).\nimport type { IssuePriority, IssueStatusCategory } from '../contract/contract.types.ts';\nimport type { CiEventCategory, CiStatusCategory } from './ci.schema.ts';\nimport type { PullRequestStatusCategory } from './pull.schema.ts';\n\n// Сопоставление статусов и приоритетов трекеров с единой моделью (D-351). Ключ — слаг или имя у трекера,\n// значение — категория единой модели. Не найденное в таблице: статус → `open`, приоритет не заполняется.\n\n/** SourceCraft: системные статусы. На паузе — ещё не закончено, но и не в работе: `open`. */\nexport const SOURCECRAFT_STATUSES: Readonly<Record<string, IssueStatusCategory>> = {\n open: 'open',\n paused: 'open',\n inProgress: 'in_progress',\n closed: 'done',\n declined: 'declined',\n duplicate: 'declined',\n};\n\n/** Категория → слаг статуса SourceCraft при переводе задачи. */\nexport const SOURCECRAFT_STATUS_SLUGS: Readonly<Record<IssueStatusCategory, string>> = {\n open: 'open',\n in_progress: 'inProgress',\n done: 'closed',\n declined: 'declined',\n};\n\n/** Категория → слаги статусов QL фильтра списка (`status in (…)`); QL принимает только слаги, не имена. */\nexport const SOURCECRAFT_STATUS_FILTER: Readonly<Record<IssueStatusCategory, readonly string[]>> = {\n open: ['open', 'paused'],\n in_progress: ['in_progress'],\n done: ['closed'],\n declined: ['declined', 'duplicate'],\n};\n\n/** Приоритеты SourceCraft совпадают с единой моделью по именам. */\nexport const SOURCECRAFT_PRIORITIES: Readonly<Record<string, IssuePriority>> = {\n trivial: 'trivial',\n minor: 'minor',\n normal: 'normal',\n critical: 'critical',\n blocker: 'blocker',\n};\n\n/** Jira: `statusCategory.key` статуса. */\nexport const JIRA_STATUS_CATEGORIES: Readonly<Record<string, IssueStatusCategory>> = {\n new: 'open',\n indeterminate: 'in_progress',\n done: 'done',\n};\n\n/** Jira: имена приоритетов схемы по умолчанию (регистр не важен, ключи в нижнем). */\nexport const JIRA_PRIORITIES: Readonly<Record<string, IssuePriority>> = {\n lowest: 'trivial',\n low: 'minor',\n medium: 'normal',\n high: 'critical',\n highest: 'blocker',\n};\n\n/** Категория → имя приоритета Jira при создании и правке. */\nexport const JIRA_PRIORITY_NAMES: Readonly<Record<IssuePriority, string>> = {\n trivial: 'Lowest',\n minor: 'Low',\n normal: 'Medium',\n critical: 'High',\n blocker: 'Highest',\n};\n\n/** Тип задачи Jira, который создаёт адаптер. */\nexport const JIRA_ISSUE_TYPE = 'Task';\n\n/** GitHub: причина закрытия `state_reason`. */\nexport const GITHUB_CLOSE_REASONS: Readonly<Record<string, IssueStatusCategory>> = {\n completed: 'done',\n not_planned: 'declined',\n duplicate: 'declined',\n};\n\n/** GitLab: приоритеты нет, но принято помечать задачи метками `priority::<имя>`; метка читается как приоритет. */\nexport const GITLAB_PRIORITY_LABELS: Readonly<Record<string, IssuePriority>> = {\n 'priority::trivial': 'trivial',\n 'priority::minor': 'minor',\n 'priority::normal': 'normal',\n 'priority::critical': 'critical',\n 'priority::blocker': 'blocker',\n};\n\n/** Метка GitLab, которой адаптер отмечает «в работе»: у GitLab только opened и closed. */\nexport const GITLAB_IN_PROGRESS_LABEL = 'status::in-progress';\n\n/** Метка GitHub для «в работе» — по той же причине. */\nexport const GITHUB_IN_PROGRESS_LABEL = 'in progress';\n\n/** Метки GitHub для приоритета: `priority: <имя>`. */\nexport const GITHUB_PRIORITY_LABELS: Readonly<Record<string, IssuePriority>> = {\n 'priority: trivial': 'trivial',\n 'priority: minor': 'minor',\n 'priority: normal': 'normal',\n 'priority: critical': 'critical',\n 'priority: blocker': 'blocker',\n};\n\nexport const ALL_STATUSES: readonly IssueStatusCategory[] = ['open', 'in_progress', 'done', 'declined'];\n\n// Pull request-ы (D-005): состояние у трекера → категория единой модели.\n\n/** GitLab: state MR → категория; черновик — поле draft открытого MR. locked — слияние идёт, MR ещё открыт. */\nexport const GITLAB_MERGE_REQUEST_STATES: Readonly<Record<string, PullRequestStatusCategory>> = {\n opened: 'open',\n locked: 'open',\n merged: 'merged',\n closed: 'closed',\n};\n\n/** GitLab: префикс заголовка, которым адаптер делает MR черновиком. */\nexport const GITLAB_DRAFT_PREFIX = 'Draft: ';\n\n/** GitLab: все формы префикса черновика, которые снимаются при переводе в open. */\nexport const GITLAB_DRAFT_PATTERN = /^\\s*(?:\\[draft\\]|\\(draft\\)|draft:)\\s*/i;\n\n/** SourceCraft: состояния PR. merging — слияние идёт, PR ещё открыт; discarded — закрыт без слияния. */\nexport const SOURCECRAFT_PULL_STATUSES: Readonly<Record<string, PullRequestStatusCategory>> = {\n draft: 'draft',\n open: 'open',\n merging: 'open',\n merged: 'merged',\n discarded: 'closed',\n};\n\n// Сопоставление состояний и событий CI с единой моделью (D-006). Не найденный статус — `running`: не закончено,\n// и тот, кто ждёт конца прогона, продолжает опрос. Законченный прогон GitHub с незнакомым conclusion — `failed`:\n// незнакомое не бывает зелёным.\n\n/** GitHub: status прогона, задания и шага, пока не completed. */\nexport const GITHUB_RUN_STATUSES: Readonly<Record<string, CiStatusCategory>> = {\n queued: 'queued',\n requested: 'queued',\n pending: 'queued',\n waiting: 'waiting',\n in_progress: 'running',\n};\n\n/** GitHub: conclusion при status completed; не найдено — failed. */\nexport const GITHUB_RUN_CONCLUSIONS: Readonly<Record<string, CiStatusCategory>> = {\n success: 'success',\n neutral: 'success',\n failure: 'failed',\n timed_out: 'failed',\n startup_failure: 'failed',\n cancelled: 'canceled',\n stale: 'canceled',\n skipped: 'skipped',\n action_required: 'waiting',\n};\n\n/** GitHub: event прогона; не найдено — other. */\nexport const GITHUB_RUN_EVENTS: Readonly<Record<string, CiEventCategory>> = {\n push: 'push',\n pull_request: 'pull_request',\n pull_request_target: 'pull_request',\n merge_group: 'pull_request',\n workflow_dispatch: 'manual',\n schedule: 'schedule',\n repository_dispatch: 'trigger',\n workflow_run: 'trigger',\n workflow_call: 'trigger',\n};\n\n/** GitLab: status пайплайна и задания; canceling — ещё не закончено. */\nexport const GITLAB_CI_STATUSES: Readonly<Record<string, CiStatusCategory>> = {\n created: 'queued',\n waiting_for_resource: 'queued',\n preparing: 'queued',\n pending: 'queued',\n running: 'running',\n canceling: 'running',\n waiting_for_callback: 'waiting',\n manual: 'waiting',\n scheduled: 'waiting',\n success: 'success',\n failed: 'failed',\n canceled: 'canceled',\n skipped: 'skipped',\n};\n\n/** GitLab: source пайплайна; не найдено — other. */\nexport const GITLAB_PIPELINE_SOURCES: Readonly<Record<string, CiEventCategory>> = {\n push: 'push',\n merge_request_event: 'pull_request',\n external_pull_request_event: 'pull_request',\n web: 'manual',\n api: 'manual',\n chat: 'manual',\n webide: 'manual',\n schedule: 'schedule',\n pipeline_execution_policy_schedule: 'schedule',\n trigger: 'trigger',\n pipeline: 'trigger',\n parent_pipeline: 'trigger',\n};\n\n/** SourceCraft: status прогона, workflow, задачи и куба. */\nexport const SOURCECRAFT_CI_STATUSES: Readonly<Record<string, CiStatusCategory>> = {\n created: 'queued',\n prepared: 'queued',\n processing: 'running',\n awaiting_approval: 'waiting',\n success: 'success',\n failed: 'failed',\n timeout: 'failed',\n canceled: 'canceled',\n rejected: 'canceled',\n skipped: 'skipped',\n};\n\n/** SourceCraft: event_type прогона. */\nexport const SOURCECRAFT_RUN_EVENTS: Readonly<Record<string, CiEventCategory>> = {\n push: 'push',\n pr_update: 'pull_request',\n manual: 'manual',\n restart: 'retry',\n schedule: 'schedule',\n repository_event: 'trigger',\n};\n","// JSON-запросы к REST внешних трекеров библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/http.lib.ts — дословная копия, redactSecretText — из ядра библиотеки\n// (общий redactor ядра, kernel/redact.lib.ts); отказы not_found, conflict и rate_limited — свои (#14),\n// потоковое чтение текста requestText — своё (#16); origin подключения и свои редиректы — свои (#24).\nimport { redactSecretText } from '../kernel/redact.lib.ts';\nimport { CI_LOG_READ_MAX_BYTES, CI_LOG_TIMEOUT_MS, TRACKER_ERROR_BODY_MAX, TRACKER_REDIRECT_MAX, TRACKER_TIMEOUT_MS } from './tracker.const.ts';\nimport { TrackerError } from './tracker.lib.ts';\nimport type { JsonRequest, JsonResponse, TextRequest, TextResponse } from './tracker.types.ts';\n\n// Запрос к REST внешнего трекера: JSON в обе стороны, таймаут, ошибки без токена (D-352, D-353).\n\nexport async function requestJson(url: string, request: JsonRequest): Promise<JsonResponse> {\n const accept = { accept: 'application/json' };\n const { response, url: final } = await send(url, request, AbortSignal.timeout(TRACKER_TIMEOUT_MS), accept, {\n method: request.method ?? 'GET',\n headers: { ...accept, ...(request.body === undefined ? {} : { 'content-type': 'application/json' }), ...request.headers },\n body: request.body === undefined ? undefined : JSON.stringify(request.body),\n });\n let raw: string;\n try {\n raw = await response.text();\n } catch (error) {\n throw notAnswered(final, error);\n }\n if (!response.ok) throw failureOf(final, response, raw, request);\n if (raw === '') return { body: undefined, headers: response.headers };\n try {\n return { body: JSON.parse(raw) as unknown, headers: response.headers };\n } catch {\n throw new TrackerError('failed', `Трекер ${hostOf(final)} вернул не JSON.`);\n }\n}\n\n/** Шаг запроса: метод, заголовки и тело; на редиректе меняется. */\ntype Hop = { method: string; headers: Record<string, string>; body: string | undefined };\n\n/** Статусы редиректа: за ними идёт send, если есть location. */\nconst REDIRECT_STATUSES: ReadonlySet<number> = new Set([301, 302, 303, 307, 308]);\n\n/**\n * Запрос с origin подключения и своими редиректами. Адрес вне origin (request.origin, нет — origin самого адреса) —\n * invalid_request до сети. fetch получает redirect: 'manual', и за редиректом идёт send, не дальше\n * TRACKER_REDIRECT_MAX переходов. Метод меняется как в fetch: 303 и 301/302 после POST — GET без тела. Переход\n * на чужой origin (и всё после него, даже обратно) — только GET и только с заголовками anonymous: Authorization,\n * токены и свои заголовки туда не уходят; иной метод — отказ failed без запроса. Ответ, за которым fetch пошёл\n * сам (обёртка потеряла redirect), — отказ failed, а не данные. Возвращает ответ и его адрес.\n */\nasync function send(url: string, request: { fetch: JsonRequest['fetch']; origin?: string | undefined }, signal: AbortSignal, anonymous: Record<string, string>, first: Hop): Promise<{ response: Response; url: string }> {\n const home = originOf(request.origin ?? url, 'Origin подключения');\n if (originOf(url, 'Адрес запроса') !== home) throw new TrackerError('invalid_request', `Адрес запроса ${hostOf(url)} вне origin подключения ${hostOf(home)}: запрос не отправлен.`);\n let current = url;\n let hop = first;\n let away = false;\n for (let redirects = 0; ; redirects += 1) {\n let response: Response;\n try {\n response = await request.fetch(current, { method: hop.method, headers: hop.headers, ...(hop.body === undefined ? {} : { body: hop.body }), redirect: 'manual', signal });\n } catch (error) {\n throw notAnswered(current, error);\n }\n const hidden = followedByFetch(response, current);\n if (hidden !== undefined) {\n await response.body?.cancel().catch(() => undefined);\n throw new TrackerError('failed', `Трекер ${hostOf(current)}: ${hidden}; ответ отброшен.`);\n }\n // Пустой location — как его нет: иначе new URL('', current) вернёт тот же адрес и выйдет петля.\n const location = REDIRECT_STATUSES.has(response.status) ? response.headers.get('location') : null;\n if (location === null || location === '') return { response, url: current };\n await response.body?.cancel().catch(() => undefined);\n if (redirects >= TRACKER_REDIRECT_MAX) throw new TrackerError('failed', `Трекер ${hostOf(url)}: больше ${String(TRACKER_REDIRECT_MAX)} редиректов подряд.`);\n const next = redirectTarget(location, current);\n if ((response.status === 303 && hop.method !== 'GET') || ((response.status === 301 || response.status === 302) && hop.method === 'POST')) {\n const { 'content-type': _type, ...headers } = hop.headers;\n hop = { method: 'GET', headers, body: undefined };\n }\n away ||= new URL(next).origin !== home;\n if (away) {\n if (hop.method !== 'GET') throw new TrackerError('failed', `Трекер ${hostOf(current)} перенаправил ${hop.method} на чужой origin ${hostOf(next)}: запрос не отправлен.`);\n hop = { method: 'GET', headers: anonymous, body: undefined };\n }\n current = next;\n }\n}\n\n/**\n * Прошёл ли fetch контекста редирект сам, вопреки redirect: 'manual' (обёртка не передала redirect дальше):\n * redirected, адрес ответа на другом origin или opaqueredirect. Тогда запрос с токеном уже мог уйти на чужой\n * origin, а заголовки на переходе выбирала реализация fetch, а не send. Причина отказа или undefined.\n */\nfunction followedByFetch(response: Response, current: string): string | undefined {\n if (response.type === 'opaqueredirect') return 'fetch контекста скрыл редирект (opaqueredirect), пройти его нельзя';\n let moved = response.redirected;\n if (!moved && response.url !== '') {\n try {\n moved = new URL(response.url).origin !== new URL(current).origin;\n } catch {\n moved = true;\n }\n }\n return moved ? 'fetch контекста сам прошёл редирект — обёртка fetch должна передавать init.redirect дальше' : undefined;\n}\n\n/** Адрес из location относительно текущего; не http и не https — отказ failed. */\nfunction redirectTarget(location: string, current: string): string {\n let next: URL;\n try {\n next = new URL(location, current);\n } catch {\n throw new TrackerError('failed', `Трекер ${hostOf(current)} вернул редирект не на URL.`);\n }\n if (next.protocol !== 'http:' && next.protocol !== 'https:') throw new TrackerError('failed', `Трекер ${hostOf(current)} вернул редирект не на http или https.`);\n return next.href;\n}\n\n/** Origin адреса http или https; иное — invalid_request. */\nfunction originOf(value: string, subject: string): string {\n let parsed: URL;\n try {\n parsed = new URL(value);\n } catch {\n throw new TrackerError('invalid_request', `${subject} — не URL.`);\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') throw new TrackerError('invalid_request', `${subject} должен быть http или https.`);\n return parsed.origin;\n}\n\n/** Сколько байт тела отказа читается для текста ошибки: в него попадает не больше TRACKER_ERROR_BODY_MAX символов. */\nconst ERROR_BODY_READ_MAX = 16 * 1024;\n\n/**\n * Запрос текста (лог CI): тело читается потоком, в памяти — только окно keep после skip. head — первые keep.bytes,\n * поток отменяется, как только окно набрано; tail — последние keep.bytes в кольцевом буфере. Чтение обрывается\n * на readMax байт тела. Границы окна сдвигаются к целым символам UTF-8: начало — вперёд, конец — назад (и у тела,\n * оборванного посреди символа). Отказ — как у requestJson: missing, rate_limited, failed с телом без секретов.\n * Origin и редиректы — как у requestJson: 302 GitHub на подписанный адрес лога уходит GET без Authorization.\n */\nexport async function requestText(url: string, request: TextRequest): Promise<TextResponse> {\n const skip = request.skip ?? 0;\n const { bytes, from } = request.keep;\n const readMax = request.readMax ?? CI_LOG_READ_MAX_BYTES;\n if (![skip, bytes, readMax].every((value) => Number.isSafeInteger(value) && value >= 0)) {\n throw new TrackerError('invalid_request', 'Окно чтения текста — целые числа байт не меньше 0.');\n }\n const accept = { accept: request.accept ?? 'text/plain' };\n const { response, url: final } = await send(url, request, AbortSignal.timeout(request.timeoutMs ?? CI_LOG_TIMEOUT_MS), accept, {\n method: 'GET',\n headers: { ...accept, ...request.headers },\n body: undefined,\n });\n if (!response.ok) {\n const head = await readBody(final, response, { skip: 0, bytes: ERROR_BODY_READ_MAX, from: 'head', readMax: ERROR_BODY_READ_MAX });\n throw failureOf(final, response, decodeUtf8(head.window), request);\n }\n const body = await readBody(final, response, { skip, bytes, from, readMax });\n let start = Math.min(body.start, body.end);\n let end = body.end;\n let window = body.window;\n // Начало посреди символа: окно начинается со следующего целого.\n const lead = start > 0 ? leadingContinuation(window) : 0;\n // Конец посреди символа: незаконченный символ уходит в следующее окно. Тело, дочитанное до конца, тоже\n // бывает оборвано посреди символа (trace идущего задания): иначе вместо символа вышел бы U+FFFD.\n const tail = trailingPartial(window.subarray(lead));\n if (lead > 0 || tail > 0) {\n window = window.subarray(lead, window.length - tail);\n start += lead;\n end -= tail;\n }\n return { text: decodeUtf8(window), start, end, read: body.read, whole: body.whole, headers: response.headers };\n}\n\n/** Окно тела после чтения: байты [start, end) тела, сколько прочитано и дочитано ли до конца. */\ntype BodyWindow = { window: Uint8Array; start: number; end: number; read: number; whole: boolean };\n\n/**\n * Чтение тела потоком с ограниченной памятью: окно bytes после skip с нужной стороны, не дальше readMax байт тела.\n * head отменяет поток, как только увидит байт за окном; дочитанный readMax тоже отменяет поток.\n */\nasync function readBody(url: string, response: Response, window: { skip: number; bytes: number; from: 'head' | 'tail'; readMax: number }): Promise<BodyWindow> {\n const { skip, bytes, from, readMax } = window;\n const reader = response.body?.getReader();\n const kept = from === 'head' ? headBuffer(bytes) : ringBuffer(bytes);\n let read = 0;\n let whole = true;\n if (reader !== undefined) {\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n const chunk = value.subarray(0, Math.max(0, readMax - read));\n // Байт за readMax — тело длиннее потолка; за окном head — дальше читать незачем.\n const cut = chunk.length < value.length;\n const offset = Math.max(0, skip - read);\n if (offset < chunk.length) kept.push(chunk.subarray(offset));\n read += chunk.length;\n if (cut || kept.full()) {\n whole = false;\n await reader.cancel().catch(() => undefined);\n break;\n }\n }\n } catch (error) {\n await reader.cancel().catch(() => undefined);\n throw notAnswered(url, error);\n }\n }\n const data = kept.bytes();\n const start = from === 'head' ? skip : Math.max(skip, read - data.length);\n return { window: data, start, end: from === 'head' ? skip + data.length : read, read, whole };\n}\n\n/** Буфер окна чтения: push принимает байты после skip, full — окно head набрано и за ним есть байт. */\ntype WindowBuffer = { push(chunk: Uint8Array): void; full(): boolean; bytes(): Uint8Array };\n\n/** Первые capacity байт; full, как только пришёл байт сверх окна. */\nfunction headBuffer(capacity: number): WindowBuffer {\n const buffer = new Uint8Array(capacity);\n let length = 0;\n let overflow = false;\n return {\n push(chunk) {\n const room = capacity - length;\n buffer.set(chunk.subarray(0, room), length);\n length += Math.min(room, chunk.length);\n if (chunk.length > room) overflow = true;\n },\n full: () => overflow,\n bytes: () => buffer.subarray(0, length),\n };\n}\n\n/** Кольцевой буфер последних capacity байт: память не растёт с длиной тела. */\nfunction ringBuffer(capacity: number): WindowBuffer {\n const buffer = new Uint8Array(capacity);\n let next = 0;\n let length = 0;\n return {\n push(chunk) {\n if (capacity === 0) return;\n const part = chunk.subarray(Math.max(0, chunk.length - capacity));\n const first = Math.min(part.length, capacity - next);\n buffer.set(part.subarray(0, first), next);\n buffer.set(part.subarray(first), 0);\n next = (next + part.length) % capacity;\n length = Math.min(capacity, length + part.length);\n },\n full: () => false,\n bytes() {\n if (length < capacity) return buffer.subarray(0, length);\n const ordered = new Uint8Array(capacity);\n ordered.set(buffer.subarray(next), 0);\n ordered.set(buffer.subarray(0, next), capacity - next);\n return ordered;\n },\n };\n}\n\n/** Сколько байт продолжения UTF-8 (10xxxxxx) в начале окна: хвост символа, начатого до окна (не больше 3). */\nfunction leadingContinuation(window: Uint8Array): number {\n let count = 0;\n while (count < 3 && count < window.length && ((window[count] ?? 0) & 0xc0) === 0x80) count += 1;\n return count;\n}\n\n/** Сколько байт в конце окна — начало символа UTF-8, который в окно целиком не вошёл. */\nfunction trailingPartial(window: Uint8Array): number {\n for (let back = 1; back <= Math.min(4, window.length); back += 1) {\n const byte = window[window.length - back] ?? 0;\n if ((byte & 0xc0) === 0x80) continue;\n const length = byte >= 0xf0 ? 4 : byte >= 0xe0 ? 3 : byte >= 0xc0 ? 2 : 1;\n return length > back ? back : 0;\n }\n return 0;\n}\n\nfunction decodeUtf8(bytes: Uint8Array): string {\n return new TextDecoder('utf-8').decode(bytes);\n}\n\n/** Сеть, таймаут или обрыв тела: failed без секретов. */\nfunction notAnswered(url: string, error: unknown): TrackerError {\n return new TrackerError('failed', redactSecretText(`Трекер не ответил (${hostOf(url)}): ${error instanceof Error ? error.message : String(error)}`));\n}\n\n/**\n * Отказ по ответу не 2xx, по порядку: 404 с missing или missingIsIssue, статус из conflictOn — conflict,\n * 429, а также 403 с x-ratelimit-remaining: 0 или retry-after — rate_limited (retry-after без исчерпанного\n * лимита — вторичный лимит частоты GitHub), иначе failed. Тело ответа — без секретов и не длиннее потолка.\n */\nfunction failureOf(url: string, response: Response, raw: string, request: Pick<JsonRequest, 'missing' | 'missingIsIssue' | 'conflictOn'>): TrackerError {\n const status = response.status;\n if (status === 404 && request.missing !== undefined) return new TrackerError(request.missing.failure, request.missing.message);\n if (status === 404 && request.missingIsIssue === true) return new TrackerError('unknown_issue', 'Задача не найдена в трекере.');\n const detail = redactSecretText(raw.replace(/\\s+/g, ' ').trim()).slice(0, TRACKER_ERROR_BODY_MAX);\n const answered = `Трекер ${hostOf(url)} ответил ${String(status)}${detail === '' ? '' : `: ${detail}`}.`;\n if (request.conflictOn?.includes(status) === true) return new TrackerError('conflict', answered);\n const secondaryLimit = status === 403 && (response.headers.get('x-ratelimit-remaining')?.trim() === '0' || retryAfterOf(response.headers.get('retry-after')?.trim(), Date.now()) !== undefined);\n if (status === 429 || secondaryLimit) {\n const delay = retryDelayOf(response.headers);\n return new TrackerError('rate_limited', `Трекер ${hostOf(url)} ограничил частоту запросов${delay === undefined ? '' : `, повтор через ${String(delay)} с`}.`);\n }\n return new TrackerError('failed', answered);\n}\n\n/**\n * Через сколько секунд повторить: retry-after (секунды или HTTP-дата), иначе x-ratelimit-reset (GitHub, epoch секунд),\n * иначе ratelimit-reset (GitLab); не разобралось — undefined.\n */\nfunction retryDelayOf(headers: Headers, now: number = Date.now()): number | undefined {\n const retryAfter = retryAfterOf(headers.get('retry-after')?.trim(), now);\n if (retryAfter !== undefined) return retryAfter;\n for (const name of ['x-ratelimit-reset', 'ratelimit-reset']) {\n const reset = headers.get(name)?.trim();\n if (reset !== undefined && /^\\d+$/.test(reset)) return resetDelay(Number(reset), now);\n }\n return undefined;\n}\n\n/** retry-after — число секунд или HTTP-дата; пустой и неразборчивый — undefined. */\nfunction retryAfterOf(value: string | undefined, now: number): number | undefined {\n if (value === undefined || value === '') return undefined;\n if (/^\\d+$/.test(value)) return Number(value);\n const at = Date.parse(value);\n return Number.isFinite(at) ? Math.max(0, Math.ceil((at - now) / 1000)) : undefined;\n}\n\n/** Сброс лимита: epoch секунд (от 1e9, 2001-09-09) — задержка до него от now; меньшее число — уже задержка в секундах. */\nfunction resetDelay(reset: number, now: number): number {\n return reset >= 1_000_000_000 ? Math.max(0, reset - Math.floor(now / 1000)) : reset;\n}\n\n/** Адрес без пути и параметров: в тексте ошибки секретам неоткуда взяться. */\nfunction hostOf(url: string): string {\n try {\n return new URL(url).host;\n } catch {\n return 'трекер';\n }\n}\n\n/** Базовый адрес без хвостовых слэшей; не http и не https — отказ подключения. */\nexport function baseUrl(value: string | undefined, fallback: string): string {\n const raw = (value ?? fallback).replace(/\\/+$/, '');\n let parsed: URL;\n try {\n parsed = new URL(raw);\n } catch {\n throw new TrackerError('invalid_request', 'Адрес трекера — не URL.');\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') throw new TrackerError('invalid_request', 'Адрес трекера должен быть http или https.');\n return raw;\n}\n","// Модель CI трекеров библиотеки @smwb/onreel-git-mcp: workflow, прогоны, задания и окно лога (#16, D-006).\n// Своя: в onreel CI трекеров нет.\nimport { z } from 'zod';\nimport { issueLinkSchema, timestampSchema } from '../contract/contract.schema.ts';\nimport { CI_LOG_MAX_BYTES } from './tracker.const.ts';\n\n/** Категория состояния прогона, задания и шага CI единой модели (D-006); своё имя трекер отдаёт в status.name. */\nexport const ciStatusCategorySchema = z.enum(['queued', 'running', 'waiting', 'success', 'failed', 'canceled', 'skipped']);\n/** Что запустило прогон; своё имя события трекер отдаёт в event.name. */\nexport const ciEventCategorySchema = z.enum(['push', 'pull_request', 'manual', 'schedule', 'retry', 'trigger', 'other']);\nexport const ciRunFilterSchema = z.enum(['status', 'ref', 'sha', 'event', 'workflow', 'actor', 'pullRequest', 'createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore']);\nexport const ciRunSortFieldSchema = z.enum(['created', 'updated']);\nexport const ciJobFilterSchema = z.enum(['status', 'allAttempts']);\n\nexport const ciStatusSchema = z.object({ category: ciStatusCategorySchema, name: z.string().min(1).max(100) });\n\nexport const ciWorkflowSchema = z.object({\n /** Ключ workflow: GitHub — id строкой; подходит в trigger.workflows и фильтр workflow. */\n key: z.string().min(1).max(200),\n name: z.string().min(1).max(500),\n path: z.string().min(1).max(1000).optional(),\n enabled: z.boolean(),\n});\n\nexport const ciRunSchema = z.object({\n /** Ключ прогона: GitHub run id, GitLab pipeline id, SourceCraft slug-счётчик; непрозрачная строка. */\n key: z.string().min(1).max(200),\n /** Номер для людей: GitHub run_number, GitLab iid, SourceCraft — счётчик. */\n number: z.number().int().nonnegative().optional(),\n /** Workflow прогона: GitHub — один, SourceCraft — все в прогоне, GitLab — имя пайплайна, если задано. */\n workflows: z.array(z.string().min(1).max(500)).max(100),\n status: ciStatusSchema,\n event: z.object({ category: ciEventCategorySchema, name: z.string().min(1).max(100) }).optional(),\n /** Ветка или тег прогона. */\n ref: z.string().min(1).max(500).optional(),\n sha: z\n .string()\n .regex(/^[0-9a-f]{7,64}$/)\n .optional(),\n /** Кто запустил — логин или slug трекера. */\n actor: z.string().min(1).max(200).optional(),\n /** Ключ PR того же трекера, для которого прогон. */\n pullRequest: z.string().min(1).max(200).optional(),\n /** Попытка прогона (GitHub run_attempt). */\n attempt: z.number().int().positive().optional(),\n /** Ошибки прогона от трекера (SourceCraft error_messages). */\n errors: z.array(z.string().min(1).max(4000)).max(20).optional(),\n links: z.array(issueLinkSchema).max(10),\n createdAt: timestampSchema.optional(),\n startedAt: timestampSchema.optional(),\n finishedAt: timestampSchema.optional(),\n updatedAt: timestampSchema.optional(),\n});\n\nexport const ciJobSchema = z.object({\n /** Ключ задания: GitHub и GitLab — job id, SourceCraft — `<run>/<workflow>/<task>/<cube>`, части через encodeURIComponent. */\n key: z.string().min(1).max(1000),\n runKey: z.string().min(1).max(200),\n name: z.string().min(1).max(500),\n /** Группа: GitLab — stage, SourceCraft — `<workflow>/<task>`; у GitHub нет. */\n stage: z.string().min(1).max(1000).optional(),\n status: ciStatusSchema,\n /** Шаги GitHub: где упало; у остальных нет. */\n steps: z\n .array(z.object({ number: z.number().int().nonnegative(), name: z.string().min(1).max(500), status: ciStatusSchema }))\n .max(1000)\n .optional(),\n attempt: z.number().int().positive().optional(),\n links: z.array(issueLinkSchema).max(10),\n createdAt: timestampSchema.optional(),\n startedAt: timestampSchema.optional(),\n finishedAt: timestampSchema.optional(),\n});\n\nexport const ciLogSchema = z.object({\n /** Окно лога: очищено от ANSI (если не raw), секреты замаскированы. */\n text: z.string().max(CI_LOG_MAX_BYTES),\n /** Окно не покрывает весь лог от курсора: срезано спереди (tail), сзади (head) или упёрлись в потолок чтения. */\n truncated: z.boolean(),\n /** Задание закончилось — лог больше не растёт. */\n complete: z.boolean(),\n /** Курсор дочитывания: передайте в log() — придёт текст после этого места. Нет — дальше ничего не будет. */\n nextCursor: z.string().min(1).max(200).optional(),\n /** Размер лога в байтах, если тело прочитано целиком. */\n size: z.number().int().nonnegative().optional(),\n});\n\nexport type CiStatusCategory = z.infer<typeof ciStatusCategorySchema>;\nexport type CiEventCategory = z.infer<typeof ciEventCategorySchema>;\nexport type CiRunFilter = z.infer<typeof ciRunFilterSchema>;\nexport type CiRunSortField = z.infer<typeof ciRunSortFieldSchema>;\nexport type CiJobFilter = z.infer<typeof ciJobFilterSchema>;\nexport type CiStatus = z.infer<typeof ciStatusSchema>;\nexport type CiWorkflow = z.infer<typeof ciWorkflowSchema>;\nexport type CiRun = z.infer<typeof ciRunSchema>;\nexport type CiJob = z.infer<typeof ciJobSchema>;\nexport type CiLog = z.infer<typeof ciLogSchema>;\n","// Общие помощники CI трекеров библиотеки @smwb/onreel-git-mcp: адаптер по определению, окно и курсор лога,\n// очистка текста лога (#16, D-005, D-006). Свои: в onreel CI трекеров нет.\nimport { REDACTED, redactSecretText } from '../kernel/redact.lib.ts';\nimport type { CiLog, CiStatusCategory } from './ci.schema.ts';\nimport type { CiAdapter, CiLogQuery, CiLogWindow } from './ci.types.ts';\nimport { CI_FINISHED_STATUSES, CI_LOG_DEFAULT_BYTES, CI_LOG_MAX_BYTES } from './tracker.const.ts';\nimport { clipText, TrackerError } from './tracker.lib.ts';\nimport type { AdapterContext, TrackerDefinition } from './tracker.types.ts';\n\n/** Адаптер CI трекера (D-005); трекер без раздела ci — TrackerError('unsupported', 'Трекер <title> не ведёт CI.'). */\nexport function ciAdapterOf(definition: TrackerDefinition, context: AdapterContext): CiAdapter {\n if (definition.ci === undefined) throw new TrackerError('unsupported', `Трекер ${definition.descriptor.title} не ведёт CI.`);\n return definition.ci.create(context);\n}\n\n/** Курсор лога: страница и байт в ней — целые без знака в пределах безопасных чисел. */\nconst LOG_CURSOR = /^c:(\\d{1,15}):(\\d{1,15})$/;\n\n/**\n * Окно лога из запроса (D-006): maxBytes 1..CI_LOG_MAX_BYTES (по умолчанию CI_LOG_DEFAULT_BYTES), from по умолчанию tail,\n * курсор `c:<страница>:<байт>` — в resume; иначе TrackerError('invalid_request').\n */\nexport function logWindow(query: CiLogQuery): CiLogWindow {\n const bytes = query.maxBytes ?? CI_LOG_DEFAULT_BYTES;\n if (!Number.isInteger(bytes) || bytes < 1 || bytes > CI_LOG_MAX_BYTES) {\n throw new TrackerError('invalid_request', `Окно лога maxBytes — целое от 1 до ${String(CI_LOG_MAX_BYTES)}.`);\n }\n const from = query.from ?? 'tail';\n if (from !== 'head' && from !== 'tail') throw new TrackerError('invalid_request', 'Начало окна лога from — head или tail.');\n if (query.cursor === undefined) return { bytes, from };\n const match = LOG_CURSOR.exec(query.cursor);\n if (match === null) {\n throw new TrackerError('invalid_request', 'Курсор лога неверен: передайте nextCursor прошлого ответа log() или не передавайте cursor.');\n }\n // С курсором окно читается вперёд от его места: from не читается.\n return { bytes, from: 'head', resume: { page: Number(match[1]), offset: Number(match[2]) } };\n}\n\n/** Курсор дочитывания с места (страница, байт в ней): `c:<page>:<offset>`. */\nexport function logCursor(page: number, offset: number): string {\n return `c:${String(page)}:${String(offset)}`;\n}\n\n/**\n * Лог единой модели из прочитанного окна: окно выравнивается по целым строкам (lineWindow), затем cleanLogText\n * (если не raw), хвост приватного ключа из прошлого окна и redactSecretText — всегда. nextCursor = logCursor(page, end)\n * со сдвигом end назад на отложенный конец окна, если задание не закончилось или окно head оборвалось раньше конца\n * тела; иначе курсора нет. Окно, которое не сдвинулось (пусто при more: потолок чтения, символ шире окна), у законченного\n * задания курсора не даёт — тот же курсор зациклил бы дочитывание. startCut — начало окна отрезано (хвост лога): первая\n * неполная строка отбрасывается; по умолчанию truncated && !more — окно усечено, а дальше читать нечего.\n * end — байт за окном на странице page; на эту страницу приходятся не больше end последних байт окна.\n */\nexport function logOf(input: {\n text: string;\n truncated: boolean;\n complete: boolean;\n page: number;\n end: number;\n more: boolean;\n size?: number | undefined;\n raw: boolean;\n startCut?: boolean | undefined;\n}): CiLog {\n const stalled = input.text === '' && input.more;\n const follow = !input.complete || (input.more && !stalled);\n const window = lineWindow(input.text, { start: input.startCut ?? (input.truncated && !input.more), end: follow, endBytes: input.end });\n const clean = maskKeyTail(input.raw ? window.text : cleanLogText(window.text));\n // Маскирование может удлинить текст на несколько символов: окно не выходит за потолок схемы.\n const text = clipText(redactSecretText(clean), CI_LOG_MAX_BYTES);\n return {\n text,\n truncated: input.truncated,\n complete: input.complete,\n ...(follow ? { nextCursor: logCursor(input.page, input.end - window.held) } : {}),\n ...(input.size === undefined ? {} : { size: input.size }),\n };\n}\n\n// Секрет, разрезанный краем окна, не узнаётся ни в одном из окон, а склеенные окна отдают его целиком (D-006).\n// Поэтому окно с курсором кончается после последнего \\n (курсор — на начале следующей строки), окно с отрезанным\n// началом начинается после первого \\n, а приватный ключ не начинается в окне, которое его не закончит. Строка\n// длиннее окна режется по словам: конец — перед последним словом вместе с ключом присваивания перед ним, начало —\n// после первого пробела; без пробелов — по байту, тогда откладываются незаконченная ANSI-последовательность и \\r.\n\nconst KEY_BEGIN = /-----BEGIN [A-Z ]*PRIVATE KEY-----/g;\nconst KEY_END = /-----END [A-Z ]*PRIVATE KEY-----/;\n/** Целая ANSI-последовательность с начала строки: как ANSI_SEQUENCE, но OSC — только с терминатором, а `ESC [` и `ESC ]` — не целые. */\n// oxlint-disable-next-line no-control-regex -- ESC и BEL — сами искомые управляющие символы.\nconst WHOLE_ANSI_SEQUENCE = /^(?:\\x1b\\[[0-?]*[ -/]*[@-~]|\\x1b\\][^\\x07\\x1b]*(?:\\x07|\\x1b\\\\)|\\x1b[ -/]*(?![[\\]])[0-~])/;\n/** Ключ перед значением в конце текста: `token: `, `PASSWORD=`, `Bearer ` — значение без ключа не узнать. */\nconst VALUE_KEY = /(?:[A-Za-z][\\w.-]{0,63}[\"']?\\s*[=:]|\\b(?:Bearer|Basic|Token))\\s*[\"']?$/i;\n/** Сколько символов перед последним словом ищется ключ: имя ключа короче 64 символов. */\nconst VALUE_KEY_LOOKBACK = 80;\n\n/**\n * Окно по целым строкам: start — отбросить начало до первого \\n включительно, end — отложить конец после последнего\n * \\n (и строку BEGIN незаконченного в окне приватного ключа). held — сколько байт конца отложено; не больше endBytes:\n * у SourceCraft окно собрано из нескольких страниц, курсор не уходит на прошлую — окно кончается на её границе.\n */\nfunction lineWindow(text: string, cut: { start: boolean; end: boolean; endBytes: number }): { text: string; held: number } {\n let to = text.length;\n if (cut.end) {\n const line = text.lastIndexOf('\\n');\n to = keyStart(text, line >= 0 ? line + 1 : wordCut(text, byteCut(text)));\n }\n let held = to === text.length ? 0 : utf8Length(text.slice(to));\n if (held > cut.endBytes) {\n to = suffixStart(text, cut.endBytes);\n held = cut.endBytes;\n }\n let from = 0;\n if (cut.start) {\n const line = text.indexOf('\\n');\n from = Math.min(line >= 0 ? line + 1 : firstWordEnd(text), to);\n }\n return { text: text.slice(from, to), held };\n}\n\n/** Конец окна без \\n: перед незаконченной ANSI-последовательностью и \\r; окно не становится пустым. */\nfunction byteCut(text: string): number {\n let to = text.length;\n const escape = text.lastIndexOf('\\x1b');\n if (escape > 0 && !WHOLE_ANSI_SEQUENCE.test(text.slice(escape))) to = escape;\n if (to > 1 && text[to - 1] === '\\r') to -= 1;\n return to;\n}\n\n/** Конец окна перед последним словом text[0, to) и ключом перед ним; без пробела — to. Окно не становится пустым. */\nfunction wordCut(text: string, to: number): number {\n let space = to - 1;\n while (space >= 0 && !/\\s/.test(text.charAt(space))) space -= 1;\n if (space < 0) return to;\n const word = space + 1;\n const before = text.slice(Math.max(0, word - VALUE_KEY_LOOKBACK), word);\n const key = VALUE_KEY.exec(before);\n const keyed = key === null ? word : word - before.length + key.index;\n return keyed > 0 ? keyed : word;\n}\n\n/** Начало окна без \\n: после первого пробела (обрывок слова отбрасывается); без пробелов — 0. */\nfunction firstWordEnd(text: string): number {\n const space = /\\s+/.exec(text);\n return space === null ? 0 : space.index + space[0].length;\n}\n\n/** Конец окна перед строкой BEGIN приватного ключа, у которого в text[0, to) нет END; ключ с начала окна не трогается. */\nfunction keyStart(text: string, to: number): number {\n const head = text.slice(0, to);\n const begin = [...head.matchAll(KEY_BEGIN)].at(-1);\n if (begin === undefined || KEY_END.test(head.slice(begin.index))) return to;\n const line = head.lastIndexOf('\\n', begin.index) + 1;\n return line > 0 ? line : begin.index > 0 ? begin.index : to;\n}\n\n/**\n * Окно начинается внутри приватного ключа: всё до END без BEGIN перед ним маскируется; ключ длиннее окна — ведущие\n * строки его тела (base64 в обоих регистрах и с цифрами), даже без END в окне.\n */\nfunction maskKeyTail(text: string): string {\n const end = KEY_END.exec(text);\n if (end !== null && [...text.slice(0, end.index).matchAll(KEY_BEGIN)].length === 0) return REDACTED + text.slice(end.index + end[0].length);\n let at = 0;\n for (;;) {\n const next = text.indexOf('\\n', at);\n if (!isKeyBodyLine(text.slice(at, next < 0 ? text.length : next))) break;\n at = next < 0 ? text.length : next + 1;\n if (next < 0) break;\n }\n if (at === 0) return text;\n return REDACTED + (text[at - 1] === '\\n' ? text.slice(at - 1) : '');\n}\n\n/** Строка тела PEM: 16..76 символов base64 с паддингом, есть заглавные, строчные и цифры (не hex-дайджест и не слово). */\nfunction isKeyBodyLine(line: string): boolean {\n const body = line.endsWith('\\r') ? line.slice(0, -1) : line;\n return /^[A-Za-z0-9+/]{16,76}={0,2}$/.test(body) && /[A-Z]/.test(body) && /[a-z]/.test(body) && /\\d/.test(body);\n}\n\nconst utf8 = new TextEncoder();\n\nfunction utf8Length(text: string): number {\n return utf8.encode(text).length;\n}\n\n/** Индекс в text, с которого последние bytes байт UTF-8; граница — между целыми символами. */\nfunction suffixStart(text: string, bytes: number): number {\n let index = text.length;\n let count = 0;\n while (index > 0 && count < bytes) {\n const low = text.charCodeAt(index - 1);\n const pair = index > 1 && low >= 0xdc00 && low <= 0xdfff && text.charCodeAt(index - 2) >= 0xd800 && text.charCodeAt(index - 2) <= 0xdbff;\n count += utf8Length(text.slice(index - (pair ? 2 : 1), index));\n index -= pair ? 2 : 1;\n }\n return index;\n}\n\n// ANSI: CSI (`ESC [ … финальный`), OSC (`ESC ] … BEL | ESC \\`) и прочие ESC-последовательности\n// (`ESC ( B` — набор символов, `ESC =` — режим клавиатуры).\n// oxlint-disable-next-line no-control-regex -- ESC и BEL — сами искомые управляющие символы.\nconst ANSI_SEQUENCE = /\\x1b\\[[0-?]*[ -/]*[@-~]|\\x1b\\][^\\x07\\x1b]*(?:\\x07|\\x1b\\\\|$)|\\x1b[ -/]*[0-~]/g;\n/** Маркеры свёртки GitLab: `section_start:<epoch>:<имя>[опции]\\r` и `section_end:<epoch>:<имя>\\r` (ESC[0K уже снят). */\nconst GITLAB_SECTION_MARKER = /section_(?:start|end):\\d+:[A-Za-z0-9_.-]+(?:\\[[^\\]\\r\\n]*\\])?\\r?/g;\n\n/** Текст лога без ANSI-последовательностей (CSI, OSC), перерисовок строки через \\r и маркеров section_start/section_end GitLab. */\nexport function cleanLogText(text: string): string {\n const plain = text.replace(ANSI_SEQUENCE, '').replace(GITLAB_SECTION_MARKER, '').replace(/\\r+\\n/g, '\\n');\n if (!plain.includes('\\r')) return plain;\n // Перерисовка строки (прогресс): видна последняя непустая версия строки после \\r.\n return plain\n .split('\\n')\n .map((line) => (line.includes('\\r') ? (line.split('\\r').findLast((part) => part !== '') ?? '') : line))\n .join('\\n');\n}\n\n/** Категория законченного состояния: success, failed, canceled, skipped. */\nexport function isFinished(category: CiStatusCategory): boolean {\n return CI_FINISHED_STATUSES.includes(category);\n}\n","// Адаптер CI GitHub библиотеки @smwb/onreel-git-mcp: workflow, прогоны и задания Actions репозитория через\n// REST API на том же подключении, что и задачи (#16, D-005, D-006). Свой: в onreel CI трекеров нет.\nimport { isFinished, logCursor, logOf, logWindow } from './ci.lib.ts';\nimport { ciJobFilterSchema, ciRunFilterSchema } from './ci.schema.ts';\nimport type { CiEventCategory, CiJob, CiRun, CiStatus, CiStatusCategory, CiWorkflow } from './ci.schema.ts';\nimport type { CiAdapter, CiCapabilities, CiDefinition, CiRunQuery } from './ci.types.ts';\nimport { baseUrl, requestJson, requestText } from './http.lib.ts';\nimport { GITHUB_RUN_CONCLUSIONS, GITHUB_RUN_EVENTS, GITHUB_RUN_STATUSES } from './mapping.const.ts';\nimport { TrackerError, assertListQuery, inTimeRange, isRecord, isoTime, keysFor, lookup, requireTarget, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext } from './tracker.types.ts';\n\n// CI GitHub (D-005, D-006): Actions репозитория `owner/repo`. Статус, событие и границы updated проверяются по\n// полученной странице: upstream фильтрует грубее единой модели (у категории pull_request три сырых имени,\n// времени изменения прогона параметром нет). Лог задания появляется только после его конца, дальше читается\n// окном с курсором по байту тела. Запуск — workflow_dispatch ровно одного workflow с не больше чем 25 inputs.\n\nconst DEFAULT_API = 'https://api.github.com';\nconst TARGET = /^[\\w.-]+\\/[\\w.-]+$/;\nconst ID = /^[1-9]\\d{0,19}$/;\nconst SHA = /^[0-9a-f]{7,64}$/;\n/** Потолок inputs workflow_dispatch: больше 25 параметров GitHub не принимает. */\nconst DISPATCH_INPUTS_MAX = 25;\n\n/** Фильтры списков CI — значения схемы; порядок — для текстов отказов. */\nconst RUN_FILTERS = ciRunFilterSchema.options;\nconst JOB_FILTERS = ciJobFilterSchema.options;\n\nconst RUNS_SUBJECT = 'Прогоны CI GitHub';\nconst JOBS_SUBJECT = 'Задания CI GitHub';\nconst WORKFLOWS_SUBJECT = 'Список workflow GitHub';\nconst TRIGGER_SUBJECT = 'Запуск CI GitHub';\n\n/** Возможности CI GitHub (§3.6): список workflow есть, сортировки прогонов нет, лог — только законченного задания. */\nconst CAPABILITIES: CiCapabilities = {\n workflows: true,\n runs: { filters: RUN_FILTERS, clientSide: ['status', 'event', 'updatedAfter', 'updatedBefore'], sorts: [] },\n jobs: { filters: JOB_FILTERS, clientSide: ['status'], sorts: [] },\n log: { live: false, cursor: true },\n trigger: { supported: true, workflows: 'one', inputs: true, tags: true },\n rerun: { all: true, failedOnly: true, job: true, debug: true },\n cancel: { run: true, job: false },\n};\n\nexport function githubCi(): CiDefinition {\n return { capabilities: CAPABILITIES, create: (context) => createGithubCiAdapter(context) };\n}\n\nfunction createGithubCiAdapter({ connection, fetch }: AdapterContext): CiAdapter {\n const target = requireTarget(connection.target, 'owner/repo репозитория GitHub');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target GitHub — owner/repo.');\n const api = baseUrl(connection.url, DEFAULT_API);\n const origin = new URL(api).origin;\n const root = `${api}/repos/${target}`;\n const actions = `${root}/actions`;\n const headers = {\n accept: 'application/vnd.github+json',\n 'x-github-api-version': '2022-11-28',\n ...(connection.token === undefined || connection.token === '' ? {} : { authorization: `Bearer ${connection.token}` }),\n };\n const runKey = (key: string): string => {\n if (!ID.test(key)) throw new TrackerError('not_found', `В GitHub нет прогона ${key}.`);\n return key;\n };\n const jobKey = (key: string): string => {\n if (!ID.test(key)) throw new TrackerError('not_found', `В GitHub нет задания ${key}.`);\n return key;\n };\n const missingRun = (key: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В GitHub нет прогона ${key}.` });\n const missingJob = (key: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В GitHub нет задания ${key}.` });\n const getRun = async (key: string): Promise<CiRun> => runOf((await requestJson(`${actions}/runs/${runKey(key)}`, { fetch, origin, headers, missing: missingRun(key) })).body);\n /**\n * Голова прогона для фильтра: pullRequest читает PR и отдаёт его head_sha — у GitHub прогоны PR иначе\n * как по голове не выбрать. sha и pullRequest вместе задавать нельзя (§3.7 C2).\n */\n const headShaOf = async (query: CiRunQuery): Promise<string | undefined> => {\n if (query.pullRequest === undefined) return query.sha;\n if (query.sha !== undefined) throw new TrackerError('invalid_request', `${RUNS_SUBJECT}: sha и pullRequest задаются по отдельности — прогоны PR берутся по его голове.`);\n const pull = query.pullRequest;\n if (!ID.test(pull)) throw new TrackerError('not_found', `В GitHub нет pull request ${pull}.`);\n const { body } = await requestJson(`${root}/pulls/${pull}`, { fetch, origin, headers, missing: { failure: 'not_found', message: `В GitHub нет pull request ${pull}.` } });\n const head = isRecord(body) && isRecord(body.head) ? text(body.head.sha) : undefined;\n if (head === undefined) throw new TrackerError('failed', 'GitHub не вернул голову pull request.');\n return head;\n };\n return {\n listWorkflows: async (query) => {\n assertListQuery(WORKFLOWS_SUBJECT, { filters: [], clientSide: [], sorts: [] }, query, []);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({ per_page: String(query.limit), page: String(page) });\n const { body, headers: responseHeaders } = await requestJson(`${actions}/workflows?${params.toString()}`, { fetch, origin, headers });\n return { items: rowsOf(body, 'workflows').map(workflowOf), ...nextCursorOf(page, responseHeaders.get('link') ?? '') };\n },\n listRuns: async (query) => {\n assertListQuery(RUNS_SUBJECT, CAPABILITIES.runs, query, RUN_FILTERS);\n const page = pageOf(query.cursor);\n const sha = await headShaOf(query);\n const params = new URLSearchParams({ per_page: String(query.limit), page: String(page) });\n if (query.ref !== undefined) params.set('branch', query.ref);\n if (sha !== undefined) params.set('head_sha', sha);\n if (query.actor !== undefined) params.set('actor', query.actor);\n const status = statusParam(query.status);\n if (status !== undefined) params.set('status', status);\n const event = eventParam(query.event);\n if (event !== undefined) params.set('event', event);\n const created = createdParam(query);\n if (created !== undefined) params.set('created', created);\n // Прогоны одного workflow — свой путь; id и имя файла GitHub принимает одинаково (§3.7 C2).\n const path = query.workflow === undefined ? `${actions}/runs` : `${actions}/workflows/${encodeURIComponent(query.workflow)}/runs`;\n const { body, headers: responseHeaders } = await requestJson(`${path}?${params.toString()}`, { fetch, origin, headers });\n const items = rowsOf(body, 'workflow_runs')\n .map(runOf)\n .filter((run) =>\n (query.status === undefined || query.status.includes(run.status.category)) &&\n (query.event === undefined || (run.event !== undefined && query.event.includes(run.event.category))) &&\n inTimeRange(run.updatedAt, query.updatedAfter, query.updatedBefore),\n );\n return { items, ...nextCursorOf(page, responseHeaders.get('link') ?? '') };\n },\n getRun: getRun,\n listJobs: async (key, query) => {\n const run = runKey(key);\n // allAttempts — переключатель формы списка, а не фильтр значения: проверка запроса идёт без него.\n const { allAttempts, ...rest } = query;\n assertListQuery(JOBS_SUBJECT, CAPABILITIES.jobs, rest, JOB_FILTERS);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({ per_page: String(query.limit), page: String(page), filter: allAttempts === true ? 'all' : 'latest' });\n const { body, headers: responseHeaders } = await requestJson(`${actions}/runs/${run}/jobs?${params.toString()}`, { fetch, origin, headers, missing: missingRun(run) });\n const items = rowsOf(body, 'jobs')\n .map(jobOf)\n .filter((job) => query.status === undefined || query.status.includes(job.status.category));\n return { items, ...nextCursorOf(page, responseHeaders.get('link') ?? '') };\n },\n getJob: async (key) => {\n const id = jobKey(key);\n return jobOf((await requestJson(`${actions}/jobs/${id}`, { fetch, origin, headers, missing: missingJob(id) })).body);\n },\n log: async (key, query) => {\n const id = jobKey(key);\n const window = logWindow(query);\n const job = (await requestJson(`${actions}/jobs/${id}`, { fetch, origin, headers, missing: missingJob(id) })).body;\n const complete = isFinished(statusOf(isRecord(job) ? job : {}).category);\n // Лог у GitHub появляется только после конца задания: идущее — пустой результат без скачивания (§3.5).\n if (!complete) return { text: '', truncated: false, complete: false, nextCursor: logCursor(0, 0) };\n // Логи отдаёт подписанный адрес за 302 на чужом origin: requestText идёт туда GET без Authorization и своих заголовков.\n const response = await requestText(`${actions}/jobs/${id}/logs`, {\n fetch,\n origin,\n headers,\n skip: window.resume?.offset ?? 0,\n keep: { bytes: window.bytes, from: window.from },\n missing: missingJob(id),\n });\n return logOf({\n text: response.text,\n truncated: window.from === 'tail' ? response.start > 0 : !response.whole,\n complete,\n page: 0,\n end: response.end,\n // Курсор дальше имеет смысл только когда окно head оборвалось раньше конца тела: tail уже читает конец.\n more: window.from === 'head' && !response.whole,\n ...(response.whole ? { size: response.read } : {}),\n raw: query.raw ?? false,\n });\n },\n trigger: async (input) => {\n const workflows = input.workflows ?? [];\n const workflow = workflows[0];\n if (workflows.length !== 1 || workflow === undefined) {\n throw new TrackerError('invalid_request', `${TRIGGER_SUBJECT}: нужен ровно один workflow — id или имя файла.`);\n }\n const inputs = input.inputs ?? {};\n const count = Object.keys(inputs).length;\n if (count > DISPATCH_INPUTS_MAX) throw new TrackerError('invalid_request', `${TRIGGER_SUBJECT}: workflow_dispatch принимает не больше ${String(DISPATCH_INPUTS_MAX)} параметров.`);\n const { body } = await requestJson(`${actions}/workflows/${encodeURIComponent(workflow)}/dispatches`, {\n fetch,\n origin,\n headers,\n method: 'POST',\n body: { ref: input.ref, ...(count === 0 ? {} : { inputs }), return_run_details: true },\n });\n // return_run_details даёт id созданного прогона; без него трекер принял запуск и ничего не сказал (§3.5).\n const run = runIdOf(isRecord(body) ? body.workflow_run_id : undefined);\n return run === undefined ? {} : { run: await getRun(run) };\n },\n rerun: async (key, input) => {\n const run = runKey(key);\n // Только упавшие задания — отдельный адрес; флаг отладки GitHub читает и при полном перезапуске.\n await requestJson(`${actions}/runs/${run}/${input.failedOnly === true ? 'rerun-failed-jobs' : 'rerun'}`, {\n fetch,\n origin,\n headers,\n method: 'POST',\n body: { enable_debug_logging: input.debug === true },\n missing: missingRun(run),\n });\n return getRun(run);\n },\n rerunJob: async (key, input) => {\n const id = jobKey(key);\n const job = (await requestJson(`${actions}/jobs/${id}`, { fetch, origin, headers, missing: missingJob(id) })).body;\n const run = runIdOf(isRecord(job) ? job.run_id : undefined);\n if (run === undefined) throw new TrackerError('failed', 'GitHub не вернул прогон задания.');\n await requestJson(`${actions}/jobs/${id}/rerun`, { fetch, origin, headers, method: 'POST', body: { enable_debug_logging: input.debug === true }, missing: missingJob(id) });\n // Задание уходит в тот же прогон: состояние прогона и есть ответ (§3.7 C2).\n return getRun(run);\n },\n cancel: async (key) => {\n const run = runKey(key);\n await requestJson(`${actions}/runs/${run}/cancel`, { fetch, origin, headers, method: 'POST', conflictOn: [409], missing: missingRun(run) });\n return getRun(run);\n },\n cancelJob: async () => {\n throw new TrackerError('unsupported', 'Отмена CI GitHub: задания по отдельности не отменяются, отменяется прогон.');\n },\n };\n}\n\n/** Номер страницы из курсора: курсор GitHub — простой номер страницы, первый — 1. */\nfunction pageOf(cursor: string | undefined): number {\n const page = cursor === undefined ? 1 : Number(cursor);\n return Number.isInteger(page) && page >= 1 ? page : 1;\n}\n\n/** Курсор следующей страницы по заголовку Link: rel=\"next\" — страница номером на один больше. */\nfunction nextCursorOf(page: number, link: string): { nextCursor?: string } {\n return /rel=\"next\"/.test(link) ? { nextCursor: String(page + 1) } : {};\n}\n\n/** Элементы списка: GitHub кладёт их в поле ответа рядом с total_count. */\nfunction rowsOf(body: unknown, field: string): readonly unknown[] {\n const rows = isRecord(body) ? body[field] : undefined;\n return Array.isArray(rows) ? rows : [];\n}\n\n/** Ключ сущности в непрозрачную строку единой модели: id числом или строкой; не разобралось — «?». */\nfunction keyOf(value: unknown): string {\n if (typeof value === 'number' && Number.isSafeInteger(value)) return String(value);\n return typeof value === 'string' && value !== '' ? value : '?';\n}\n\n/** Целое положительное число (номер прогона, попытка): не число или не положительное — undefined. */\nfunction positiveInt(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isSafeInteger(value) && value > 0 ? value : undefined;\n}\n\n/** id прогона в сырых полях (run_id задания, workflow_run_id ответа dispatch): ключ прогона для getRun. */\nfunction runIdOf(value: unknown): string | undefined {\n const id = positiveInt(value);\n return id === undefined ? undefined : String(id);\n}\n\n/**\n * Статус прогона, задания и шага GitHub: заключение читается только когда status completed, незнакомое законченное —\n * failed, незнакомый не законченный — running (§3.6).\n */\nfunction statusOf(item: Record<string, unknown>): CiStatus {\n const raw = text(item.status) ?? 'unknown';\n if (raw !== 'completed') return { category: lookup(GITHUB_RUN_STATUSES, raw, 'running'), name: raw };\n const conclusion = text(item.conclusion);\n return { category: lookup(GITHUB_RUN_CONCLUSIONS, conclusion, 'failed'), name: conclusion ?? raw };\n}\n\n/** Параметр status: completed — когда запрошены только законченные категории, in_progress — только одиночный running. */\nfunction statusParam(status: readonly CiStatusCategory[] | undefined): string | undefined {\n if (status === undefined || status.length === 0) return undefined;\n if (status.every(isFinished)) return 'completed';\n return status.length === 1 && status[0] === 'running' ? 'in_progress' : undefined;\n}\n\n/** Параметр event: одна запрошенная категория с единственным сырым именем (push, manual, schedule). */\nfunction eventParam(event: readonly CiEventCategory[] | undefined): string | undefined {\n if (event === undefined || event.length !== 1) return undefined;\n const raws = keysFor(GITHUB_RUN_EVENTS, event);\n return raws.length === 1 ? raws[0] : undefined;\n}\n\n/** Параметр created: >=A, <=B или диапазон A..B (ISO). Границ updated у GitHub параметра нет — проверка по странице. */\nfunction createdParam(query: CiRunQuery): string | undefined {\n const { createdAfter: after, createdBefore: before } = query;\n if (after !== undefined && before !== undefined) return `${isoTime(after)}..${isoTime(before)}`;\n if (after !== undefined) return `>=${isoTime(after)}`;\n return before !== undefined ? `<=${isoTime(before)}` : undefined;\n}\n\n/** Workflow Actions: включён только активный — inactive и disabled для единой модели выключены. */\nfunction workflowOf(raw: unknown): CiWorkflow {\n const item = isRecord(raw) ? raw : {};\n const key = keyOf(item.id);\n const path = text(item.path);\n return { key, name: text(item.name) ?? key, ...(path === undefined ? {} : { path }), enabled: item.state === 'active' };\n}\n\n/** Прогон Actions → прогон единой модели: время конца — последнее обновление завершённого (§3.7 C2). */\nfunction runOf(raw: unknown): CiRun {\n const item = isRecord(raw) ? raw : {};\n const key = keyOf(item.id);\n const status = statusOf(item);\n const name = text(item.name) ?? text(item.path);\n const branch = text(item.head_branch);\n const sha = text(item.head_sha);\n const actor = isRecord(item.actor) ? text(item.actor.login) : undefined;\n const pull = Array.isArray(item.pull_requests) ? item.pull_requests[0] : undefined;\n const pullNumber = isRecord(pull) && typeof pull.number === 'number' ? String(pull.number) : undefined;\n const number = positiveInt(item.run_number);\n const attempt = positiveInt(item.run_attempt);\n const url = text(item.html_url);\n const createdAt = toTimestamp(item.created_at);\n const startedAt = toTimestamp(item.run_started_at);\n const updatedAt = toTimestamp(item.updated_at);\n const finishedAt = text(item.status) === 'completed' ? updatedAt : undefined;\n const event = text(item.event);\n return {\n key,\n ...(number === undefined ? {} : { number }),\n workflows: name === undefined ? [] : [name],\n status,\n ...(event === undefined ? {} : { event: { category: lookup(GITHUB_RUN_EVENTS, event, 'other'), name: event } }),\n ...(branch === undefined ? {} : { ref: branch }),\n ...(sha === undefined || !SHA.test(sha) ? {} : { sha }),\n ...(actor === undefined ? {} : { actor }),\n ...(pullNumber === undefined ? {} : { pullRequest: pullNumber }),\n ...(attempt === undefined ? {} : { attempt }),\n links: url === undefined ? [] : [{ url, title: 'GitHub Actions' }],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(startedAt === undefined ? {} : { startedAt }),\n ...(finishedAt === undefined ? {} : { finishedAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n };\n}\n\n/** Задание Actions → задание единой модели: прогон берётся из run_id, шаги читаются теми же таблицами. */\nfunction jobOf(raw: unknown): CiJob {\n const item = isRecord(raw) ? raw : {};\n const key = keyOf(item.id);\n const url = text(item.html_url);\n const startedAt = toTimestamp(item.started_at);\n const finishedAt = toTimestamp(item.completed_at);\n const steps = Array.isArray(item.steps) ? item.steps.map(stepOf) : undefined;\n return {\n key,\n runKey: runIdOf(item.run_id) ?? '?',\n name: text(item.name) ?? key,\n status: statusOf(item),\n ...(steps === undefined ? {} : { steps }),\n links: url === undefined ? [] : [{ url, title: 'GitHub Actions' }],\n ...(startedAt === undefined ? {} : { startedAt }),\n ...(finishedAt === undefined ? {} : { finishedAt }),\n };\n}\n\n/** Шаг задания: по его статусу видно, на чём упало задание; времени шага в единой модели нет. */\nfunction stepOf(raw: unknown): { number: number; name: string; status: CiStatus } {\n const item = isRecord(raw) ? raw : {};\n const number = positiveInt(item.number) ?? 0;\n return { number, name: text(item.name) ?? String(number), status: statusOf(item) };\n}\n","// Адаптер CI GitLab библиотеки @smwb/onreel-git-mcp: пайплайны и задания проекта через REST API v4, токен —\n// PRIVATE-TOKEN (#16, D-006). Свой: в onreel CI трекеров нет.\nimport { isFinished, logOf, logWindow } from './ci.lib.ts';\nimport { ciJobFilterSchema, ciRunFilterSchema } from './ci.schema.ts';\nimport type { CiJob, CiRun } from './ci.schema.ts';\nimport type { CiAdapter, CiCapabilities, CiDefinition, CiJobRerunInput, CiRerunInput, CiTriggerInput } from './ci.types.ts';\nimport { baseUrl, requestJson, requestText } from './http.lib.ts';\nimport { GITLAB_CI_STATUSES, GITLAB_PIPELINE_SOURCES } from './mapping.const.ts';\nimport { TrackerError, assertListQuery, inTimeRange, isRecord, isoTime, keysFor, lookup, requireTarget, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext } from './tracker.types.ts';\n\n// CI GitLab (D-006): пайплайны и задания проекта. Workflow у GitLab нет — запуск идёт сразу на ref с\n// переменными. Лог задания (trace) отдаётся, пока задание идёт, и дочитывается по курсору. Статус и событие\n// всегда сверяются со страницей: upstream грубее единой модели (created, preparing и pending — одно).\n\nconst DEFAULT_URL = 'https://gitlab.com';\nconst TARGET = /^(\\d{1,15}|[\\w.-]+(\\/[\\w.-]+)+)$/;\nconst ID = /^[1-9]\\d{0,19}$/;\n\n/** Фильтры списков CI — значения схемы; порядок — для текстов отказов. */\nconst RUN_FILTERS = ciRunFilterSchema.options;\nconst JOB_FILTERS = ciJobFilterSchema.options;\n\n/** Возможности CI GitLab (#16): все фильтры прогонов, сортировка по созданию и обновлению; лог живой, с курсором. */\nconst CAPABILITIES: CiCapabilities = {\n workflows: false,\n runs: { filters: RUN_FILTERS, clientSide: ['status', 'event'], sorts: ['created', 'updated'] },\n jobs: { filters: JOB_FILTERS, clientSide: [], sorts: [] },\n log: { live: true, cursor: true },\n trigger: { supported: true, workflows: 'none', inputs: true, tags: true },\n rerun: { all: false, failedOnly: true, job: true, debug: false },\n cancel: { run: true, job: true },\n};\n\nexport function gitlabCi(): CiDefinition {\n return { capabilities: CAPABILITIES, create: (context) => createGitlabCiAdapter(context) };\n}\n\nfunction createGitlabCiAdapter({ connection, fetch }: AdapterContext): CiAdapter {\n const target = requireTarget(connection.target, 'путь проекта GitLab, group/project, или его id');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target GitLab — group/project или числовой id.');\n const site = baseUrl(connection.url, DEFAULT_URL);\n const origin = new URL(site).origin;\n const api = `${site}/api/v4`;\n const project = `${api}/projects/${encodeURIComponent(target)}`;\n const headers: Record<string, string> = connection.token === undefined || connection.token === '' ? {} : { 'private-token': connection.token };\n // Сырое значение параметра одиночной категории: у категории ровно одно сырое значение — оно, больше —\n // только проверка по странице (upstream грубее единой модели: created, preparing и pending — одно).\n const rawOf = <T extends string>(table: Readonly<Record<string, T>>, categories: readonly T[] | undefined): string | undefined => {\n if (categories === undefined || categories.length !== 1) return undefined;\n const raws = keysFor(table, categories);\n return raws.length === 1 ? raws[0] : undefined;\n };\n const pipelineKey = (key: string): string => {\n if (!ID.test(key)) throw new TrackerError('not_found', `В GitLab нет прогона ${key}.`);\n return key;\n };\n const jobKey = (key: string): string => {\n if (!ID.test(key)) throw new TrackerError('not_found', `В GitLab нет задания ${key}.`);\n return key;\n };\n const missingPipeline = (key: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В GitLab нет прогона ${key}.` });\n const missingJob = (key: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В GitLab нет задания ${key}.` });\n const getPipeline = async (key: string): Promise<CiRun> =>\n runOf((await requestJson(`${project}/pipelines/${pipelineKey(key)}`, { fetch, origin, headers, missing: missingPipeline(key) })).body);\n return {\n listWorkflows: async () => {\n throw new TrackerError('unsupported', 'Прогоны CI GitLab: списка workflow у GitLab нет.');\n },\n listRuns: async (query) => {\n assertListQuery('Прогоны CI GitLab', CAPABILITIES.runs, query, RUN_FILTERS);\n const params = new URLSearchParams({ per_page: String(query.limit), page: String(pageOf(query.cursor)) });\n let body: unknown;\n let responseHeaders: Headers;\n let keep: (run: CiRun) => boolean;\n if (query.pullRequest !== undefined) {\n // Прогоны MR: upstream отдаёт только страницы без фильтров — остальное проверяется по странице;\n // сортировка и фильтры по полям, которых у элементов списка нет, отклоняются до запроса.\n const mr = query.pullRequest;\n if (!ID.test(mr)) throw new TrackerError('not_found', `В GitLab нет merge request ${mr}.`);\n if (query.sort !== undefined) throw new TrackerError('unsupported', 'Прогоны CI GitLab для merge request: сортировка не поддерживается.');\n if (query.actor !== undefined) throw new TrackerError('unsupported', 'Прогоны CI GitLab для merge request: фильтр actor не поддерживается.');\n if (query.workflow !== undefined) throw new TrackerError('unsupported', 'Прогоны CI GitLab для merge request: фильтр workflow не поддерживается.');\n const result = await requestJson(`${project}/merge_requests/${mr}/pipelines?${params.toString()}`, { fetch, origin, headers, missing: { failure: 'not_found', message: `В GitLab нет merge request ${mr}.` } });\n body = result.body;\n responseHeaders = result.headers;\n keep = (run) =>\n (query.status === undefined || query.status.includes(run.status.category)) &&\n (query.event === undefined || (run.event !== undefined && query.event.includes(run.event.category))) &&\n (query.ref === undefined || run.ref === query.ref) &&\n (query.sha === undefined || run.sha === query.sha) &&\n inTimeRange(run.createdAt, query.createdAfter, query.createdBefore) &&\n inTimeRange(run.updatedAt, query.updatedAfter, query.updatedBefore);\n } else {\n if (query.ref !== undefined) params.set('ref', query.ref);\n if (query.sha !== undefined) params.set('sha', query.sha);\n if (query.actor !== undefined) params.set('username', query.actor);\n if (query.workflow !== undefined) params.set('name', query.workflow);\n if (query.status !== undefined && query.status.length > 0) {\n const status = rawOf(GITLAB_CI_STATUSES, query.status);\n if (status !== undefined) params.set('status', status);\n if (status === undefined && query.status.every(isFinished)) params.set('scope', 'finished');\n }\n const source = rawOf(GITLAB_PIPELINE_SOURCES, query.event);\n if (source !== undefined) params.set('source', source);\n if (query.createdAfter !== undefined) params.set('created_after', isoTime(query.createdAfter));\n if (query.createdBefore !== undefined) params.set('created_before', isoTime(query.createdBefore));\n if (query.updatedAfter !== undefined) params.set('updated_after', isoTime(query.updatedAfter));\n if (query.updatedBefore !== undefined) params.set('updated_before', isoTime(query.updatedBefore));\n params.set('order_by', query.sort?.field === 'updated' ? 'updated_at' : 'id');\n params.set('sort', query.sort?.direction ?? 'desc');\n const result = await requestJson(`${project}/pipelines?${params.toString()}`, { fetch, origin, headers });\n body = result.body;\n responseHeaders = result.headers;\n keep = (run) =>\n (query.status === undefined || query.status.includes(run.status.category)) &&\n (query.event === undefined || (run.event !== undefined && query.event.includes(run.event.category)));\n }\n const items = (Array.isArray(body) ? body : []).map(runOf).filter(keep);\n const next = responseHeaders.get('x-next-page');\n return { items, ...(next === null || next === '' ? {} : { nextCursor: next }) };\n },\n getRun: getPipeline,\n listJobs: async (runKey, query) => {\n // allAttempts — переключатель формы списка, а не фильтр значения: проверка запроса идёт без него.\n const { allAttempts, ...rest } = query;\n assertListQuery('Задания CI GitLab', CAPABILITIES.jobs, rest, JOB_FILTERS);\n const params = new URLSearchParams({ per_page: String(query.limit), page: String(pageOf(query.cursor)), include_retried: String(allAttempts ?? false) });\n for (const scope of keysFor(GITLAB_CI_STATUSES, query.status ?? [])) params.append('scope[]', scope);\n const { body, headers: responseHeaders } = await requestJson(`${project}/pipelines/${pipelineKey(runKey)}/jobs?${params.toString()}`, { fetch, origin, headers, missing: missingPipeline(runKey) });\n const items = (Array.isArray(body) ? body : []).map(jobOf);\n const next = responseHeaders.get('x-next-page');\n return { items, ...(next === null || next === '' ? {} : { nextCursor: next }) };\n },\n getJob: async (key) => jobOf((await requestJson(`${project}/jobs/${jobKey(key)}`, { fetch, origin, headers, missing: missingJob(key) })).body),\n log: async (key, query) => {\n const window = logWindow(query);\n const job = (await requestJson(`${project}/jobs/${jobKey(key)}`, { fetch, origin, headers, missing: missingJob(key) })).body;\n const rawStatus = isRecord(job) && typeof job.status === 'string' ? job.status : 'unknown';\n const complete = isFinished(lookup(GITLAB_CI_STATUSES, rawStatus, 'running'));\n // Trace читается целиком с пропуском прочитанного: курсор GitLab — всегда страница 0 и байт в теле.\n const response = await requestText(`${project}/jobs/${jobKey(key)}/trace`, { fetch, origin, headers, skip: window.resume?.offset ?? 0, keep: { bytes: window.bytes, from: window.from }, missing: missingJob(key) });\n return logOf({\n text: response.text,\n truncated: window.from === 'tail' ? response.start > 0 : !response.whole,\n complete,\n page: 0,\n end: response.end,\n more: !response.whole,\n ...(response.whole ? { size: response.read } : {}),\n // Кольцевой буфер отрезал начало хвоста и при потолке чтения (whole=false): там default\n // startCut (truncated && !more) молчит, а первая неполная строка в окне остаётся.\n startCut: window.from === 'tail' && response.start > 0,\n raw: query.raw ?? false,\n });\n },\n trigger: async (input: CiTriggerInput) => {\n if (input.workflows !== undefined && input.workflows.length > 0) {\n throw new TrackerError('unsupported', 'Запуск CI GitLab: workflow не задаётся — только ref и переменные.');\n }\n const variables = Object.entries(input.inputs ?? {}).map(([key, value]) => ({ key, value, variable_type: 'env_var' }));\n const { body } = await requestJson(`${project}/pipeline`, {\n fetch,\n origin,\n headers,\n method: 'POST',\n body: { ref: input.ref, ...(variables.length === 0 ? {} : { variables }) },\n missing: { failure: 'not_found', message: `В GitLab нет ветки или тега ${input.ref}.` },\n });\n return { run: runOf(body) };\n },\n rerun: async (runKey, input: CiRerunInput) => {\n if (input.failedOnly !== true) throw new TrackerError('unsupported', 'Перезапуск CI GitLab умеет только упавшие задания: задайте failedOnly.');\n if (input.debug === true) throw new TrackerError('unsupported', 'Перезапуск CI GitLab не поддерживает отладочное логирование.');\n return runOf((await requestJson(`${project}/pipelines/${pipelineKey(runKey)}/retry`, { fetch, origin, headers, method: 'POST', missing: missingPipeline(runKey) })).body);\n },\n rerunJob: async (jobKeyValue, input: CiJobRerunInput) => {\n if (input.debug === true) throw new TrackerError('unsupported', 'Перезапуск задания GitLab не поддерживает отладочное логирование.');\n const body = (await requestJson(`${project}/jobs/${jobKey(jobKeyValue)}/retry`, { fetch, origin, headers, method: 'POST', missing: missingJob(jobKeyValue) })).body;\n const pipeline = isRecord(body) && isRecord(body.pipeline) && typeof body.pipeline.id === 'number' ? String(body.pipeline.id) : undefined;\n if (pipeline === undefined) throw new TrackerError('failed', 'GitLab не вернул пайплайн нового задания.');\n return getPipeline(pipeline);\n },\n cancel: async (runKey) =>\n runOf((await requestJson(`${project}/pipelines/${pipelineKey(runKey)}/cancel`, { fetch, origin, headers, method: 'POST', missing: missingPipeline(runKey) })).body),\n cancelJob: async (jobKeyValue) => jobOf((await requestJson(`${project}/jobs/${jobKey(jobKeyValue)}/cancel`, { fetch, origin, headers, method: 'POST', missing: missingJob(jobKeyValue) })).body),\n };\n}\n\nfunction pageOf(cursor: string | undefined): number {\n const page = cursor === undefined ? 1 : Number(cursor);\n return Number.isInteger(page) && page >= 1 ? page : 1;\n}\n\n/** Пайплайн GitLab → прогон единой модели; ref вида refs/merge-requests/<iid>/head читается как PR. */\nfunction runOf(raw: unknown): CiRun {\n const item = isRecord(raw) ? raw : {};\n const key = typeof item.id === 'number' ? String(item.id) : '?';\n const rawStatus = typeof item.status === 'string' ? item.status : 'unknown';\n const rawSource = text(item.source);\n const mr = typeof item.ref === 'string' ? /^refs\\/merge-requests\\/(\\d+)\\/head$/.exec(item.ref) : null;\n const user = isRecord(item.user) ? text(item.user.username) : undefined;\n const url = text(item.web_url);\n const name = text(item.name);\n const createdAt = toTimestamp(item.created_at);\n const startedAt = toTimestamp(item.started_at);\n const finishedAt = toTimestamp(item.finished_at);\n const updatedAt = toTimestamp(item.updated_at);\n return {\n key,\n ...(typeof item.iid === 'number' ? { number: item.iid } : {}),\n workflows: name === undefined ? [] : [name],\n status: { category: lookup(GITLAB_CI_STATUSES, rawStatus, 'running'), name: rawStatus },\n ...(rawSource === undefined ? {} : { event: { category: lookup(GITLAB_PIPELINE_SOURCES, rawSource, 'other'), name: rawSource } }),\n ...(typeof item.ref === 'string' && item.ref !== '' ? { ref: item.ref } : {}),\n ...(typeof item.sha === 'string' && /^[0-9a-f]{7,64}$/.test(item.sha) ? { sha: item.sha } : {}),\n ...(user === undefined ? {} : { actor: user }),\n ...(mr === null ? {} : { pullRequest: mr[1] }),\n links: url === undefined ? [] : [{ url, title: 'GitLab' }],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(startedAt === undefined ? {} : { startedAt }),\n ...(finishedAt === undefined ? {} : { finishedAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n };\n}\n\n/** Задание GitLab → задание единой модели; runKey берётся из пайплайна задания. */\nfunction jobOf(raw: unknown): CiJob {\n const item = isRecord(raw) ? raw : {};\n const key = typeof item.id === 'number' ? String(item.id) : '?';\n const rawStatus = typeof item.status === 'string' ? item.status : 'unknown';\n const pipeline = isRecord(item.pipeline) && typeof item.pipeline.id === 'number' ? String(item.pipeline.id) : '?';\n const url = text(item.web_url);\n const stage = text(item.stage);\n const startedAt = toTimestamp(item.started_at);\n const finishedAt = toTimestamp(item.finished_at);\n return {\n key,\n runKey: pipeline,\n name: text(item.name) ?? key,\n ...(stage === undefined ? {} : { stage }),\n status: { category: lookup(GITLAB_CI_STATUSES, rawStatus, 'running'), name: rawStatus },\n links: url === undefined ? [] : [{ url, title: 'GitLab' }],\n ...(startedAt === undefined ? {} : { startedAt }),\n ...(finishedAt === undefined ? {} : { finishedAt }),\n };\n}\n","// Адаптер CI SourceCraft библиотеки @smwb/onreel-git-mcp: прогоны, задания и логи репозитория через REST API,\n// токен — Bearer (#16, D-006). Свой: в onreel CI трекеров нет.\nimport { logOf, logWindow } from './ci.lib.ts';\nimport { ciJobFilterSchema, ciRunFilterSchema } from './ci.schema.ts';\nimport type { CiJob, CiJobFilter, CiRun } from './ci.schema.ts';\nimport type { CiAdapter, CiCapabilities, CiDefinition, CiRunQuery, CiTriggerInput } from './ci.types.ts';\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { SOURCECRAFT_CI_STATUSES, SOURCECRAFT_RUN_EVENTS } from './mapping.const.ts';\nimport { CI_LOG_PAGES_MAX, CI_LOG_READ_MAX_BYTES, CI_LOG_TIMEOUT_MS } from './tracker.const.ts';\nimport { TrackerError, assertListQuery, inTimeRange, isRecord, lookup, requireTarget, stringList, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext } from './tracker.types.ts';\n\n// CI SourceCraft (D-006): прогоны репозитория. Список отдаёт только page_size и page_token, поэтому каждый\n// фильтр проверяется по полученной странице (§3.6). Заданием считается куб задачи workflow: отдельного списка\n// заданий у площадки нет, страница строится поверх дерева прогона, а ключ задания — путь\n// `<run>/<workflow>/<task>/<cube>`, где каждой части соответствует encodeURIComponent. Логи приходят\n// страницами JSON, а не голым текстом, поэтому окно лога собирается по байтам UTF-8 здесь, а не в requestText.\n// Лог служебного куба (`#git-clone`, …) через API не читается — отказ unsupported без запроса. Фильтр\n// pullRequest идёт через id PR: у прогона pull.id живой, а pull.slug пустой. Перезапуска и отмены в публичном\n// API нет (§1.3), и эти методы отказывают до всякого запроса (§3.6).\n\nconst DEFAULT_API = 'https://api.sourcecraft.tech';\nconst TARGET = /^[\\w.-]+\\/[\\w.-]+$/;\n\n/** Ключ прогона — счётчик запуска (`slug`); иного вида у прогона быть не может. */\nconst RUN_SLUG = /^\\d{1,20}$/;\n\n/** Ключ PR — slug репозитория, как в адаптере задач (§3.7). */\nconst PR_SLUG = /^[\\w-]{1,100}$/;\n\n/** Ключ задания: четыре части через `/`. Слаги кодируются, поэтому `/` внутри слаги разбору не мешает. */\nconst JOB_KEY = /^([^/]+)\\/([^/]+)\\/([^/]+)\\/([^/]+)$/;\n\n/** Значение user.slug пользователя вне площадки: его в единой модели не показывают. */\nconst EXTERNAL_USER = '<external-user>';\n\n/** Фильтр списка заданий — смещение в плоском списке кубов прогона. */\nconst JOB_OFFSET_CURSOR = /^o:(\\d{1,15})$/;\n\n/** Имена фильтров схемы — вселенная отказа; у прогонов действующие — без ref и sha: их в модели прогона нет (§1.3). */\nconst RUN_FILTER_NAMES = ciRunFilterSchema.options;\nconst RUN_FILTERS = RUN_FILTER_NAMES.filter((name) => name !== 'ref' && name !== 'sha');\nconst JOB_FILTER_NAMES = ciJobFilterSchema.options;\nconst JOB_FILTERS: readonly CiJobFilter[] = ['status'];\n\n/** Возможности CI SourceCraft (#16): все фильтры по странице, лог живой с дочитыванием, ни перезапуска, ни отмены. */\nconst CAPABILITIES: CiCapabilities = {\n workflows: false,\n runs: { filters: RUN_FILTERS, clientSide: RUN_FILTERS, sorts: [] },\n jobs: { filters: JOB_FILTERS, clientSide: JOB_FILTERS, sorts: [] },\n log: { live: true, cursor: true },\n trigger: { supported: true, workflows: 'many', inputs: true, tags: true },\n rerun: { all: false, failedOnly: false, job: false, debug: false },\n cancel: { run: false, job: false },\n};\n\nexport function sourcecraftCi(): CiDefinition {\n return { capabilities: CAPABILITIES, create: (context) => createSourceCraftCiAdapter(context) };\n}\n\n/** Части ключа задания: прогон, workflow, задача и куб. */\ntype JobPath = { run: string; workflow: string; task: string; cube: string };\n\nfunction createSourceCraftCiAdapter({ connection, fetch }: AdapterContext): CiAdapter {\n const target = requireTarget(connection.target, 'org/repo репозитория SourceCraft');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target SourceCraft — org/repo.');\n const api = baseUrl(connection.url, DEFAULT_API);\n const origin = new URL(api).origin;\n const repo = `${api}/repos/${target}`;\n const root = `${repo}/cicd`;\n const headers = { authorization: `Bearer ${connection.token ?? ''}` };\n const missingRun = (key: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В SourceCraft нет прогона ${key}.` });\n const missingJob = (key: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В SourceCraft нет задания ${key}.` });\n const missingWorkflow = (run: string, workflow: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В прогоне ${run} SourceCraft нет workflow ${workflow}.` });\n const runKey = (key: string): string => {\n if (!RUN_SLUG.test(key)) throw new TrackerError('not_found', `В SourceCraft нет прогона ${key}.`);\n return key;\n };\n const jobPath = (key: string): JobPath => {\n const match = JOB_KEY.exec(key);\n if (match === null) throw new TrackerError('not_found', `В SourceCraft нет задания ${key}.`);\n const path: JobPath = { run: partOf(match[1], key), workflow: partOf(match[2], key), task: partOf(match[3], key), cube: partOf(match[4], key) };\n runKey(path.run);\n return path;\n };\n const getRun = async (key: string): Promise<CiRun> => runOf((await requestJson(`${root}/runs/${runKey(key)}`, { fetch, origin, headers, missing: missingRun(key) })).body);\n /** Дерево workflow прогона: задачи с кубами. Слаги кодируются — среди них есть `#git-clone`. */\n const getWorkflow = async (run: string, workflow: string): Promise<Record<string, unknown>> => {\n const { body } = await requestJson(`${root}/runs/${runKey(run)}/${encodeURIComponent(workflow)}`, { fetch, origin, headers, missing: missingWorkflow(run, workflow) });\n return isRecord(body) ? body : {};\n };\n /**\n * id PR по его ключу: фильтр pullRequest страницы идёт через run.pull.id, потому что у живого API у прогона\n * pull.id есть, а pull.slug пустой (M4, §3.7 C4). Чужой ключ — not_found, ответ без id — failed.\n */\n const pullIdOf = async (slug: string): Promise<string> => {\n if (!PR_SLUG.test(slug)) throw new TrackerError('invalid_request', `Ключ pull request SourceCraft — slug из букв, цифр, _ и - длиной до 100.`);\n const { body } = await requestJson(`${repo}/pulls/${slug}`, { fetch, origin, headers, missing: { failure: 'not_found', message: `В SourceCraft нет pull request ${slug}.` } });\n const id = isRecord(body) ? text(body.id) : undefined;\n if (id === undefined) throw new TrackerError('failed', `Ответ SourceCraft на /pulls/${slug} не содержит id.`);\n return id;\n };\n /** Плоский список заданий прогона: кубы задач каждого workflow, в порядке прогона (§3.7 C4). */\n const flattenJobs = async (run: string): Promise<CiJob[]> => {\n const jobs: CiJob[] = [];\n for (const workflow of (await getRun(run)).workflows) {\n const tree = await getWorkflow(run, workflow);\n for (const task of recordList(tree.tasks)) {\n const taskSlug = text(task.slug);\n if (taskSlug === undefined) continue;\n for (const cube of recordList(task.cubes)) {\n const cubeSlug = text(cube.slug);\n if (cubeSlug === undefined) continue;\n jobs.push(jobOf(run, workflow, taskSlug, cubeSlug, cube));\n }\n }\n }\n return jobs;\n };\n return {\n listWorkflows: async () => {\n throw new TrackerError('unsupported', 'Прогоны CI SourceCraft: отдельного списка workflow нет, workflow есть у прогона.');\n },\n listRuns: async (query) => {\n assertListQuery('Прогоны CI SourceCraft', CAPABILITIES.runs, query, RUN_FILTER_NAMES);\n const pullId = query.pullRequest === undefined ? undefined : await pullIdOf(query.pullRequest);\n const params = new URLSearchParams({ page_size: String(query.limit) });\n if (query.cursor !== undefined) params.set('page_token', query.cursor);\n const { body } = await requestJson(`${root}/runs?${params.toString()}`, { fetch, origin, headers });\n const record = isRecord(body) ? body : {};\n const items = recordList(record.runs)\n .map((raw) => pullSlugOf(runOf(raw), raw, pullId, query.pullRequest))\n .filter((run) => keepsRun(run, query));\n const token = text(record.next_page_token);\n return { items, ...(token === undefined ? {} : { nextCursor: token }) };\n },\n getRun,\n listJobs: async (runKeyValue, query) => {\n assertListQuery('Задания CI SourceCraft', CAPABILITIES.jobs, query, JOB_FILTER_NAMES);\n const jobs = await flattenJobs(runKey(runKeyValue));\n const from = offsetOf(query.cursor);\n const next = from + query.limit;\n const page = jobs.slice(from, next);\n const items = query.status === undefined ? page : page.filter((job) => query.status?.includes(job.status.category) === true);\n return { items, ...(next < jobs.length ? { nextCursor: `o:${String(next)}` } : {}) };\n },\n getJob: async (key) => {\n const path = jobPath(key);\n const tree = await getWorkflow(path.run, path.workflow);\n for (const task of recordList(tree.tasks)) {\n if (text(task.slug) !== path.task) continue;\n const cube = recordList(task.cubes).find((item) => text(item.slug) === path.cube);\n if (cube !== undefined) return jobOf(path.run, path.workflow, path.task, path.cube, cube);\n }\n throw new TrackerError('not_found', `В SourceCraft нет задания ${key}.`);\n },\n log: async (key, query) => {\n const parsed = jobPath(key);\n // Служебные кубы (`#git-clone`, …) в API логов не читаются: площадка отвечает 400 ValidationError (m2).\n if (parsed.cube.startsWith('#')) {\n throw new TrackerError('unsupported', `Лог задания SourceCraft ${key}: служебный куб, лог через API недоступен.`);\n }\n const window = logWindow(query);\n const path = pathOf(parsed);\n const tail = window.resume === undefined && window.from === 'tail';\n const first = window.resume?.page ?? 1;\n const deadline = Date.now() + CI_LOG_TIMEOUT_MS;\n let page = first;\n let skip = window.resume?.offset ?? 0;\n let kept: Uint8Array<ArrayBufferLike> = new Uint8Array(0);\n let dropped = 0;\n let seen = 0;\n let lastPage = first;\n let lastEnd = 0;\n let done = false;\n let unread = false;\n const encoder = new TextEncoder();\n const decoder = new TextDecoder('utf-8');\n for (;;) {\n // Начало и курсор останавливаются на набранном окне; хвост обязан дочитать страницы до конца, иначе\n // потеряется его конец — там обычно и лежит причина падения.\n if (!tail && kept.length >= window.bytes) {\n unread = true;\n break;\n }\n const { body } = await requestJson(`${root}/logs/${path}?page=${String(page)}`, { fetch, origin, headers, missing: missingJob(key) });\n const record = isRecord(body) ? body : {};\n const data = encoder.encode(text(record.logs) ?? '');\n const rest = skip >= data.length ? new Uint8Array(0) : data.subarray(skip);\n // Хвост режется общим кольцевым буфером ниже: отрезанное начало учитывается в dropped, иначе truncated\n // соврал бы на первой же странице длиннее окна. Начало и курсор останавливаются на набранном bytes.\n let slice = rest;\n if (!tail) {\n const room = rest.subarray(0, Math.min(window.bytes - kept.length, rest.length));\n slice = room.subarray(0, room.length - trailingByte(room));\n }\n const merged = concat(kept, slice);\n if (merged.length > window.bytes) {\n const fitted = merged.subarray(merged.length - window.bytes);\n dropped += merged.length - fitted.length;\n kept = fitted;\n } else {\n kept = merged;\n }\n seen += data.length;\n // Курсор указывает на место сразу за выданным окном: у хвоста это конец прочитанной страницы, у начала\n // и курсора — байт последнего целого символа.\n lastPage = page;\n lastEnd = tail ? data.length : skip + slice.length;\n skip = 0;\n done = record.done === true;\n // Начало и курсор взяли страницу не целиком (край окна упёрся в символ UTF-8 или потолок окна): за\n // курсором остаётся текст, а начало следующей страницы дало бы разрыв в окне — останавливаемся, дочиты-\n // вание идёт с курсора этого места (M1, D-006).\n if (!tail && rest.length > slice.length) {\n unread = true;\n break;\n }\n // Страницу ещё дописывают: запрос следующих страниц площадка отдаёт 404, дальше не читаем (§1.3).\n if (done || record.page_complete === false) break;\n // Пределы чтения (m4, D-006): не больше CI_LOG_PAGES_MAX страниц, CI_LOG_READ_MAX_BYTES байт на лог\n // и CI_LOG_TIMEOUT_MS на вызов; дальше — truncated с курсором, дочитывание следующим вызовом.\n if (page - first + 1 >= CI_LOG_PAGES_MAX || seen >= CI_LOG_READ_MAX_BYTES || Date.now() >= deadline) {\n unread = true;\n break;\n }\n page += 1;\n }\n return logOf({\n text: decoder.decode(kept.subarray(leadingByte(kept))),\n truncated: dropped > 0 || unread,\n complete: done,\n page: lastPage,\n end: lastEnd,\n more: unread,\n // Размер всего лога известен, только если с первой страницы прочитали их все.\n size: window.resume === undefined && !unread ? seen : undefined,\n // Страниц было прочитано больше окна: начало хвоста отрезано кольцевым буфером, и первая неполная\n // строка уходит из окна даже когда за ним ещё есть страницы (default startCut там молчит).\n startCut: tail && dropped > 0,\n raw: query.raw ?? false,\n });\n },\n trigger: async (input: CiTriggerInput) => {\n const workflows = input.workflows ?? [];\n if (workflows.length === 0) throw new TrackerError('invalid_request', 'Запуск CI SourceCraft: нужен хотя бы один workflow.');\n const values = Object.entries(input.inputs ?? {}).map(([name, value]) => ({ name, value }));\n const head = input.refType === 'tag' ? { tag: input.ref } : { branch: input.ref };\n const { body } = await requestJson(`${root}/runs`, { fetch, origin, headers, method: 'POST', body: { head, workflows: workflows.map((name) => ({ name, values })) } });\n return { run: runOf(body) };\n },\n // Публичный API SourceCraft не умеет ни перезапускать, ни отменять (§1.3): отказ без запроса (§3.6).\n rerun: async () => {\n throw new TrackerError('unsupported', 'Перезапуск прогона CI SourceCraft недоступен: у площадки нет такого запроса в API.');\n },\n rerunJob: async () => {\n throw new TrackerError('unsupported', 'Перезапуск задания CI SourceCraft недоступен: у площадки нет такого запроса в API.');\n },\n cancel: async () => {\n throw new TrackerError('unsupported', 'Отмена прогона CI SourceCraft недоступна: у площадки нет такого запроса в API.');\n },\n cancelJob: async () => {\n throw new TrackerError('unsupported', 'Отмена задания CI SourceCraft недоступна: у площадки нет такого запроса в API.');\n },\n };\n}\n\n/** Часть ключа задания: проценты раскрыты; пустая часть или битая процентовка — «нет задания», как и любой чужой ключ. */\nfunction partOf(value: string | undefined, key: string): string {\n const refusal = new TrackerError('not_found', `В SourceCraft нет задания ${key}.`);\n if (value === undefined) throw refusal;\n let decoded: string;\n try {\n decoded = decodeURIComponent(value);\n } catch {\n throw refusal;\n }\n if (decoded === '') throw refusal;\n return decoded;\n}\n\n/** Путь задания в адресе логов: каждая часть через encodeURIComponent, как и в ключе. */\nfunction pathOf(path: JobPath): string {\n return [path.run, path.workflow, path.task, path.cube].map(encodeURIComponent).join('/');\n}\n\n/** Массив записей из поля ответа: не-записи отбрасываются, порядок сохраняется. */\nfunction recordList(value: unknown): Record<string, unknown>[] {\n return Array.isArray(value) ? value.filter(isRecord) : [];\n}\n\n/** Смещение плоского списка заданий; чужой курсор — начало списка. */\nfunction offsetOf(cursor: string | undefined): number {\n if (cursor === undefined) return 0;\n const match = JOB_OFFSET_CURSOR.exec(cursor);\n if (match === null) return 0;\n const from = Number(match[1]);\n return Number.isSafeInteger(from) && from >= 0 ? from : 0;\n}\n\n/** Прогон SourceCraft → CiRun единой модели: ref и sha у прогона нет, ссылку даёт потребитель (Q9). */\nfunction runOf(raw: unknown): CiRun {\n const item = isRecord(raw) ? raw : {};\n const key = text(item.slug) ?? '?';\n const rawStatus = text(item.status) ?? 'unknown';\n const rawEvent = text(item.event_type);\n const user = isRecord(item.user) ? text(item.user.slug) : undefined;\n const pull = isRecord(item.pull) ? text(item.pull.slug) : undefined;\n const dates = isRecord(item.dates) ? item.dates : {};\n const createdAt = toTimestamp(dates.created_at);\n const startedAt = toTimestamp(dates.started_at);\n const finishedAt = toTimestamp(dates.finished_at);\n const updatedAt = toTimestamp(dates.updated_at);\n const errors = stringList(item.error_messages);\n return {\n key,\n ...(RUN_SLUG.test(key) ? { number: Number(key) } : {}),\n workflows: stringList(recordList(item.workflows).map((workflow) => workflow.slug)),\n status: { category: lookup(SOURCECRAFT_CI_STATUSES, rawStatus, 'running'), name: rawStatus },\n ...(rawEvent === undefined ? {} : { event: { category: lookup(SOURCECRAFT_RUN_EVENTS, rawEvent, 'other'), name: rawEvent } }),\n ...(user === undefined || user === EXTERNAL_USER ? {} : { actor: user }),\n ...(pull === undefined ? {} : { pullRequest: pull }),\n ...(errors.length === 0 ? {} : { errors }),\n links: [],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(startedAt === undefined ? {} : { startedAt }),\n ...(finishedAt === undefined ? {} : { finishedAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n };\n}\n\n/** Куб задачи workflow → CiJob: ключ — путь прогона, stage — `<workflow>/<task>` (§3.7 C4). */\nfunction jobOf(run: string, workflow: string, task: string, cubeSlug: string, cube: Record<string, unknown>): CiJob {\n const rawStatus = text(cube.status) ?? 'unknown';\n const dates = isRecord(cube.dates) ? cube.dates : {};\n const createdAt = toTimestamp(dates.created_at);\n const startedAt = toTimestamp(dates.started_at);\n const finishedAt = toTimestamp(dates.finished_at);\n return {\n key: [run, workflow, task, cubeSlug].map(encodeURIComponent).join('/'),\n runKey: run,\n name: cubeSlug,\n stage: `${workflow}/${task}`,\n status: { category: lookup(SOURCECRAFT_CI_STATUSES, rawStatus, 'running'), name: rawStatus },\n links: [],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(startedAt === undefined ? {} : { startedAt }),\n ...(finishedAt === undefined ? {} : { finishedAt }),\n };\n}\n\n/** Проверка прогона фильтрами страницы: status, event, workflow, actor, pullRequest и границы времени. */\nfunction keepsRun(run: CiRun, query: CiRunQuery): boolean {\n return (\n (query.status === undefined || query.status.includes(run.status.category)) &&\n (query.event === undefined || (run.event !== undefined && query.event.includes(run.event.category))) &&\n (query.workflow === undefined || run.workflows.includes(query.workflow)) &&\n (query.actor === undefined || run.actor === query.actor) &&\n (query.pullRequest === undefined || run.pullRequest === query.pullRequest) &&\n inTimeRange(run.createdAt, query.createdAfter, query.createdBefore) &&\n inTimeRange(run.updatedAt, query.updatedAfter, query.updatedBefore)\n );\n}\n\n/**\n * pullRequest прогона для фильтра: slug, если API его отдал; если slug пуст, а фильтр pullRequest разрешён\n * в id PR — ключ из фильтра (M4: у живого API у прогона pull.id есть, а pull.slug пустой, поэтому фильтр\n * и сравнение идут через id, а pullRequest заполняется разрешённым ключом).\n */\nfunction pullSlugOf(run: CiRun, raw: Record<string, unknown>, pullId: string | undefined, slug: string | undefined): CiRun {\n if (run.pullRequest !== undefined || pullId === undefined || slug === undefined) return run;\n const id = isRecord(raw.pull) ? text(raw.pull.id) : undefined;\n return id === pullId ? { ...run, pullRequest: slug } : run;\n}\n\n/** Сколько байт в начале окна — продолжение символа UTF-8, начатого до окна: окно начинается со следующего целого. */\nfunction leadingByte(window: Uint8Array): number {\n let count = 0;\n while (count < 3 && count < window.length && ((window[count] ?? 0) & 0xc0) === 0x80) count += 1;\n return count;\n}\n\n/** Сколько байт в конце окна — начало символа UTF-8, который в окно целиком не вошёл: он уходит в следующее. */\nfunction trailingByte(window: Uint8Array): number {\n for (let back = 1; back <= Math.min(4, window.length); back += 1) {\n const byte = window[window.length - back] ?? 0;\n if ((byte & 0xc0) === 0x80) continue;\n const size = byte >= 0xf0 ? 4 : byte >= 0xe0 ? 3 : byte >= 0xc0 ? 2 : 1;\n return size > back ? back : 0;\n }\n return 0;\n}\n\nfunction concat(head: Uint8Array, tail: Uint8Array): Uint8Array {\n if (head.length === 0) return tail;\n if (tail.length === 0) return head;\n const merged = new Uint8Array(head.length + tail.length);\n merged.set(head, 0);\n merged.set(tail, head.length);\n return merged;\n}\n","// Реестр трекеров библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/registry.lib.ts — дословная копия. Побочных эффектов при импорте нет:\n// реестр пуст, наполняется только явными вызовами registerTracker/registerBuiltinTrackers (R-001).\nimport type { TrackerDefinition } from './tracker.types.ts';\n\n// Реестр трекеров (D-350): вид подключения → определение. Потребитель работает только через него;\n// новый трекер — модуль с `TrackerDefinition` и одна строка регистрации в `builtin.lib.ts`.\n\nconst definitions = new Map<string, TrackerDefinition>();\n\n/** Регистрирует трекер; повтор того же вида — ошибка сборки, а не замена. */\nexport function registerTracker(definition: TrackerDefinition): void {\n const kind = definition.descriptor.tracker;\n if (definitions.has(kind)) throw new Error(`Трекер ${kind} уже зарегистрирован.`);\n definitions.set(kind, definition);\n}\n\nexport function findTracker(kind: string): TrackerDefinition | undefined {\n return definitions.get(kind);\n}\n\nexport function listTrackers(): TrackerDefinition[] {\n return [...definitions.values()];\n}\n","// Схемы zod pull request-ов единой модели библиотеки @smwb/onreel-git-mcp — свои (#15).\n// Выведенные типы — здесь же (фасет schema, pet:D-037).\nimport { z } from 'zod';\nimport { issueLinkSchema, timestampSchema } from '../contract/contract.schema.ts';\n\n/** Категория состояния PR единой модели (D-005); своё имя трекер отдаёт в status.name. */\nexport const pullRequestStatusCategorySchema = z.enum(['draft', 'open', 'merged', 'closed']);\nexport const pullRequestFilterSchema = z.enum(['status', 'author', 'source', 'target', 'labels', 'search', 'createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore']);\nexport const pullRequestSortFieldSchema = z.enum(['created', 'updated', 'title']);\nexport const mergeMethodSchema = z.enum(['merge', 'squash', 'rebase']);\n\nexport const pullRequestSchema = z.object({\n /** Номер PR в своём трекере: GitHub number, GitLab iid, SourceCraft slug; для клиента непрозрачная строка. */\n key: z.string().min(1).max(200),\n title: z.string().min(1).max(1024),\n description: z.string().max(1_048_576).optional(),\n status: z.object({ category: pullRequestStatusCategorySchema, name: z.string().min(1).max(200) }),\n /** Автор — логин или slug трекера. */\n author: z.string().min(1).max(200).optional(),\n /** Ветка-источник и целевая ветка — имя без refs/heads/. */\n source: z.string().min(1).max(500),\n target: z.string().min(1).max(500),\n /** Коммит головы источника. */\n headSha: z.string().regex(/^[0-9a-f]{7,64}$/).optional(),\n labels: z.array(z.string().min(1).max(200)).max(100),\n /** Запрошенные ревьюеры; нет — трекер их в PR не отдаёт. */\n reviewers: z.array(z.string().min(1).max(200)).max(100).optional(),\n links: z.array(issueLinkSchema).max(100),\n createdAt: timestampSchema.optional(),\n updatedAt: timestampSchema.optional(),\n mergedAt: timestampSchema.optional(),\n closedAt: timestampSchema.optional(),\n});\n\nexport type PullRequestStatusCategory = z.infer<typeof pullRequestStatusCategorySchema>;\nexport type PullRequestFilter = z.infer<typeof pullRequestFilterSchema>;\nexport type PullRequestSortField = z.infer<typeof pullRequestSortFieldSchema>;\nexport type MergeMethod = z.infer<typeof mergeMethodSchema>;\nexport type PullRequest = z.infer<typeof pullRequestSchema>;\n","// Адаптер pull request-ов GitHub библиотеки @smwb/onreel-git-mcp — свой (#15): раздел pulls определения\n// трекера (D-005) на том же подключении, что и задачи; PR репозитория `owner/repo` через REST API.\nimport type { IssueComment } from '../contract/contract.types.ts';\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { pullRequestFilterSchema, pullRequestStatusCategorySchema } from './pull.schema.ts';\nimport type { PullRequest, PullRequestStatusCategory } from './pull.schema.ts';\nimport type { MergeInput, NewPullRequestInput, PullRequestAdapter, PullRequestCapabilities, PullRequestDefinition, PullRequestPatchInput, PullRequestQuery } from './pull.types.ts';\nimport { COMMENT_FILTERS } from './tracker.const.ts';\nimport { TrackerError, assertCommentQuery, assertListQuery, containsText, inTimeRange, isRecord, isoTime, requireTarget, stringList, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext } from './tracker.types.ts';\n\n// Список PR идёт через `/pulls`: параметров автора, меток, поиска и времени у него нет, поэтому эти фильтры\n// проверяются по полученной странице (D-004). Черновик и «готов» переводятся только GraphQL, а ветка-источник\n// при слиянии не удаляется — отказы по capability до записи, снятие черновика — после чтения PR. Комментарии PR лежат под\n// задачиным `/issues/{n}/comments`, а не под `/pulls`.\n\nconst DEFAULT_API = 'https://api.github.com';\nconst TARGET = /^[\\w.-]+\\/[\\w.-]+$/;\nconst NUMBER = /^[1-9]\\d{0,19}$/;\nconst SHA = /^[0-9a-f]{7,64}$/;\nconst LIST_SUBJECT = 'PR GitHub';\nconst COMMENTS_SUBJECT = 'Комментарии PR GitHub';\n\n/** Возможности PR GitHub (§3.6): автор, метки, поиск и время — по странице; сортировка — created и updated. */\nconst PULL_CAPABILITIES: PullRequestCapabilities = {\n list: {\n filters: pullRequestFilterSchema.options,\n clientSide: ['status', 'author', 'labels', 'search', 'createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore'],\n sorts: ['created', 'updated'],\n },\n comments: { filters: COMMENT_FILTERS, clientSide: [], order: ['asc'] },\n create: true,\n createDraft: true,\n update: ['title', 'description', 'target'],\n statuses: ['open', 'closed'],\n comment: true,\n merge: ['merge', 'squash', 'rebase'],\n deleteSourceOnMerge: false,\n};\n\nexport function githubPulls(): PullRequestDefinition {\n return {\n capabilities: PULL_CAPABILITIES,\n create: (context) => createGithubPullAdapter(context),\n };\n}\n\nfunction createGithubPullAdapter({ connection, fetch }: AdapterContext): PullRequestAdapter {\n const target = requireTarget(connection.target, 'owner/repo репозитория GitHub');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target GitHub — owner/repo.');\n const api = baseUrl(connection.url, DEFAULT_API);\n const origin = new URL(api).origin;\n const root = `${api}/repos/${target}/pulls`;\n const issues = `${api}/repos/${target}/issues`;\n // `head` списка — `owner:ветка`: источник ищется в том же владельце, что и целевой репозиторий.\n const owner = target.split('/')[0] ?? target;\n const headers = {\n accept: 'application/vnd.github+json',\n 'x-github-api-version': '2022-11-28',\n ...(connection.token === undefined || connection.token === '' ? {} : { authorization: `Bearer ${connection.token}` }),\n };\n const missing = (key: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В GitHub нет PR ${key}.` });\n const number = (key: string): string => {\n if (!NUMBER.test(key)) throw new TrackerError('not_found', `В GitHub нет PR ${key}.`);\n return key;\n };\n const getPull = async (key: string): Promise<PullRequest> =>\n pullOf((await requestJson(`${root}/${number(key)}`, { fetch, origin, headers, missing: missing(key) })).body);\n return {\n list: async (query) => {\n assertListQuery(LIST_SUBJECT, PULL_CAPABILITIES.list, query, pullRequestFilterSchema.options);\n const status = usedStatuses(query.status);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({ state: stateFilter(status), per_page: String(query.limit), page: String(page) });\n if (query.source !== undefined) params.set('head', `${owner}:${query.source}`);\n if (query.target !== undefined) params.set('base', query.target);\n if (query.sort !== undefined) {\n params.set('sort', query.sort.field);\n params.set('direction', query.sort.direction ?? 'desc');\n }\n const { body, headers: responseHeaders } = await requestJson(`${root}?${params.toString()}`, { fetch, origin, headers });\n const items = (Array.isArray(body) ? body : []).map(pullOf).filter((pull) => matchesPage(pull, query, status));\n return { items, ...nextOf(responseHeaders.get('link'), page) };\n },\n get: (key) => getPull(key),\n create: async (input) => pullOf((await requestJson(root, { fetch, origin, headers, method: 'POST', body: createBody(input) })).body),\n update: async (key, patch) => {\n // Черновик через REST не ставится; снятие черновика — тем более, и оно требует текущего состояния PR.\n if (patch.status === 'draft') throw new TrackerError('unsupported', 'PR GitHub: перевод в черновик недоступен через REST.');\n const current = patch.status === 'open' ? await getPull(key) : undefined;\n if (current?.status.category === 'draft') throw new TrackerError('unsupported', 'PR GitHub: снятие черновика недоступно через REST.');\n // Переход «в то же состояние» без других правок не пишет повторно: open на открытом PR — только GET.\n if (current !== undefined && current.status.category === 'open' && patch.title === undefined && patch.description === undefined && patch.target === undefined) return current;\n return pullOf((await requestJson(`${root}/${number(key)}`, { fetch, origin, headers, method: 'PATCH', body: patchBody(patch), missing: missing(key) })).body);\n },\n merge: async (key, input) => {\n if (input.deleteSource === true) throw new TrackerError('unsupported', 'PR GitHub: удаление ветки-источника при слиянии недоступно.');\n if (input.method !== undefined && !PULL_CAPABILITIES.merge.includes(input.method)) {\n throw new TrackerError('unsupported', `PR GitHub: слияние способом ${input.method} не поддерживается.`);\n }\n // Ответ `/merge` — про слияние, а не про PR: состояние перечитывается get-ом.\n await requestJson(`${root}/${number(key)}/merge`, { fetch, origin, headers, method: 'PUT', body: mergeBody(input), conflictOn: [405, 409], missing: missing(key) });\n return getPull(key);\n },\n comments: async (key, query) => {\n assertCommentQuery(COMMENTS_SUBJECT, PULL_CAPABILITIES.comments, query);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({ per_page: String(query.limit), page: String(page) });\n // `since` — изменения не раньше момента; порядок у GitHub один, по id (§3.7 B2).\n if (query.updatedAfter !== undefined) params.set('since', isoTime(query.updatedAfter));\n const { body, headers: responseHeaders } = await requestJson(`${issues}/${number(key)}/comments?${params.toString()}`, { fetch, origin, headers, missing: missing(key) });\n return { items: (Array.isArray(body) ? body : []).map(commentOf), ...nextOf(responseHeaders.get('link'), page) };\n },\n comment: async (key, body) => commentOf((await requestJson(`${issues}/${number(key)}/comments`, { fetch, origin, headers, method: 'POST', body: { body }, missing: missing(key) })).body),\n };\n}\n\nfunction pageOf(cursor: string | undefined): number {\n const page = cursor === undefined ? 1 : Number(cursor);\n return Number.isInteger(page) && page >= 1 ? page : 1;\n}\n\n/** Следующая страница по `Link`; курсор — номер страницы (§1.1). */\nfunction nextOf(link: string | null, page: number): { nextCursor?: string } {\n return link !== null && /rel=\"next\"/.test(link) ? { nextCursor: String(page + 1) } : {};\n}\n\n/** Категории состояния → `state` списка: черновик и открытый — open, слитый и закрытый — closed;\n * смешанный запрос — all, лишнее отсеет страница. */\nfunction stateFilter(status: readonly PullRequestStatusCategory[] | undefined): string {\n if (status === undefined) return 'all';\n if (status.every((item) => item === 'draft' || item === 'open')) return 'open';\n if (status.every((item) => item === 'merged' || item === 'closed')) return 'closed';\n return 'all';\n}\n\n/** Фильтры, которых нет в параметрах `/pulls`: категория (черновик и слитый видны только по полям PR),\n * автор, метки, поиск и границы времени — по полученной странице (D-004, §3.7 B2). */\nfunction matchesPage(pull: PullRequest, query: PullRequestQuery, status: readonly PullRequestStatusCategory[] | undefined): boolean {\n if (status !== undefined && !status.includes(pull.status.category)) return false;\n if (query.author !== undefined && pull.author !== query.author) return false;\n if (query.labels !== undefined && !query.labels.every((label) => pull.labels.includes(label))) return false;\n if (query.search !== undefined && !containsText([pull.title, pull.description], query.search)) return false;\n return inTimeRange(pull.createdAt, query.createdAfter, query.createdBefore) && inTimeRange(pull.updatedAt, query.updatedAfter, query.updatedBefore);\n}\n\n/** Статусы списка: пустой массив — без фильтра; неизвестная категория — invalid_request до запроса. */\nfunction usedStatuses(status: readonly PullRequestStatusCategory[] | undefined): readonly PullRequestStatusCategory[] | undefined {\n if (status === undefined || status.length === 0) return undefined;\n for (const item of status) {\n if (!pullRequestStatusCategorySchema.options.includes(item)) {\n throw new TrackerError('invalid_request', `PR GitHub: неизвестная категория статуса ${String(item)}.`);\n }\n }\n return status;\n}\n\n/** Тело создания PR: `head` — ветка источника своего репозитория, черновик ставится только когда запрошен. */\nfunction createBody(input: NewPullRequestInput): Record<string, unknown> {\n return {\n title: input.title,\n head: input.source,\n base: input.target,\n ...(input.description === undefined ? {} : { body: input.description }),\n ...(input.draft === true ? { draft: true } : {}),\n };\n}\n\n/** Тело PATCH: поля правки плюс переход состояния — open или closed, черновик отсекается выше. */\nfunction patchBody(patch: PullRequestPatchInput): Record<string, unknown> {\n return {\n ...(patch.title === undefined ? {} : { title: patch.title }),\n ...(patch.description === undefined ? {} : { body: patch.description }),\n ...(patch.target === undefined ? {} : { base: patch.target }),\n ...(patch.status === undefined ? {} : { state: patch.status === 'closed' ? 'closed' : 'open' }),\n };\n}\n\n/** Тело слияния: способ, ожидаемая голова и сообщение коммита — первая строка заголовок, остальное текст. */\nfunction mergeBody(input: MergeInput): Record<string, unknown> {\n const lines = input.message?.split('\\n') ?? [];\n return {\n ...(input.method === undefined ? {} : { merge_method: input.method }),\n ...(input.headSha === undefined ? {} : { sha: input.headSha }),\n ...(input.message === undefined ? {} : { commit_title: lines[0] ?? '' }),\n ...(lines.length > 1 ? { commit_message: lines.slice(1).join('\\n') } : {}),\n };\n}\n\nfunction pullOf(raw: unknown): PullRequest {\n const item = isRecord(raw) ? raw : {};\n const head = isRecord(item.head) ? item.head : {};\n const base = isRecord(item.base) ? item.base : {};\n const key = typeof item.number === 'number' ? String(item.number) : '?';\n const description = text(item.body);\n const author = isRecord(item.user) ? text(item.user.login) : undefined;\n const sha = text(head.sha);\n const url = text(item.html_url);\n const createdAt = toTimestamp(item.created_at);\n const updatedAt = toTimestamp(item.updated_at);\n const mergedAt = toTimestamp(item.merged_at);\n const closedAt = toTimestamp(item.closed_at);\n const closed = item.state === 'closed';\n const merged = item.merged_at !== undefined && item.merged_at !== null;\n // Состояние PR: слитый закрыт вместе с merged_at, черновик — открытый со своим флагом.\n const category: PullRequestStatusCategory = closed ? merged ? 'merged' : 'closed' : item.draft === true ? 'draft' : 'open';\n return {\n key,\n title: text(item.title) ?? key,\n ...(description === undefined ? {} : { description }),\n status: { category, name: category },\n ...(author === undefined ? {} : { author }),\n source: text(head.ref) ?? '?',\n target: text(base.ref) ?? '?',\n ...(sha !== undefined && SHA.test(sha) ? { headSha: sha } : {}),\n labels: Array.isArray(item.labels) ? stringList(item.labels.map((label) => (isRecord(label) ? label.name : label))) : [],\n reviewers: logins(item.requested_reviewers),\n links: url === undefined ? [] : [{ url, title: 'GitHub' }],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n ...(mergedAt === undefined ? {} : { mergedAt }),\n ...(closedAt === undefined ? {} : { closedAt }),\n };\n}\n\n/** Логины запрошенных ревьюеров: GitHub отдаёт их массивом объектов. */\nfunction logins(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n const names = value.map((item) => (isRecord(item) ? text(item.login) : undefined));\n return [...new Set(names.filter((name): name is string => name !== undefined))];\n}\n\nfunction commentOf(raw: unknown): IssueComment {\n const item = isRecord(raw) ? raw : {};\n const author = isRecord(item.user) ? text(item.user.login) : undefined;\n const createdAt = toTimestamp(item.created_at);\n return { id: typeof item.id === 'number' ? String(item.id) : '?', ...(author === undefined ? {} : { author }), body: typeof item.body === 'string' ? item.body : '', ...(createdAt === undefined ? {} : { createdAt }) };\n}\n","// Схемы zod раздела репозитория единой модели библиотеки @smwb/onreel-git-mcp — свои (#23).\n// Выведенные типы — здесь же (фасет schema, pet:D-037).\nimport { z } from 'zod';\nimport { issueLinkSchema } from '../contract/contract.schema.ts';\n\n/** Видимость репозитория единой модели (#23): GitHub, GitLab и SourceCraft называют её одними словами. */\nexport const repoVisibilitySchema = z.enum(['public', 'internal', 'private']);\n/** Фильтры списка веток — имена полей BranchQuery. */\nexport const branchFilterSchema = z.enum(['search']);\n\nexport const repoSchema = z.object({\n /** Имя репозитория, как его называет трекер: GitHub name, GitLab name, SourceCraft slug. */\n name: z.string().min(1).max(500),\n /** Ветка по умолчанию; у пустого репозитория её нет. */\n defaultBranch: z.string().min(1).max(500).optional(),\n description: z.string().max(100_000).optional(),\n visibility: repoVisibilitySchema.optional(),\n /** Ссылки: страница репозитория в трекере (url первой). */\n links: z.array(issueLinkSchema).max(10),\n});\n\nexport const branchSchema = z.object({\n /** Имя ветки без refs/heads/. */\n name: z.string().min(1).max(500),\n /** Коммит головы ветки. */\n sha: z.string().regex(/^[0-9a-f]{7,64}$/).optional(),\n /** Ветка защищена; трекер, который признака не отдаёт, поле не заполняет. */\n protected: z.boolean().optional(),\n /** Ветка по умолчанию репозитория; трекер, который признака не отдаёт, поле не заполняет. */\n isDefault: z.boolean().optional(),\n});\n\nexport type RepoVisibility = z.infer<typeof repoVisibilitySchema>;\nexport type BranchFilter = z.infer<typeof branchFilterSchema>;\nexport type Repo = z.infer<typeof repoSchema>;\nexport type Branch = z.infer<typeof branchSchema>;\n","// Адаптер репозитория GitHub библиотеки @smwb/onreel-git-mcp — свой (#23): раздел repo определения трекера\n// (D-005, D-008) на том же подключении, что и задачи; карточка и ветки репозитория `owner/repo` через REST API.\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { branchFilterSchema, repoVisibilitySchema } from './repo.schema.ts';\nimport type { Branch, Repo, RepoVisibility } from './repo.schema.ts';\nimport type { RepoAdapter, RepoCapabilities, RepoDefinition } from './repo.types.ts';\nimport { TrackerError, assertListQuery, containsText, isRecord, requireTarget, text } from './tracker.lib.ts';\nimport type { AdapterContext } from './tracker.types.ts';\n\n// Карточка и ветки GitHub (D-008). У `/branches` нет ни параметра поиска, ни признака ветки по умолчанию:\n// поиск проверяется по полученной странице (D-004), а ветку по умолчанию потребитель читает из карточки.\n\nconst DEFAULT_API = 'https://api.github.com';\nconst TARGET = /^[\\w.-]+\\/[\\w.-]+$/;\nconst SHA = /^[0-9a-f]{7,64}$/;\nconst BRANCHES_SUBJECT = 'Ветки GitHub';\nconst BRANCH_FILTERS = branchFilterSchema.options;\n\n/** Возможности раздела repo GitHub (#23): поиск по имени ветки адаптер проверяет на полученной странице. */\nconst CAPABILITIES: RepoCapabilities = {\n branches: { filters: BRANCH_FILTERS, clientSide: BRANCH_FILTERS, sorts: [] },\n};\n\nexport function githubRepo(): RepoDefinition {\n return { capabilities: CAPABILITIES, create: (context) => createGithubRepoAdapter(context) };\n}\n\nfunction createGithubRepoAdapter({ connection, fetch }: AdapterContext): RepoAdapter {\n const target = requireTarget(connection.target, 'owner/repo репозитория GitHub');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target GitHub — owner/repo.');\n const api = baseUrl(connection.url, DEFAULT_API);\n const origin = new URL(api).origin;\n const root = `${api}/repos/${target}`;\n const headers = {\n accept: 'application/vnd.github+json',\n 'x-github-api-version': '2022-11-28',\n ...(connection.token === undefined || connection.token === '' ? {} : { authorization: `Bearer ${connection.token}` }),\n };\n const missing = { failure: 'not_found', message: `В GitHub нет репозитория ${target}.` } as const;\n return {\n get: async () => repoOf((await requestJson(root, { fetch, origin, headers, missing })).body, target),\n branches: async (query) => {\n assertListQuery(BRANCHES_SUBJECT, CAPABILITIES.branches, query, BRANCH_FILTERS);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({ per_page: String(query.limit), page: String(page) });\n const { body, headers: responseHeaders } = await requestJson(`${root}/branches?${params.toString()}`, { fetch, origin, headers, missing });\n const items = (Array.isArray(body) ? body : []).map(branchOf).filter((branch) => query.search === undefined || containsText([branch.name], query.search));\n return { items, ...nextOf(responseHeaders.get('link'), page) };\n },\n };\n}\n\n/** Номер страницы из курсора: курсор GitHub — простой номер страницы, первый — 1. */\nfunction pageOf(cursor: string | undefined): number {\n const page = cursor === undefined ? 1 : Number(cursor);\n return Number.isInteger(page) && page >= 1 ? page : 1;\n}\n\n/** Курсор следующей страницы по заголовку Link: rel=\"next\" — страница номером на один больше. */\nfunction nextOf(link: string | null, page: number): { nextCursor?: string } {\n return link !== null && /rel=\"next\"/.test(link) ? { nextCursor: String(page + 1) } : {};\n}\n\n/** Карточка репозитория: имя — как его называет GitHub, видимость — его же слово из перечисления схемы. */\nfunction repoOf(raw: unknown, target: string): Repo {\n const item = isRecord(raw) ? raw : {};\n const defaultBranch = text(item.default_branch);\n const description = text(item.description);\n const visibility = visibilityOf(item.visibility);\n const url = text(item.html_url);\n return {\n name: text(item.name) ?? text(item.full_name) ?? target,\n ...(defaultBranch === undefined ? {} : { defaultBranch }),\n ...(description === undefined ? {} : { description }),\n ...(visibility === undefined ? {} : { visibility }),\n links: url === undefined ? [] : [{ url, title: 'GitHub' }],\n };\n}\n\n/** Ветка GitHub: sha — из commit.sha; признака ветки по умолчанию список не отдаёт. */\nfunction branchOf(raw: unknown): Branch {\n const item = isRecord(raw) ? raw : {};\n const sha = isRecord(item.commit) ? text(item.commit.sha) : undefined;\n return {\n name: text(item.name) ?? '?',\n ...(sha === undefined || !SHA.test(sha) ? {} : { sha }),\n ...(typeof item.protected === 'boolean' ? { protected: item.protected } : {}),\n };\n}\n\n/** Видимость единой модели: значение трекера из перечисления схемы, незнакомое — поле не заполняется. */\nfunction visibilityOf(value: unknown): RepoVisibility | undefined {\n const parsed = repoVisibilitySchema.safeParse(value);\n return parsed.success ? parsed.data : undefined;\n}\n","// Адаптер GitHub библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/github.lib.ts — дословная копия, импорт типов из среза контракта библиотеки;\n// возможности фильтров, маршрутизация /issues ↔ Search API и since комментариев — свои (#14).\nimport type { Issue, IssueComment, IssuePriority, IssueStatusCategory } from '../contract/contract.types.ts';\nimport { githubCi } from './github-ci.lib.ts';\nimport { githubPulls } from './github-pull.lib.ts';\nimport { githubRepo } from './github-repo.lib.ts';\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { GITHUB_CLOSE_REASONS, GITHUB_IN_PROGRESS_LABEL, GITHUB_PRIORITY_LABELS } from './mapping.const.ts';\nimport { ISSUE_FILTERS } from './tracker.const.ts';\nimport { TrackerError, assertCommentQuery, assertListQuery, isRecord, isoTime, lookup, priorityName, quoted, requireTarget, stringList, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext, IssueCapabilities, IssuePatchInput, IssueQuery, TrackerAdapter, TrackerDefinition, TrackerPage } from './tracker.types.ts';\n\n// Трекер GitHub (D-350): задачи репозитория `owner/repo` через REST API. У GitHub статус — open или closed\n// с причиной: «в работе» держится меткой `in progress`, приоритет — меткой `priority: <имя>`; обе метки\n// читаются в поля единой модели и из `labels` убираются. Pull request-ы в списке задач пропускаются.\n// Список идёт через `/issues`, а поиск по тексту и границы created/updated-before есть только в Search API (#14).\n\nconst DEFAULT_API = 'https://api.github.com';\nconst TARGET = /^[\\w.-]+\\/[\\w.-]+$/;\nconst NUMBER = /^[1-9]\\d{0,14}$/;\nconst LIST_SUBJECT = 'Задачи GitHub';\nconst COMMENTS_SUBJECT = 'Комментарии GitHub';\n\nexport function githubTracker(): TrackerDefinition {\n // Возможности по задачам (§3.6): статус GitHub не фильтрует, поэтому проверяется по полученной странице;\n // комментарии — только по времени изменения и только в порядке asc.\n const issues: IssueCapabilities = {\n list: { filters: ISSUE_FILTERS, clientSide: ['status'], sorts: ['created', 'updated', 'comments'] },\n comments: { filters: ['updatedAfter'], clientSide: [], order: ['asc'] },\n };\n return {\n descriptor: {\n tracker: 'github',\n title: 'GitHub',\n fields: [\n { name: 'target', required: true, secret: false },\n { name: 'token', required: true, secret: true },\n { name: 'url', required: false, secret: false },\n ],\n features: { create: true, update: true, comment: true, priority: true, labels: true, assignee: true, statuses: ['open', 'in_progress', 'done', 'declined'] },\n },\n create: (context) => createGithubAdapter(context, issues),\n origin: (connection) => new URL(baseUrl(connection.url, DEFAULT_API)).origin,\n issues,\n pulls: githubPulls(),\n ci: githubCi(),\n repo: githubRepo(),\n };\n}\n\nfunction createGithubAdapter({ connection, fetch }: AdapterContext, capabilities: IssueCapabilities): TrackerAdapter {\n const target = requireTarget(connection.target, 'owner/repo репозитория GitHub');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target GitHub — owner/repo.');\n const api = baseUrl(connection.url, DEFAULT_API);\n const origin = new URL(api).origin;\n const root = `${api}/repos/${target}/issues`;\n const headers = {\n accept: 'application/vnd.github+json',\n 'x-github-api-version': '2022-11-28',\n ...(connection.token === undefined || connection.token === '' ? {} : { authorization: `Bearer ${connection.token}` }),\n };\n const number = (key: string): string => {\n if (!NUMBER.test(key)) throw new TrackerError('unknown_issue', `В GitHub нет задачи ${key}.`);\n return key;\n };\n const rawOf = async (key: string): Promise<Record<string, unknown>> => {\n const { body } = await requestJson(`${root}/${number(key)}`, { fetch, origin, headers, missingIsIssue: true });\n return isRecord(body) ? body : {};\n };\n return {\n list: async (query) => {\n assertListQuery(LIST_SUBJECT, capabilities.list, query, ISSUE_FILTERS);\n assertCsvLabels(query.labels);\n const page = pageOf(query.cursor);\n // Search API нужен, когда запрошено то, чего `/issues` не умеет: текст поиска и границы created/updated-before (§3.7 A2).\n const search = needsSearch(query);\n const params = search ? searchParams(target, query, page) : issuesParams(query, page);\n const { body, headers: responseHeaders } = await requestJson(`${search ? `${api}/search/issues` : root}?${params.toString()}`, { fetch, origin, headers });\n return issuePageOf(rowsOf(body, search), query, responseHeaders.get('link') ?? '', page);\n },\n get: async (key) => issueOf(await rawOf(key)),\n create: async (input) => {\n const labels = composeLabels(input.labels ?? [], input.priority, undefined);\n const body = {\n title: input.title,\n ...(input.description === undefined ? {} : { body: input.description }),\n ...(labels.length === 0 ? {} : { labels }),\n ...(input.assignee === undefined ? {} : { assignees: [input.assignee] }),\n };\n return issueOf((await requestJson(root, { fetch, origin, headers, method: 'POST', body })).body);\n },\n update: async (key, patch) => {\n const current = patch.labels === undefined && patch.priority === undefined && patch.status === undefined ? undefined : issueOf(await rawOf(key));\n const response = await requestJson(`${root}/${number(key)}`, { fetch, origin, headers, method: 'PATCH', body: patchBody(patch, current), missingIsIssue: true });\n return issueOf(response.body);\n },\n comments: async (key, query) => {\n assertCommentQuery(COMMENTS_SUBJECT, capabilities.comments, query);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({ per_page: String(query.limit), page: String(page) });\n // `since` — изменения не раньше момента; порядок у GitHub один, по id (§3.7 A2).\n if (query.updatedAfter !== undefined) params.set('since', isoTime(query.updatedAfter));\n const { body, headers: responseHeaders } = await requestJson(`${root}/${number(key)}/comments?${params.toString()}`, { fetch, origin, headers, missingIsIssue: true });\n return { items: (Array.isArray(body) ? body : []).map(commentOf), ...(/rel=\"next\"/.test(responseHeaders.get('link') ?? '') ? { nextCursor: String(page + 1) } : {}) };\n },\n comment: async (key, body) => commentOf((await requestJson(`${root}/${number(key)}/comments`, { fetch, origin, headers, method: 'POST', body: { body }, missingIsIssue: true })).body),\n };\n}\n\nfunction pageOf(cursor: string | undefined): number {\n const page = cursor === undefined ? 1 : Number(cursor);\n return Number.isInteger(page) && page >= 1 ? page : 1;\n}\n\n/** Параметр `state` по запрошенным категориям; смешанный запрос — все, лишнее отсеет клиент. */\nfunction stateFilter(status: readonly IssueStatusCategory[] | undefined): string {\n if (status === undefined) return 'all';\n if (status.every((item) => item === 'open' || item === 'in_progress')) return 'open';\n if (status.every((item) => item === 'done' || item === 'declined')) return 'closed';\n return 'all';\n}\n\n/** Поиск по тексту и границы created/updated-before есть только в Search API — он и выбирает endpoint (§3.7 A2). */\nfunction needsSearch(query: IssueQuery): boolean {\n return query.search !== undefined || query.createdAfter !== undefined || query.createdBefore !== undefined || query.updatedBefore !== undefined;\n}\n\n/** CSV-параметр labels: запятая внутри метки читалась бы как разделитель списка — отказ до запроса (§3.2 R1). */\nfunction assertCsvLabels(labels: readonly string[] | undefined): void {\n if (labels?.some((label) => label.includes(',')) === true) throw new TrackerError('invalid_request', `${LIST_SUBJECT}: метка не должна содержать запятую.`);\n}\n\n/** Параметры `/issues`: сегодняшние плюс фильтры и сортировка, которые GitHub применяет сам. */\nfunction issuesParams(query: IssueQuery, page: number): URLSearchParams {\n const params = new URLSearchParams({ state: stateFilter(query.status), per_page: String(query.limit), page: String(page) });\n if (query.labels !== undefined && query.labels.length > 0) params.set('labels', query.labels.join(','));\n if (query.assignee !== undefined) params.set('assignee', query.assignee ?? 'none');\n if (query.author !== undefined) params.set('creator', query.author);\n if (query.updatedAfter !== undefined) params.set('since', isoTime(query.updatedAfter));\n if (query.sort !== undefined) {\n params.set('sort', query.sort.field);\n params.set('direction', query.sort.direction ?? 'desc');\n }\n return params;\n}\n\n/** Параметры поиска: `q` плюс страницы и сортировка с `order` вместо `direction`; без sort — created desc,\n * иначе GitHub сортирует по релевантности, а порядок по умолчанию у списка — новые первыми (§3.2 R4, §3.7 A2). */\nfunction searchParams(target: string, query: IssueQuery, page: number): URLSearchParams {\n const params = new URLSearchParams({ q: searchQuery(target, query), per_page: String(query.limit), page: String(page) });\n const sort = query.sort;\n params.set('sort', sort?.field ?? 'created');\n params.set('order', sort?.direction ?? 'desc');\n return params;\n}\n\n/** `q` поиска: репозиторий и тип, затем фильтры; свободный текст — одна фраза в кавычках (§3.2 R6). */\nfunction searchQuery(target: string, query: IssueQuery): string {\n const parts: string[] = [`repo:${target}`, 'is:issue'];\n const state = searchStateFilter(query.status);\n if (state !== undefined) parts.push(state);\n for (const label of query.labels ?? []) parts.push(`label:${quoted(label)}`);\n if (query.assignee !== undefined) parts.push(query.assignee === null ? 'no:assignee' : `assignee:${quoted(query.assignee)}`);\n if (query.author !== undefined) parts.push(`author:${quoted(query.author)}`);\n const created = timeRangeQualifier('created', query.createdAfter, query.createdBefore);\n if (created !== undefined) parts.push(created);\n const updated = timeRangeQualifier('updated', query.updatedAfter, query.updatedBefore);\n if (updated !== undefined) parts.push(updated);\n if (query.search !== undefined) parts.push(quoted(query.search));\n return parts.join(' ');\n}\n\n/** Границы поля времени в q: обе — один квалификатор-диапазон (два квалификатора GitHub объединяет через OR),\n * одна — >= / <=. ISO без кавычек: значение машинное ([0-9TZ:.-]), квалификатор из него не вставить (§3.2 R6). */\nfunction timeRangeQualifier(field: 'created' | 'updated', after: number | undefined, before: number | undefined): string | undefined {\n if (after !== undefined && before !== undefined) return `${field}:${isoTime(after)}..${isoTime(before)}`;\n if (after !== undefined) return `${field}:>=${isoTime(after)}`;\n if (before !== undefined) return `${field}:<=${isoTime(before)}`;\n return undefined;\n}\n\n/** Элементы ответа: `/issues` отдаёт массив, поиск — объект с `items` (§3.7 A2). */\nfunction rowsOf(body: unknown, search: boolean): readonly unknown[] {\n if (!search) return Array.isArray(body) ? body : [];\n return isRecord(body) && Array.isArray(body.items) ? body.items : [];\n}\n\n/** `is:open`/`is:closed` по запрошенным категориям; смешанный запрос — без него, лишнее отсеет страница. */\nfunction searchStateFilter(status: readonly IssueStatusCategory[] | undefined): string | undefined {\n if (status === undefined) return undefined;\n if (status.every((item) => item === 'open' || item === 'in_progress')) return 'is:open';\n if (status.every((item) => item === 'done' || item === 'declined')) return 'is:closed';\n return undefined;\n}\n\n/** Страница задач: pull request-ы пропускаются, статус сверяется с полученной страницей (§3.2 R5). */\nfunction issuePageOf(rows: readonly unknown[], query: IssueQuery, link: string, page: number): TrackerPage<Issue> {\n const items = rows.filter((row) => isRecord(row) && row.pull_request === undefined).map(issueOf);\n return {\n items: query.status === undefined ? items : items.filter((issue) => query.status?.includes(issue.status.category) === true),\n ...(/rel=\"next\"/.test(link) ? { nextCursor: String(page + 1) } : {}),\n };\n}\n\n/** Метки записи: пользовательские плюс служебные для приоритета и «в работе». */\nfunction composeLabels(plain: readonly string[], priority: IssuePriority | undefined, status: IssueStatusCategory | undefined): string[] {\n const priorityLabel = priority === undefined ? undefined : priorityName(GITHUB_PRIORITY_LABELS, priority);\n return [...plain, ...(priorityLabel === undefined ? [] : [priorityLabel]), ...(status === 'in_progress' ? [GITHUB_IN_PROGRESS_LABEL] : [])];\n}\n\nfunction patchBody(patch: IssuePatchInput, current: Issue | undefined): Record<string, unknown> {\n const status = patch.status ?? current?.status.category;\n const touchesLabels = patch.labels !== undefined || patch.priority !== undefined || patch.status !== undefined;\n return {\n ...(patch.title === undefined ? {} : { title: patch.title }),\n ...(patch.description === undefined ? {} : { body: patch.description }),\n ...(patch.status === undefined ? {} : { state: patch.status === 'done' || patch.status === 'declined' ? 'closed' : 'open', ...(patch.status === 'declined' ? { state_reason: 'not_planned' } : patch.status === 'done' ? { state_reason: 'completed' } : { state_reason: 'reopened' }) }),\n ...(touchesLabels ? { labels: composeLabels(patch.labels ?? current?.labels ?? [], patch.priority ?? current?.priority, status) } : {}),\n ...(patch.assignee === undefined ? {} : { assignees: patch.assignee === null ? [] : [patch.assignee] }),\n };\n}\n\nfunction issueOf(raw: unknown): Issue {\n const item = isRecord(raw) ? raw : {};\n const names = Array.isArray(item.labels) ? stringList(item.labels.map((label) => (isRecord(label) ? label.name : label))) : [];\n const closed = item.state === 'closed';\n const category: IssueStatusCategory = closed ? lookup(GITHUB_CLOSE_REASONS, item.state_reason, 'done') : names.includes(GITHUB_IN_PROGRESS_LABEL) ? 'in_progress' : 'open';\n const priority = names.map((name) => lookup<IssuePriority | undefined>(GITHUB_PRIORITY_LABELS, name, undefined)).find((value) => value !== undefined);\n const description = text(item.body);\n const assignee = isRecord(item.assignee) ? text(item.assignee.login) : undefined;\n const url = text(item.html_url);\n const createdAt = toTimestamp(item.created_at);\n const updatedAt = toTimestamp(item.updated_at);\n const number = typeof item.number === 'number' ? String(item.number) : '?';\n return {\n key: number,\n title: text(item.title) ?? number,\n ...(description === undefined ? {} : { description }),\n status: { category, name: closed ? `closed${typeof item.state_reason === 'string' ? ` (${item.state_reason})` : ''}` : category === 'in_progress' ? 'in progress' : 'open' },\n ...(priority === undefined ? {} : { priority }),\n labels: names.filter((name) => name !== GITHUB_IN_PROGRESS_LABEL && !Object.hasOwn(GITHUB_PRIORITY_LABELS, name)),\n ...(assignee === undefined ? {} : { assignee }),\n links: url === undefined ? [] : [{ url, title: 'GitHub' }],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n };\n}\n\nfunction commentOf(raw: unknown): IssueComment {\n const item = isRecord(raw) ? raw : {};\n const author = isRecord(item.user) ? text(item.user.login) : undefined;\n const createdAt = toTimestamp(item.created_at);\n return { id: typeof item.id === 'number' ? String(item.id) : '?', ...(author === undefined ? {} : { author }), body: typeof item.body === 'string' ? item.body : '', ...(createdAt === undefined ? {} : { createdAt }) };\n}\n","// Адаптер merge request-ов GitLab библиотеки @smwb/onreel-git-mcp — свой (#15): раздел pulls\n// определения трекера (D-005) на том же подключении, что и задачи; MR проекта через REST API v4.\nimport type { IssueComment } from '../contract/contract.types.ts';\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { GITLAB_DRAFT_PATTERN, GITLAB_DRAFT_PREFIX, GITLAB_MERGE_REQUEST_STATES } from './mapping.const.ts';\nimport { pullRequestFilterSchema, pullRequestStatusCategorySchema } from './pull.schema.ts';\nimport type { PullRequest, PullRequestStatusCategory } from './pull.schema.ts';\nimport type { PullRequestAdapter, PullRequestCapabilities, PullRequestDefinition, PullRequestPatchInput } from './pull.types.ts';\nimport { COMMENT_FILTERS } from './tracker.const.ts';\nimport { TrackerError, assertCommentQuery, assertListQuery, inTimeRange, isRecord, isoTime, lookup, requireTarget, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext } from './tracker.types.ts';\n\n// Черновик у GitLab — префикс заголовка (`Draft: ` и прочие формы), а не поле: draft открытого MR адаптер\n// читает из поля draft, а ставит и снимает правкой заголовка. Слияние rebase — отдельный эндпоинт, которого\n// в единой модели нет.\n\nconst DEFAULT_URL = 'https://gitlab.com';\nconst TARGET = /^(\\d{1,15}|[\\w.-]+(\\/[\\w.-]+)+)$/;\nconst IID = /^[1-9]\\d{0,19}$/;\nconst SHA = /^[0-9a-f]{7,64}$/;\n\n/** Возможности PR GitLab (#15): все фильтры единой модели, статус (включая черновик) проверяется по странице. */\nconst PULL_CAPABILITIES: PullRequestCapabilities = {\n list: { filters: pullRequestFilterSchema.options, clientSide: ['status'], sorts: ['created', 'updated', 'title'] },\n comments: { filters: COMMENT_FILTERS, clientSide: COMMENT_FILTERS, order: ['asc', 'desc'] },\n create: true,\n createDraft: true,\n update: ['title', 'description', 'target'],\n statuses: ['draft', 'open', 'closed'],\n comment: true,\n merge: ['merge', 'squash'],\n deleteSourceOnMerge: true,\n};\n\n/** Поле сортировки единой модели → order_by GitLab. */\nconst ORDER_BY: Readonly<Record<string, string>> = { created: 'created_at', updated: 'updated_at', title: 'title' };\n\nexport function gitlabPulls(): PullRequestDefinition {\n return {\n capabilities: PULL_CAPABILITIES,\n create: (context) => createGitlabPullAdapter(context),\n };\n}\n\nfunction createGitlabPullAdapter({ connection, fetch }: AdapterContext): PullRequestAdapter {\n const target = requireTarget(connection.target, 'путь проекта GitLab, group/project, или его id');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target GitLab — group/project или числовой id.');\n const site = baseUrl(connection.url, DEFAULT_URL);\n const origin = new URL(site).origin;\n const root = `${site}/api/v4/projects/${encodeURIComponent(target)}/merge_requests`;\n const headers: Record<string, string> = connection.token === undefined || connection.token === '' ? {} : { 'private-token': connection.token };\n const iid = (key: string): string => {\n if (!IID.test(key)) throw new TrackerError('not_found', `В GitLab нет MR ${key}.`);\n return key;\n };\n const currentOf = async (key: string): Promise<PullRequest> => pullOf((await requestJson(`${root}/${iid(key)}`, { fetch, origin, headers, missing: { failure: 'not_found', message: `В GitLab нет MR ${key}.` } })).body);\n return {\n list: async (query) => {\n assertListQuery('PR GitLab', PULL_CAPABILITIES.list, query, pullRequestFilterSchema.options);\n const status = usedStatuses(query.status);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({\n state: stateFilter(status),\n per_page: String(query.limit),\n page: String(page),\n order_by: query.sort === undefined ? 'created_at' : (ORDER_BY[query.sort.field] ?? 'created_at'),\n sort: query.sort?.direction ?? 'desc',\n });\n if (query.labels !== undefined && query.labels.length > 0) {\n if (query.labels.some((label) => label.includes(','))) throw new TrackerError('invalid_request', 'PR GitLab: метка не должна содержать запятую.');\n params.set('labels', query.labels.join(','));\n }\n if (query.author !== undefined) params.set('author_username', query.author);\n if (query.source !== undefined) params.set('source_branch', query.source);\n if (query.target !== undefined) params.set('target_branch', query.target);\n if (query.search !== undefined) params.set('search', query.search);\n if (query.createdAfter !== undefined) params.set('created_after', isoTime(query.createdAfter));\n if (query.createdBefore !== undefined) params.set('created_before', isoTime(query.createdBefore));\n if (query.updatedAfter !== undefined) params.set('updated_after', isoTime(query.updatedAfter));\n if (query.updatedBefore !== undefined) params.set('updated_before', isoTime(query.updatedBefore));\n const { body, headers: responseHeaders } = await requestJson(`${root}?${params.toString()}`, { fetch, origin, headers });\n const next = responseHeaders.get('x-next-page');\n const items = (Array.isArray(body) ? body : []).map(pullOf);\n // Черновик против открытого адаптер различает по полю draft на странице: страница бывает короче limit.\n return {\n items: status === undefined ? items : items.filter((pr) => status.includes(pr.status.category) === true),\n ...(next === null || next === '' ? {} : { nextCursor: next }),\n };\n },\n get: currentOf,\n create: async (input) => {\n const body = {\n source_branch: input.source,\n target_branch: input.target,\n title: (input.draft === true ? GITLAB_DRAFT_PREFIX : '') + input.title,\n ...(input.description === undefined ? {} : { description: input.description }),\n };\n return pullOf((await requestJson(root, { fetch, origin, headers, method: 'POST', body, conflictOn: [409] })).body);\n },\n update: async (key, patch) => {\n const current = patch.status === undefined ? undefined : await currentOf(key);\n if (patch.status === 'draft' && current?.status.category === 'closed') {\n throw new TrackerError('unsupported', 'PR GitLab: перевод закрытого MR в черновик недоступен.');\n }\n const body = patchBody(patch, current);\n // Пустое тело GitLab отклоняет (400): неизменный запрос — без PUT, ответ — текущий MR.\n if (Object.keys(body).length === 0) return current ?? pullOf((await requestJson(`${root}/${iid(key)}`, { fetch, origin, headers, missing: { failure: 'not_found', message: `В GitLab нет MR ${key}.` } })).body);\n return pullOf((await requestJson(`${root}/${iid(key)}`, { fetch, origin, headers, method: 'PUT', body, missing: { failure: 'not_found', message: `В GitLab нет MR ${key}.` } })).body);\n },\n merge: async (key, input) => {\n if (input.method !== undefined && !PULL_CAPABILITIES.merge.includes(input.method)) {\n throw new TrackerError('unsupported', `PR GitLab: слияние способом ${input.method} не поддерживается.`);\n }\n const body = {\n // squash: true ставит squash; false GitLab игнорирует — при method 'merge' действует настройка MR/проекта.\n ...(input.method === 'squash' ? { squash: true } : {}),\n ...(input.message === undefined ? {} : input.method === 'squash' ? { squash_commit_message: input.message } : { merge_commit_message: input.message }),\n ...(input.deleteSource === undefined ? {} : { should_remove_source_branch: input.deleteSource }),\n ...(input.headSha === undefined ? {} : { sha: input.headSha }),\n };\n return pullOf((await requestJson(`${root}/${iid(key)}/merge`, { fetch, origin, headers, method: 'PUT', body, conflictOn: [405, 409, 422], missing: { failure: 'not_found', message: `В GitLab нет MR ${key}.` } })).body);\n },\n comments: async (key, query) => {\n assertCommentQuery('Комментарии GitLab', PULL_CAPABILITIES.comments, query);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({ sort: query.order ?? 'asc', order_by: 'created_at', per_page: String(query.limit), page: String(page) });\n const { body, headers: responseHeaders } = await requestJson(`${root}/${iid(key)}/notes?${params.toString()}`, { fetch, origin, headers, missing: { failure: 'not_found', message: `В GitLab нет MR ${key}.` } });\n const next = responseHeaders.get('x-next-page');\n // Системные заметки («изменил метку») — не комментарии; updatedAfter сверяется с сырым updated_at заметки.\n const items = (Array.isArray(body) ? body : [])\n .filter((note) => isRecord(note) && note.system !== true && inTimeRange(toTimestamp(note.updated_at), query.updatedAfter, undefined))\n .map(commentOf);\n return { items, ...(next === null || next === '' ? {} : { nextCursor: next }) };\n },\n comment: async (key, body) => commentOf((await requestJson(`${root}/${iid(key)}/notes`, { fetch, origin, headers, method: 'POST', body: { body }, missing: { failure: 'not_found', message: `В GitLab нет MR ${key}.` } })).body),\n };\n}\n\nfunction pageOf(cursor: string | undefined): number {\n const page = cursor === undefined ? 1 : Number(cursor);\n return Number.isInteger(page) && page >= 1 ? page : 1;\n}\n\n/** Категории состояния → state списка: только черновики и открытые — opened, смешанный набор — all. */\nfunction stateFilter(status: readonly PullRequestStatusCategory[] | undefined): string {\n if (status === undefined) return 'all';\n if (status.every((item) => item === 'draft' || item === 'open')) return 'opened';\n if (status.every((item) => item === 'merged')) return 'merged';\n if (status.every((item) => item === 'closed')) return 'closed';\n return 'all';\n}\n\n/** Тело PUT: поля правки и переход состояния; черновик правится префиксом заголовка, что требует текущего MR.\n * Переход «в то же состояние» не пишет повторно: повторный close и неизменный заголовок опускаются. */\nfunction patchBody(patch: PullRequestPatchInput, current: PullRequest | undefined): Record<string, unknown> {\n const body: Record<string, unknown> = {};\n if (patch.description !== undefined) body.description = patch.description;\n if (patch.target !== undefined) body.target_branch = patch.target;\n if (patch.status === 'closed' && current?.status.category !== 'closed') body.state_event = 'close';\n if (patch.status === 'open' && current?.status.category === 'closed') body.state_event = 'reopen';\n if (patch.status === 'draft' || patch.status === 'open') {\n // Перевод в черновик или снятие черновика: прежние формы префикса снимаются, при черновике — свой префикс;\n // open на закрытом черновике снимает префикс вместе с reopen, чтобы результат был open, а не draft.\n const title = patch.title ?? current?.title ?? '';\n const base = title.replace(GITLAB_DRAFT_PATTERN, '');\n // Неизменный заголовок (draft на черновике, open на открытом) сверяется с текущим MR и не отправляется повторно.\n const next = patch.status === 'draft' ? GITLAB_DRAFT_PREFIX + base : current?.status.category === 'draft' || title !== base ? base : patch.title;\n if (next !== undefined && next !== current?.title) body.title = next;\n } else if (patch.title !== undefined && patch.title !== current?.title) {\n body.title = patch.title;\n }\n return body;\n}\n\n/** Статусы списка: пустой массив — без фильтра; неизвестная категория — invalid_request до запроса. */\nfunction usedStatuses(status: readonly PullRequestStatusCategory[] | undefined): readonly PullRequestStatusCategory[] | undefined {\n if (status === undefined || status.length === 0) return undefined;\n for (const item of status) {\n if (!pullRequestStatusCategorySchema.options.includes(item)) {\n throw new TrackerError('invalid_request', `PR GitLab: неизвестная категория статуса ${String(item)}.`);\n }\n }\n return status;\n}\n\n/** Метки MR: GitLab отдаёт и строки, и объекты с name. */\nfunction labelNames(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n const names = value.map((item) => (typeof item === 'string' ? item : isRecord(item) ? text(item.name) : undefined));\n return [...new Set(names.filter((name): name is string => name !== undefined && name !== ''))];\n}\n\nfunction usernames(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n const names = value.map((item) => (isRecord(item) ? text(item.username) : undefined));\n return [...new Set(names.filter((name): name is string => name !== undefined && name !== ''))];\n}\n\nfunction pullOf(raw: unknown): PullRequest {\n const item = isRecord(raw) ? raw : {};\n const state = text(item.state) ?? 'opened';\n const draft = item.draft === true;\n const category = lookup<PullRequestStatusCategory>(GITLAB_MERGE_REQUEST_STATES, state, 'open');\n const key = typeof item.iid === 'number' ? String(item.iid) : '?';\n const description = text(item.description);\n const author = isRecord(item.author) ? text(item.author.username) : undefined;\n const sha = text(item.sha);\n const url = text(item.web_url);\n const createdAt = toTimestamp(item.created_at);\n const updatedAt = toTimestamp(item.updated_at);\n const mergedAt = toTimestamp(item.merged_at);\n const closedAt = toTimestamp(item.closed_at);\n return {\n key,\n title: text(item.title) ?? key,\n ...(description === undefined ? {} : { description }),\n status: { category: draft && category === 'open' ? 'draft' : category, name: draft && category === 'open' ? 'draft' : state },\n ...(author === undefined ? {} : { author }),\n source: text(item.source_branch) ?? '?',\n target: text(item.target_branch) ?? '?',\n ...(sha !== undefined && SHA.test(sha) ? { headSha: sha } : {}),\n labels: labelNames(item.labels),\n reviewers: usernames(item.reviewers),\n links: url === undefined ? [] : [{ url, title: 'GitLab' }],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n ...(mergedAt === undefined ? {} : { mergedAt }),\n ...(closedAt === undefined ? {} : { closedAt }),\n };\n}\n\nfunction commentOf(raw: unknown): IssueComment {\n const item = isRecord(raw) ? raw : {};\n const author = isRecord(item.author) ? text(item.author.username) : undefined;\n const createdAt = toTimestamp(item.created_at);\n return { id: typeof item.id === 'number' ? String(item.id) : '?', ...(author === undefined ? {} : { author }), body: typeof item.body === 'string' ? item.body : '', ...(createdAt === undefined ? {} : { createdAt }) };\n}\n","// Адаптер репозитория GitLab библиотеки @smwb/onreel-git-mcp — свой (#23): раздел repo определения трекера\n// (D-005, D-008) на том же подключении, что и задачи; карточка и ветки проекта через REST API v4.\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { branchFilterSchema, repoVisibilitySchema } from './repo.schema.ts';\nimport type { Branch, Repo, RepoVisibility } from './repo.schema.ts';\nimport type { RepoAdapter, RepoCapabilities, RepoDefinition } from './repo.types.ts';\nimport { TrackerError, assertListQuery, isRecord, requireTarget, text } from './tracker.lib.ts';\nimport type { AdapterContext } from './tracker.types.ts';\n\n// Карточка и ветки GitLab (D-008). Карточка — сам проект (`/projects/{id}`), ветки — его репозиторий\n// (`/repository/branches`): у GitLab проект и репозиторий — одна сущность. Поиск веток фильтрует сервер\n// (параметр search), поэтому на странице он не перепроверяется.\n\nconst DEFAULT_URL = 'https://gitlab.com';\nconst TARGET = /^(\\d{1,15}|[\\w.-]+(\\/[\\w.-]+)+)$/;\nconst SHA = /^[0-9a-f]{7,64}$/;\nconst BRANCHES_SUBJECT = 'Ветки GitLab';\nconst BRANCH_FILTERS = branchFilterSchema.options;\n\n/** Возможности раздела repo GitLab (#23): поиск веток — параметр сервера, сортировки нет. */\nconst CAPABILITIES: RepoCapabilities = {\n branches: { filters: BRANCH_FILTERS, clientSide: [], sorts: [] },\n};\n\nexport function gitlabRepo(): RepoDefinition {\n return { capabilities: CAPABILITIES, create: (context) => createGitlabRepoAdapter(context) };\n}\n\nfunction createGitlabRepoAdapter({ connection, fetch }: AdapterContext): RepoAdapter {\n const target = requireTarget(connection.target, 'путь проекта GitLab, group/project, или его id');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target GitLab — group/project или числовой id.');\n const site = baseUrl(connection.url, DEFAULT_URL);\n const origin = new URL(site).origin;\n const project = `${site}/api/v4/projects/${encodeURIComponent(target)}`;\n const headers: Record<string, string> = connection.token === undefined || connection.token === '' ? {} : { 'private-token': connection.token };\n const missing = { failure: 'not_found', message: `В GitLab нет проекта ${target}.` } as const;\n return {\n get: async () => repoOf((await requestJson(project, { fetch, origin, headers, missing })).body, target),\n branches: async (query) => {\n assertListQuery(BRANCHES_SUBJECT, CAPABILITIES.branches, query, BRANCH_FILTERS);\n const params = new URLSearchParams({ per_page: String(query.limit), page: String(pageOf(query.cursor)) });\n if (query.search !== undefined) params.set('search', searchOf(query.search));\n const { body, headers: responseHeaders } = await requestJson(`${project}/repository/branches?${params.toString()}`, { fetch, origin, headers, missing });\n const next = responseHeaders.get('x-next-page');\n return { items: (Array.isArray(body) ? body : []).map(branchOf), ...(next === null || next === '' ? {} : { nextCursor: next }) };\n },\n };\n}\n\n/** Номер страницы из курсора: курсор GitLab — номер страницы, первый — 1. */\nfunction pageOf(cursor: string | undefined): number {\n const page = cursor === undefined ? 1 : Number(cursor);\n return Number.isInteger(page) && page >= 1 ? page : 1;\n}\n\n/**\n * GitLab читает `^` в начале и `$` в конце `search` как якоря, а `*` — как шаблон; единая модель обещает\n * подстроку имени ветки (D-008). Якоря снимаются, и `^rel` ищет подстроку `rel` так же, как у GitHub и\n * SourceCraft. Экранировать их нельзя: GitLab ищет `\\^` буквально и не находит ничего. Строка только из\n * якорей остаётся как есть — иначе непустой запрос превратился бы в пустой. `*` остаётся шаблоном GitLab:\n * в имени ветки git её не бывает.\n */\nfunction searchOf(value: string): string {\n const stripped = value.replace(/^\\^/, '').replace(/\\$$/, '');\n return stripped === '' ? value : stripped;\n}\n\n/** Карточка проекта: имя — как его называет GitLab, видимость — его же слово из перечисления схемы. */\nfunction repoOf(raw: unknown, target: string): Repo {\n const item = isRecord(raw) ? raw : {};\n const defaultBranch = text(item.default_branch);\n const description = text(item.description);\n const visibility = visibilityOf(item.visibility);\n const url = text(item.web_url);\n return {\n name: text(item.name) ?? text(item.path_with_namespace) ?? target,\n ...(defaultBranch === undefined ? {} : { defaultBranch }),\n ...(description === undefined ? {} : { description }),\n ...(visibility === undefined ? {} : { visibility }),\n links: url === undefined ? [] : [{ url, title: 'GitLab' }],\n };\n}\n\n/** Ветка GitLab: sha — commit.id, защита и признак ветки по умолчанию — поля самой ветки. */\nfunction branchOf(raw: unknown): Branch {\n const item = isRecord(raw) ? raw : {};\n const sha = isRecord(item.commit) ? text(item.commit.id) : undefined;\n return {\n name: text(item.name) ?? '?',\n ...(sha === undefined || !SHA.test(sha) ? {} : { sha }),\n ...(typeof item.protected === 'boolean' ? { protected: item.protected } : {}),\n ...(typeof item.default === 'boolean' ? { isDefault: item.default } : {}),\n };\n}\n\n/** Видимость единой модели: значение трекера из перечисления схемы, незнакомое — поле не заполняется. */\nfunction visibilityOf(value: unknown): RepoVisibility | undefined {\n const parsed = repoVisibilitySchema.safeParse(value);\n return parsed.success ? parsed.data : undefined;\n}\n","// Адаптер GitLab библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/gitlab.lib.ts — дословная копия, импорт типов из среза контракта библиотеки.\nimport type { Issue, IssueComment, IssuePriority, IssueStatusCategory } from '../contract/contract.types.ts';\nimport { gitlabPulls } from './gitlab-pull.lib.ts';\nimport { gitlabRepo } from './gitlab-repo.lib.ts';\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { gitlabCi } from './gitlab-ci.lib.ts';\nimport { GITLAB_IN_PROGRESS_LABEL, GITLAB_PRIORITY_LABELS } from './mapping.const.ts';\nimport { COMMENT_FILTERS, ISSUE_FILTERS } from './tracker.const.ts';\nimport type { IssueSortField } from './tracker.const.ts';\nimport { TrackerError, assertCommentQuery, assertListQuery, inTimeRange, isRecord, isoTime, lookup, priorityName, requireTarget, stringList, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext, IssueCapabilities, IssuePatchInput, TrackerAdapter, TrackerDefinition } from './tracker.types.ts';\n\n// Трекер GitLab (D-350): задачи проекта (`group/project` или числовой id) через REST API v4, токен — PRIVATE-TOKEN.\n// У GitLab статус — opened или closed: «в работе» держится меткой `status::in-progress`, приоритет —\n// меткой `priority::<имя>`; служебные метки читаются в поля единой модели и из `labels` убираются. «Отклонена»\n// у GitLab нет. Исполнитель у GitLab задаётся по id пользователя, поэтому только показывается.\n\nconst DEFAULT_URL = 'https://gitlab.com';\nconst TARGET = /^(\\d{1,15}|[\\w.-]+(\\/[\\w.-]+)+)$/;\nconst IID = /^[1-9]\\d{0,14}$/;\n\n/** Возможности списков GitLab (#14): все фильтры единой модели, статус проверяется по странице; comments не сортируется. */\nconst ISSUE_CAPABILITIES: IssueCapabilities = {\n list: { filters: ISSUE_FILTERS, clientSide: ['status'], sorts: ['created', 'updated', 'priority', 'title'] },\n comments: { filters: COMMENT_FILTERS, clientSide: COMMENT_FILTERS, order: ['asc', 'desc'] },\n};\n\n/** Поле сортировки единой модели → order_by GitLab; comments GitLab не сортирует, до сюда не доходит. */\nconst ORDER_BY: Readonly<Partial<Record<IssueSortField, string>>> = {\n created: 'created_at',\n updated: 'updated_at',\n priority: 'priority',\n title: 'title',\n};\n\nexport function gitlabTracker(): TrackerDefinition {\n return {\n descriptor: {\n tracker: 'gitlab',\n title: 'GitLab',\n fields: [\n { name: 'target', required: true, secret: false },\n { name: 'token', required: true, secret: true },\n { name: 'url', required: false, secret: false },\n ],\n features: { create: true, update: true, comment: true, priority: true, labels: true, assignee: false, statuses: ['open', 'in_progress', 'done'] },\n },\n create: (context) => createGitlabAdapter(context),\n origin: (connection) => new URL(baseUrl(connection.url, DEFAULT_URL)).origin,\n issues: ISSUE_CAPABILITIES,\n pulls: gitlabPulls(),\n ci: gitlabCi(),\n repo: gitlabRepo(),\n };\n}\n\nfunction createGitlabAdapter({ connection, fetch }: AdapterContext): TrackerAdapter {\n const target = requireTarget(connection.target, 'путь проекта GitLab, group/project, или его id');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target GitLab — group/project или числовой id.');\n const site = baseUrl(connection.url, DEFAULT_URL);\n const origin = new URL(site).origin;\n const root = `${site}/api/v4/projects/${encodeURIComponent(target)}/issues`;\n const headers: Record<string, string> = connection.token === undefined || connection.token === '' ? {} : { 'private-token': connection.token };\n const iid = (key: string): string => {\n if (!IID.test(key)) throw new TrackerError('unknown_issue', `В GitLab нет задачи ${key}.`);\n return key;\n };\n const currentOf = async (key: string): Promise<Issue> => issueOf((await requestJson(`${root}/${iid(key)}`, { fetch, origin, headers, missingIsIssue: true })).body);\n return {\n list: async (query) => {\n assertListQuery('Задачи GitLab', ISSUE_CAPABILITIES.list, query, ISSUE_FILTERS);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({\n state: stateFilter(query.status),\n per_page: String(query.limit),\n page: String(page),\n order_by: query.sort === undefined ? 'created_at' : (ORDER_BY[query.sort.field] ?? 'created_at'),\n sort: query.sort?.direction ?? 'desc',\n });\n if (query.labels !== undefined && query.labels.length > 0) {\n if (query.labels.some((label) => label.includes(','))) throw new TrackerError('invalid_request', 'Задачи GitLab: метка не должна содержать запятую.');\n params.set('labels', query.labels.join(','));\n }\n if (query.assignee !== undefined) params.set(query.assignee === null ? 'assignee_id' : 'assignee_username', query.assignee === null ? 'None' : query.assignee);\n if (query.author !== undefined) params.set('author_username', query.author);\n if (query.search !== undefined) params.set('search', query.search);\n if (query.createdAfter !== undefined) params.set('created_after', isoTime(query.createdAfter));\n if (query.createdBefore !== undefined) params.set('created_before', isoTime(query.createdBefore));\n if (query.updatedAfter !== undefined) params.set('updated_after', isoTime(query.updatedAfter));\n if (query.updatedBefore !== undefined) params.set('updated_before', isoTime(query.updatedBefore));\n const { body, headers: responseHeaders } = await requestJson(`${root}?${params.toString()}`, { fetch, origin, headers });\n const items = (Array.isArray(body) ? body : []).map(issueOf);\n const next = responseHeaders.get('x-next-page');\n return {\n items: query.status === undefined ? items : items.filter((issue) => query.status?.includes(issue.status.category) === true),\n ...(next === null || next === '' ? {} : { nextCursor: next }),\n };\n },\n get: currentOf,\n create: async (input) => {\n const labels = composeLabels(input.labels ?? [], input.priority, undefined);\n const body = { title: input.title, ...(input.description === undefined ? {} : { description: input.description }), ...(labels.length === 0 ? {} : { labels: labels.join(',') }) };\n return issueOf((await requestJson(root, { fetch, origin, headers, method: 'POST', body })).body);\n },\n update: async (key, patch) => {\n const current = patch.labels === undefined && patch.priority === undefined && patch.status === undefined ? undefined : await currentOf(key);\n return issueOf((await requestJson(`${root}/${iid(key)}`, { fetch, origin, headers, method: 'PUT', body: patchBody(patch, current), missingIsIssue: true })).body);\n },\n comments: async (key, query) => {\n assertCommentQuery('Комментарии GitLab', ISSUE_CAPABILITIES.comments, query);\n const page = pageOf(query.cursor);\n const params = new URLSearchParams({ sort: query.order ?? 'asc', order_by: 'created_at', per_page: String(query.limit), page: String(page) });\n const { body, headers: responseHeaders } = await requestJson(`${root}/${iid(key)}/notes?${params.toString()}`, { fetch, origin, headers, missingIsIssue: true });\n const next = responseHeaders.get('x-next-page');\n // Системные заметки («изменил метку») — не комментарии; updatedAfter сверяется с сырым updated_at заметки.\n const items = (Array.isArray(body) ? body : [])\n .filter((note) => isRecord(note) && note.system !== true && inTimeRange(toTimestamp(note.updated_at), query.updatedAfter, undefined))\n .map(commentOf);\n return { items, ...(next === null || next === '' ? {} : { nextCursor: next }) };\n },\n comment: async (key, body) => commentOf((await requestJson(`${root}/${iid(key)}/notes`, { fetch, origin, headers, method: 'POST', body: { body }, missingIsIssue: true })).body),\n };\n}\n\nfunction pageOf(cursor: string | undefined): number {\n const page = cursor === undefined ? 1 : Number(cursor);\n return Number.isInteger(page) && page >= 1 ? page : 1;\n}\n\nfunction stateFilter(status: readonly IssueStatusCategory[] | undefined): string {\n if (status === undefined) return 'all';\n if (status.every((item) => item === 'open' || item === 'in_progress')) return 'opened';\n if (status.every((item) => item === 'done' || item === 'declined')) return 'closed';\n return 'all';\n}\n\nfunction composeLabels(plain: readonly string[], priority: IssuePriority | undefined, status: IssueStatusCategory | undefined): string[] {\n const priorityLabel = priority === undefined ? undefined : priorityName(GITLAB_PRIORITY_LABELS, priority);\n return [...plain, ...(priorityLabel === undefined ? [] : [priorityLabel]), ...(status === 'in_progress' ? [GITLAB_IN_PROGRESS_LABEL] : [])];\n}\n\nfunction patchBody(patch: IssuePatchInput, current: Issue | undefined): Record<string, unknown> {\n const status = patch.status ?? current?.status.category;\n const touchesLabels = patch.labels !== undefined || patch.priority !== undefined || patch.status !== undefined;\n if (patch.status === 'declined') throw new TrackerError('invalid_request', 'В GitLab нет статуса «отклонена».');\n return {\n ...(patch.title === undefined ? {} : { title: patch.title }),\n ...(patch.description === undefined ? {} : { description: patch.description }),\n ...(patch.status === undefined ? {} : { state_event: patch.status === 'done' ? 'close' : 'reopen' }),\n ...(touchesLabels ? { labels: composeLabels(patch.labels ?? current?.labels ?? [], patch.priority ?? current?.priority, status).join(',') } : {}),\n };\n}\n\nfunction issueOf(raw: unknown): Issue {\n const item = isRecord(raw) ? raw : {};\n const names = stringList(item.labels);\n const closed = item.state === 'closed';\n const category: IssueStatusCategory = closed ? 'done' : names.includes(GITLAB_IN_PROGRESS_LABEL) ? 'in_progress' : 'open';\n const priority = names.map((name) => lookup<IssuePriority | undefined>(GITLAB_PRIORITY_LABELS, name, undefined)).find((value) => value !== undefined);\n const description = text(item.description);\n const assignees = Array.isArray(item.assignees) ? item.assignees : [];\n const first = assignees[0];\n const assignee = isRecord(first) ? text(first.username) : undefined;\n const url = text(item.web_url);\n const createdAt = toTimestamp(item.created_at);\n const updatedAt = toTimestamp(item.updated_at);\n const key = typeof item.iid === 'number' ? String(item.iid) : '?';\n return {\n key,\n title: text(item.title) ?? key,\n ...(description === undefined ? {} : { description }),\n status: { category, name: closed ? 'closed' : category === 'in_progress' ? 'in progress' : 'opened' },\n ...(priority === undefined ? {} : { priority }),\n labels: names.filter((name) => name !== GITLAB_IN_PROGRESS_LABEL && !Object.hasOwn(GITLAB_PRIORITY_LABELS, name)),\n ...(assignee === undefined ? {} : { assignee }),\n links: url === undefined ? [] : [{ url, title: 'GitLab' }],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n };\n}\n\nfunction commentOf(raw: unknown): IssueComment {\n const item = isRecord(raw) ? raw : {};\n const author = isRecord(item.author) ? text(item.author.username) : undefined;\n const createdAt = toTimestamp(item.created_at);\n return { id: typeof item.id === 'number' ? String(item.id) : '?', ...(author === undefined ? {} : { author }), body: typeof item.body === 'string' ? item.body : '', ...(createdAt === undefined ? {} : { createdAt }) };\n}\n","// Адаптер Jira библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/jira.lib.ts — дословная копия, импорт типов из среза контракта библиотеки;\n// фильтры и сортировка списков — свои (#14).\nimport type { Issue, IssueComment, IssuePriority, IssueStatusCategory } from '../contract/contract.types.ts';\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { JIRA_ISSUE_TYPE, JIRA_PRIORITIES, JIRA_PRIORITY_NAMES, JIRA_STATUS_CATEGORIES } from './mapping.const.ts';\nimport { COMMENT_FILTERS, ISSUE_FILTERS } from './tracker.const.ts';\nimport type { IssueSortField } from './tracker.const.ts';\nimport { TrackerError, assertCommentQuery, assertListQuery, inTimeRange, isRecord, lookup, quoted, requireTarget, stringList, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext, IssueCapabilities, IssuePatchInput, IssueQuery, TrackerAdapter, TrackerDefinition } from './tracker.types.ts';\n\n// Трекер Jira (D-350): проект по ключу, REST API v2 (описание — обычный текст). Есть `user` — Basic (email и\n// API-токен Cloud), нет — Bearer (персональный токен Server и Data Center). Список — `/search/jql` Cloud, на\n// 404 — классический `/search` Server с курсором `s:<startAt>`. Статус — по `statusCategory`, меняется\n// переходом (transition) в нужную категорию; «отклонена» у Jira нет. Исполнитель у Cloud — accountId, поэтому\n// только показывается.\n\nconst PROJECT_KEY = /^[A-Z][A-Z0-9_]{0,49}$/;\nconst ISSUE_KEY = /^[A-Z][A-Z0-9_]{0,49}-[1-9]\\d{0,14}$/;\nconst FIELDS = 'summary,description,status,priority,labels,assignee,created,updated';\nconst CATEGORY_JQL: Readonly<Partial<Record<IssueStatusCategory, string>>> = { open: '\"To Do\"', in_progress: '\"In Progress\"', done: 'Done' };\n\n/** Возможности списков задач Jira (#14): все фильтры — в JQL на стороне Jira, порядок комментариев asc и desc. */\nconst ISSUE_CAPABILITIES: IssueCapabilities = {\n list: { filters: ISSUE_FILTERS, clientSide: [], sorts: ['created', 'updated', 'priority', 'title'] },\n comments: { filters: COMMENT_FILTERS, clientSide: COMMENT_FILTERS, order: ['asc', 'desc'] },\n};\n\n/** Поле сортировки единой модели → поле ORDER BY JQL; без сортировки — created DESC, как раньше. */\nconst JIRA_SORT_FIELDS: Readonly<Record<Exclude<IssueSortField, 'comments'>, string>> = { created: 'created', updated: 'updated', priority: 'priority', title: 'summary' };\n\nexport function jiraTracker(): TrackerDefinition {\n return {\n descriptor: {\n tracker: 'jira',\n title: 'Jira',\n fields: [\n { name: 'url', required: true, secret: false },\n { name: 'target', required: true, secret: false },\n { name: 'user', required: false, secret: false },\n { name: 'token', required: true, secret: true },\n ],\n features: { create: true, update: true, comment: true, priority: true, labels: true, assignee: false, statuses: ['open', 'in_progress', 'done'] },\n },\n create: (context) => createJiraAdapter(context),\n origin: (connection) => new URL(siteOf(connection)).origin,\n issues: ISSUE_CAPABILITIES,\n };\n}\n\n/** Адрес сайта Jira: url подключения обязателен. */\nfunction siteOf(connection: AdapterContext['connection']): string {\n if (connection.url === undefined) throw new TrackerError('invalid_request', 'Не задан адрес Jira.');\n return baseUrl(connection.url, connection.url);\n}\n\nfunction createJiraAdapter({ connection, fetch }: AdapterContext): TrackerAdapter {\n const site = siteOf(connection);\n const project = requireTarget(connection.target, 'ключ проекта Jira, например PROJ');\n if (!PROJECT_KEY.test(project)) throw new TrackerError('invalid_request', 'target Jira — ключ проекта: заглавные буквы и цифры.');\n const origin = new URL(site).origin;\n const api = `${site}/rest/api/2`;\n const token = connection.token ?? '';\n const headers = { authorization: connection.user === undefined ? `Bearer ${token}` : `Basic ${Buffer.from(`${connection.user}:${token}`).toString('base64')}` };\n const key = (value: string): string => {\n if (!ISSUE_KEY.test(value)) throw new TrackerError('unknown_issue', `В Jira нет задачи ${value}.`);\n return value;\n };\n const toIssue = (raw: unknown): Issue => issueOf(raw, site);\n const load = async (value: string): Promise<Issue> => toIssue((await requestJson(`${api}/issue/${key(value)}?fields=${FIELDS}`, { fetch, origin, headers, missingIsIssue: true })).body);\n return {\n list: async (query) => {\n assertListQuery('Задачи Jira', ISSUE_CAPABILITIES.list, query, ISSUE_FILTERS);\n const jql = listJql(project, query);\n if (jql === undefined) return { items: [] };\n if (query.cursor?.startsWith('s:') !== true) {\n const params = new URLSearchParams({ jql, fields: FIELDS, maxResults: String(query.limit) });\n if (query.cursor !== undefined) params.set('nextPageToken', query.cursor);\n try {\n const { body } = await requestJson(`${api}/search/jql?${params.toString()}`, { fetch, origin, headers });\n const record = isRecord(body) ? body : {};\n const next = text(record.nextPageToken);\n return { items: (Array.isArray(record.issues) ? record.issues : []).map(toIssue), ...(next === undefined || record.isLast === true ? {} : { nextCursor: next }) };\n } catch (error) {\n if (!(error instanceof TrackerError) || !error.message.includes(' 404')) throw error;\n }\n }\n const startAt = query.cursor?.startsWith('s:') === true ? Number(query.cursor.slice(2)) : 0;\n const params = new URLSearchParams({ jql, fields: FIELDS, maxResults: String(query.limit), startAt: String(Number.isInteger(startAt) && startAt >= 0 ? startAt : 0) });\n const { body } = await requestJson(`${api}/search?${params.toString()}`, { fetch, origin, headers });\n const record = isRecord(body) ? body : {};\n const issues = Array.isArray(record.issues) ? record.issues : [];\n const total = typeof record.total === 'number' ? record.total : 0;\n const at = typeof record.startAt === 'number' ? record.startAt : 0;\n return { items: issues.map(toIssue), ...(at + issues.length < total && issues.length > 0 ? { nextCursor: `s:${String(at + issues.length)}` } : {}) };\n },\n get: load,\n create: async (input) => {\n const fields = {\n project: { key: project },\n summary: input.title,\n issuetype: { name: JIRA_ISSUE_TYPE },\n ...(input.description === undefined ? {} : { description: input.description }),\n ...(input.priority === undefined ? {} : { priority: { name: JIRA_PRIORITY_NAMES[input.priority] } }),\n ...(input.labels === undefined ? {} : { labels: input.labels.map((label) => label.replace(/\\s+/g, '-')) }),\n };\n const { body } = await requestJson(`${api}/issue`, { fetch, origin, headers, method: 'POST', body: { fields } });\n const created = isRecord(body) ? text(body.key) : undefined;\n if (created === undefined) throw new TrackerError('failed', 'Jira создала задачу, но не вернула её ключ.');\n return load(created);\n },\n update: async (value, patch) => {\n const fields = fieldsOf(patch);\n if (Object.keys(fields).length > 0) await requestJson(`${api}/issue/${key(value)}`, { fetch, origin, headers, method: 'PUT', body: { fields }, missingIsIssue: true });\n if (patch.status !== undefined) await transition(api, key(value), patch.status, { fetch, origin, headers });\n return load(value);\n },\n comments: async (value, query) => {\n assertCommentQuery('Комментарии Jira', ISSUE_CAPABILITIES.comments, query);\n const startAt = query.cursor === undefined ? 0 : Number(query.cursor);\n const params = new URLSearchParams({ startAt: String(Number.isInteger(startAt) && startAt >= 0 ? startAt : 0), maxResults: String(query.limit), orderBy: query.order === 'desc' ? '-created' : 'created' });\n const { body } = await requestJson(`${api}/issue/${key(value)}/comment?${params.toString()}`, { fetch, origin, headers, missingIsIssue: true });\n const record = isRecord(body) ? body : {};\n const raw = Array.isArray(record.comments) ? record.comments : [];\n // Курсор считается по сырой странице: после дофильтровки updatedAfter остаток бывает пуст, а листание продолжается (§3.2 R5).\n const items = raw.filter((item) => inTimeRange(toTimestamp(isRecord(item) ? item.updated : undefined), query.updatedAfter, undefined));\n const total = typeof record.total === 'number' ? record.total : 0;\n const at = typeof record.startAt === 'number' ? record.startAt : 0;\n return { items: items.map(commentOf), ...(at + raw.length < total && raw.length > 0 ? { nextCursor: String(at + raw.length) } : {}) };\n },\n comment: async (value, body) => commentOf((await requestJson(`${api}/issue/${key(value)}/comment`, { fetch, origin, headers, method: 'POST', body: { body }, missingIsIssue: true })).body),\n };\n}\n\n/** JQL списка (#14): project и дальше каждый фильтр через AND; undefined — статусов нет или Jira запрошенные\n * категории не знает (результат пуст, запроса нет, как раньше). */\nfunction listJql(project: string, query: IssueQuery): string | undefined {\n const clauses: string[] = [];\n if (query.status !== undefined) {\n const names = query.status.flatMap((item) => CATEGORY_JQL[item] ?? []);\n if (names.length === 0) return undefined;\n clauses.push(`statusCategory in (${names.join(', ')})`);\n }\n for (const label of query.labels ?? []) clauses.push(`labels = ${quoted(label.replace(/\\s+/g, '-'))}`);\n if (query.assignee !== undefined) clauses.push(query.assignee === null ? 'assignee is EMPTY' : `assignee = ${quoted(query.assignee)}`);\n if (query.author !== undefined) clauses.push(`reporter = ${quoted(query.author)}`);\n if (query.search !== undefined) clauses.push(`text ~ ${quoted(query.search)}`);\n if (query.createdAfter !== undefined) clauses.push(`created >= ${quoted(jiraTime(query.createdAfter, 'down'))}`);\n if (query.createdBefore !== undefined) clauses.push(`created <= ${quoted(jiraTime(query.createdBefore, 'up'))}`);\n if (query.updatedAfter !== undefined) clauses.push(`updated >= ${quoted(jiraTime(query.updatedAfter, 'down'))}`);\n if (query.updatedBefore !== undefined) clauses.push(`updated <= ${quoted(jiraTime(query.updatedBefore, 'up'))}`);\n const sort = query.sort;\n // 'comments' сюда не доходит: assertListQuery отказал раньше — в sorts Jira его нет.\n const field = (sort === undefined ? 'created' : sort.field) as Exclude<IssueSortField, 'comments'>;\n const direction = sort?.direction ?? 'desc';\n return `${[`project = ${quoted(project)}`, ...clauses].join(' AND ')} ORDER BY ${JIRA_SORT_FIELDS[field]} ${direction.toUpperCase()}`;\n}\n\n/** Время JQL: UTC, «yyyy/MM/dd HH:mm»; нижняя граница вниз к минуте, верхняя — вверх, чтобы границы были включительны (#14, R2). */\nfunction jiraTime(ms: number, outward: 'down' | 'up'): string {\n const at = new Date(outward === 'down' ? Math.floor(ms / 60000) * 60000 : Math.ceil(ms / 60000) * 60000);\n const pad = (value: number): string => String(value).padStart(2, '0');\n return `${String(at.getUTCFullYear())}/${pad(at.getUTCMonth() + 1)}/${pad(at.getUTCDate())} ${pad(at.getUTCHours())}:${pad(at.getUTCMinutes())}`;\n}\n\nfunction fieldsOf(patch: IssuePatchInput): Record<string, unknown> {\n return {\n ...(patch.title === undefined ? {} : { summary: patch.title }),\n ...(patch.description === undefined ? {} : { description: patch.description }),\n ...(patch.priority === undefined ? {} : { priority: { name: JIRA_PRIORITY_NAMES[patch.priority] } }),\n ...(patch.labels === undefined ? {} : { labels: patch.labels.map((label) => label.replace(/\\s+/g, '-')) }),\n };\n}\n\n/** Переводит задачу в категорию: берёт первый доступный переход, чей статус назначения лежит в ней. */\nasync function transition(api: string, key: string, category: IssueStatusCategory, request: { fetch: AdapterContext['fetch']; origin: string; headers: Record<string, string> }): Promise<void> {\n const { fetch, origin, headers } = request;\n const { body } = await requestJson(`${api}/issue/${key}/transitions`, { fetch, origin, headers, missingIsIssue: true });\n const list = isRecord(body) && Array.isArray(body.transitions) ? body.transitions : [];\n const match = list.find((item) => {\n if (!isRecord(item) || !isRecord(item.to) || !isRecord(item.to.statusCategory)) return false;\n return lookup<IssueStatusCategory | undefined>(JIRA_STATUS_CATEGORIES, item.to.statusCategory.key, undefined) === category;\n });\n const id = isRecord(match) ? text(match.id) : undefined;\n if (id === undefined) throw new TrackerError('invalid_request', `Из текущего статуса Jira нет перехода в категорию ${category}.`);\n await requestJson(`${api}/issue/${key}/transitions`, { fetch, origin, headers, method: 'POST', body: { transition: { id } }, missingIsIssue: true });\n}\n\nfunction issueOf(raw: unknown, site: string): Issue {\n const item = isRecord(raw) ? raw : {};\n const fields = isRecord(item.fields) ? item.fields : {};\n const status = isRecord(fields.status) ? fields.status : {};\n const category = isRecord(status.statusCategory) ? status.statusCategory.key : undefined;\n const priorityName = isRecord(fields.priority) && typeof fields.priority.name === 'string' ? fields.priority.name.toLowerCase() : undefined;\n const priority = lookup<IssuePriority | undefined>(JIRA_PRIORITIES, priorityName, undefined);\n const assignee = isRecord(fields.assignee) ? (text(fields.assignee.displayName) ?? text(fields.assignee.name)) : undefined;\n const description = text(fields.description);\n const createdAt = toTimestamp(fields.created);\n const updatedAt = toTimestamp(fields.updated);\n const key = text(item.key) ?? '?';\n return {\n key,\n title: text(fields.summary) ?? key,\n ...(description === undefined ? {} : { description }),\n status: { category: lookup(JIRA_STATUS_CATEGORIES, category, 'open'), name: text(status.name) ?? 'To Do' },\n ...(priority === undefined ? {} : { priority }),\n labels: stringList(fields.labels),\n ...(assignee === undefined ? {} : { assignee }),\n links: [{ url: `${site}/browse/${key}`, title: 'Jira' }],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n };\n}\n\nfunction commentOf(raw: unknown): IssueComment {\n const item = isRecord(raw) ? raw : {};\n const author = isRecord(item.author) ? text(item.author.displayName) : undefined;\n const createdAt = toTimestamp(item.created);\n return { id: text(item.id) ?? '?', ...(author === undefined ? {} : { author }), body: typeof item.body === 'string' ? item.body : '', ...(createdAt === undefined ? {} : { createdAt }) };\n}\n","// Локальный трекер библиотеки @smwb/onreel-git-mcp (часть E выделения, D-003).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/local.lib.ts — CRUD через функции ledger заменён на порт LocalIssueStore ядра\n// (kernel/store.types.ts): хранилище пишет потребитель (в onreel — поверх ledger), эталонная\n// реализация в памяти — в тестах библиотеки (test/helpers/tracker-fixtures.lib.ts).\n// Фильтры единой модели (#14): хранилище умеет только статус и keyset-страницы, остальные фильтры\n// адаптер проверяет по полученной странице — порт LocalIssueStore не меняется (D-003).\nimport type { Issue } from '../contract/contract.types.ts';\nimport type { LocalCommentRow, LocalIssueRow } from '../kernel/store.types.ts';\nimport { ALL_STATUSES } from './mapping.const.ts';\nimport { COMMENT_FILTERS, ISSUE_FILTERS } from './tracker.const.ts';\nimport { TrackerError, assertCommentQuery, assertListQuery, containsText, inTimeRange } from './tracker.lib.ts';\nimport type { AdapterContext, IssueCapabilities, IssueQuery, TrackerAdapter, TrackerDefinition } from './tracker.types.ts';\n\n// Локальный трекер (D-350): задачи в хранилище потребителя, без внешних сервисов. Номер задачи — её ключ.\n\nconst STATUS_NAMES = { open: 'Open', in_progress: 'In progress', done: 'Done', declined: 'Declined' } as const;\n\n/** Возможности списков локального трекера (#14, §3.6): из фильтров запроса хранилище знает только\n * статус, остальное проверяется по странице (D-004). Автора у локальной задачи нет и сортировки нет:\n * store отдаёт порядок ledger — новые первыми. */\nconst ISSUE_CAPABILITIES: IssueCapabilities = {\n list: {\n filters: ['status', 'labels', 'assignee', 'search', 'createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore'],\n clientSide: ['labels', 'assignee', 'search', 'createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore'],\n sorts: [],\n },\n comments: { filters: COMMENT_FILTERS, clientSide: COMMENT_FILTERS, order: ['asc'] },\n};\n\nexport function localTracker(): TrackerDefinition {\n return {\n descriptor: {\n tracker: 'local',\n title: 'Local',\n fields: [],\n features: { create: true, update: true, comment: true, priority: true, labels: true, assignee: true, statuses: [...ALL_STATUSES] },\n },\n issues: ISSUE_CAPABILITIES,\n create: (context) => createLocalAdapter(context),\n };\n}\n\nfunction createLocalAdapter({ store, projectId, author }: AdapterContext): TrackerAdapter {\n const number = (key: string): number => {\n if (!/^[1-9]\\d{0,14}$/.test(key)) throw new TrackerError('unknown_issue', `В локальном трекере нет задачи ${key}.`);\n return Number(key);\n };\n const mustGet = (key: string): LocalIssueRow => {\n const row = store.getLocalIssue(projectId, number(key));\n if (row === undefined) throw new TrackerError('unknown_issue', `В локальном трекере нет задачи ${key}.`);\n return row;\n };\n return {\n // list и comments async: отказ проверки запроса — rejected promise, как у остальных адаптеров.\n list: async (query) => {\n assertListQuery('Задачи Local', ISSUE_CAPABILITIES.list, query, ISSUE_FILTERS);\n const page = store.listLocalIssues(projectId, { limit: query.limit, ...(query.cursor === undefined ? {} : { cursor: query.cursor }), ...(query.status === undefined ? {} : { status: query.status }) });\n return { items: page.items.filter((row) => matchesIssueQuery(row, query)).map(toIssue), ...(page.nextCursor === undefined ? {} : { nextCursor: page.nextCursor }) };\n },\n get: (key) => Promise.resolve(toIssue(mustGet(key))),\n create: (input) => Promise.resolve(toIssue(store.createLocalIssue(projectId, input))),\n update: (key, patch) => {\n const row = store.updateLocalIssue(projectId, mustGet(key).number, patch);\n if (row === undefined) throw new TrackerError('unknown_issue', `В локальном трекере нет задачи ${key}.`);\n return Promise.resolve(toIssue(row));\n },\n comments: async (key, query) => {\n assertCommentQuery('Комментарии Local', ISSUE_CAPABILITIES.comments, query);\n const page = store.listLocalComments(projectId, mustGet(key).number, { limit: query.limit, ...(query.cursor === undefined ? {} : { cursor: query.cursor }) });\n // Локальные комментарии не правятся, поэтому updatedAfter сверяется с createdAt; порядок — только asc (§3.7 A6).\n const items = query.updatedAfter === undefined ? page.items : page.items.filter((row) => inTimeRange(row.createdAt, query.updatedAfter, undefined));\n return { items: items.map(toComment), ...(page.nextCursor === undefined ? {} : { nextCursor: page.nextCursor }) };\n },\n comment: (key, body) => Promise.resolve(toComment(store.addLocalComment(projectId, mustGet(key).number, body, author))),\n };\n}\n\n/** Фильтры единой модели, которые локальный трекер проверяет по странице (D-004): метки — все сразу (И),\n * assignee null — задачи без исполнителя, search — подстрока заголовка или описания без учёта регистра,\n * время — включительно с обеих сторон (R2, R3). */\nfunction matchesIssueQuery(row: LocalIssueRow, query: IssueQuery): boolean {\n if (query.labels !== undefined && !query.labels.every((label) => row.labels.includes(label))) return false;\n const assignee = query.assignee;\n if (assignee !== undefined && (assignee === null ? row.assignee !== undefined : row.assignee !== assignee)) return false;\n if (query.search !== undefined && !containsText([row.title, row.description], query.search)) return false;\n return inTimeRange(row.createdAt, query.createdAfter, query.createdBefore) && inTimeRange(row.updatedAt, query.updatedAfter, query.updatedBefore);\n}\n\nfunction toIssue(row: LocalIssueRow): Issue {\n return {\n key: String(row.number),\n title: row.title,\n ...(row.description === undefined ? {} : { description: row.description }),\n status: { category: row.status, name: STATUS_NAMES[row.status] },\n ...(row.priority === undefined ? {} : { priority: row.priority }),\n labels: row.labels,\n ...(row.assignee === undefined ? {} : { assignee: row.assignee }),\n links: [],\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\nfunction toComment(row: LocalCommentRow): { id: string; author?: string; body: string; createdAt: number } {\n return { id: String(row.id), ...(row.author === undefined ? {} : { author: row.author }), body: row.body, createdAt: row.createdAt };\n}\n","// Адаптер pull request-ов SourceCraft библиотеки @smwb/onreel-git-mcp — свой (#15).\n// Раздел pulls (D-005) на том же подключении, что и задачи: QL filter списка, отдельные\n// конечные точки состояний, асинхронное слияние (202 → get; failed/cancel — conflict).\nimport type { IssueComment } from '../contract/contract.types.ts';\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { redactSecretText } from '../kernel/redact.lib.ts';\nimport { SOURCECRAFT_PULL_STATUSES } from './mapping.const.ts';\nimport type { PullRequest, PullRequestSortField, PullRequestStatusCategory } from './pull.schema.ts';\nimport { pullRequestFilterSchema, pullRequestStatusCategorySchema } from './pull.schema.ts';\nimport type { MergeInput, NewPullRequestInput, PullRequestAdapter, PullRequestCapabilities, PullRequestDefinition, PullRequestQuery } from './pull.types.ts';\nimport { COMMENT_FILTERS } from './tracker.const.ts';\nimport { TrackerError, assertCommentQuery, assertListQuery, containsText, inTimeRange, isRecord, keysFor, lookup, quoted, requireTarget, stringList, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext, CommentQuery } from './tracker.types.ts';\n\nconst DEFAULT_API = 'https://api.sourcecraft.tech';\nconst TARGET = /^[\\w.-]+\\/[\\w.-]+$/;\nconst SLUG = /^[\\w-]{1,100}$/;\nconst SHA = /^[0-9a-f]{7,64}$/;\n\n/** Поля сортировки единой модели → поля sort_by SourceCraft. */\nconst PULL_SORT_FIELDS_UPSTREAM: Readonly<Record<PullRequestSortField, string>> = {\n created: 'created_at',\n updated: 'updated_at',\n title: 'title',\n};\n\n/** Возможности PR SourceCraft (§3.6): QL фильтрует статус, автора и ветки сервером; метки, поиск и время — по странице. */\nconst PULL_CAPABILITIES: PullRequestCapabilities = {\n list: {\n filters: pullRequestFilterSchema.options,\n clientSide: ['labels', 'search', 'createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore'],\n sorts: ['created', 'updated', 'title'],\n },\n comments: { filters: COMMENT_FILTERS, clientSide: COMMENT_FILTERS, order: ['asc', 'desc'] },\n create: true,\n createDraft: true,\n update: ['title', 'description', 'target'],\n statuses: ['draft', 'open', 'closed'],\n comment: true,\n merge: ['merge', 'squash', 'rebase'],\n deleteSourceOnMerge: true,\n};\n\nexport function sourcecraftPulls(): PullRequestDefinition {\n return { capabilities: PULL_CAPABILITIES, create: (context) => createPullAdapter(context) };\n}\n\nfunction createPullAdapter({ connection, fetch }: AdapterContext): PullRequestAdapter {\n const target = requireTarget(connection.target, 'org/repo репозитория SourceCraft');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target SourceCraft — org/repo.');\n const api = baseUrl(connection.url, DEFAULT_API);\n const origin = new URL(api).origin;\n const root = `${api}/repos/${target}/pulls`;\n const headers = { authorization: `Bearer ${connection.token ?? ''}` };\n const missing = (key: string): { failure: 'not_found'; message: string } => ({ failure: 'not_found', message: `В SourceCraft нет PR ${key}.` });\n const slug = (key: string): string => {\n if (!SLUG.test(key)) throw new TrackerError('not_found', `В SourceCraft нет PR ${key}.`);\n return key;\n };\n const getPull = async (key: string): Promise<PullRequest> =>\n pullOf((await requestJson(`${root}/${slug(key)}`, { fetch, origin, headers, missing: missing(key) })).body);\n return {\n list: async (query) => {\n assertListQuery('PR SourceCraft', PULL_CAPABILITIES.list, query, pullRequestFilterSchema.options);\n const status = usedStatuses(query.status);\n const params = new URLSearchParams({ page_size: String(query.limit) });\n if (query.cursor !== undefined) params.set('page_token', query.cursor);\n const filter = pullFilterOf(query, status);\n if (filter !== undefined) params.set('filter', filter);\n if (query.sort !== undefined) params.set('sort_by', `${query.sort.direction === 'asc' ? '' : '-'}${PULL_SORT_FIELDS_UPSTREAM[query.sort.field]}`);\n const { body } = await requestJson(`${root}?${params.toString()}`, { fetch, origin, headers });\n const record = isRecord(body) ? body : {};\n const pulls = (Array.isArray(record.pull_requests) ? record.pull_requests : []).map(pullOf).filter((pull) => matchesPage(pull, query));\n return { items: pulls, ...nextOf(record.next_page_token) };\n },\n get: (key) => getPull(key),\n create: async (input) => pullOf((await requestJson(root, { fetch, origin, headers, method: 'POST', body: createBody(input) })).body),\n update: async (key, patch) => {\n const id = slug(key);\n let updated: unknown;\n if (patch.title !== undefined || patch.description !== undefined || patch.target !== undefined) {\n const body = {\n ...(patch.title === undefined ? {} : { title: patch.title }),\n ...(patch.description === undefined ? {} : { description: patch.description }),\n ...(patch.target === undefined ? {} : { target_branch: patch.target }),\n };\n updated = (await requestJson(`${root}/${id}`, { fetch, origin, headers, method: 'PATCH', body, missing: missing(key) })).body;\n }\n if (patch.status !== undefined) {\n const action = statusActionOf(patch.status, (await getPull(key)).status.category);\n if (action !== undefined) await requestJson(`${root}/${id}/${action}`, { fetch, origin, headers, method: 'POST', missing: missing(key) });\n return getPull(key);\n }\n return pullOf(updated ?? (await requestJson(`${root}/${id}`, { fetch, origin, headers, missing: missing(key) })).body);\n },\n merge: async (key, input: MergeInput) => {\n const id = slug(key);\n if (input.message !== undefined) throw new TrackerError('unsupported', 'PR SourceCraft: сообщение коммита слияния не поддерживается.');\n if (input.method !== undefined && !PULL_CAPABILITIES.merge.includes(input.method)) {\n throw new TrackerError('unsupported', `PR SourceCraft: слияние способом ${input.method} не поддерживается.`);\n }\n if (input.headSha !== undefined) {\n const current = await getPull(key);\n // Проверка на клиенте, а не атомарная: push между чтением и POST /merge не отсекается; сравниваем в нижнем регистре.\n if ((current.headSha ?? '').toLowerCase() !== input.headSha.toLowerCase()) {\n throw new TrackerError('conflict', `Голова PR ${key} изменилась: ожидался ${input.headSha}, сейчас ${current.headSha ?? 'неизвестен'}.`);\n }\n }\n const { body } = await requestJson(`${root}/${id}/merge`, {\n fetch,\n origin,\n headers,\n method: 'POST',\n // squash/rebase по умолчанию наследуются из настройки репозитория — без method не шлём явно false.\n body: {\n ...(input.method === undefined ? {} : { squash: input.method === 'squash', rebase: input.method === 'rebase' }),\n ...(input.deleteSource === undefined ? {} : { delete_branch: input.deleteSource }),\n },\n missing: missing(key),\n });\n const operation = isRecord(body) ? body : {};\n if (operation.status === 'failed' || operation.status === 'cancel') {\n const errorMessage = isRecord(operation.error) ? text(operation.error.message) : undefined;\n throw new TrackerError('conflict', `Слияние PR ${key} не запущено: ${redactSecretText(errorMessage ?? String(operation.status))}.`);\n }\n return getPull(key);\n },\n comments: async (key, query: CommentQuery) => {\n const id = slug(key);\n assertCommentQuery('Комментарии PR SourceCraft', PULL_CAPABILITIES.comments, query);\n const params = new URLSearchParams({ page_size: String(query.limit) });\n if (query.cursor !== undefined) params.set('page_token', query.cursor);\n if (query.order !== undefined) params.set('sort_by', query.order === 'asc' ? 'created_at' : '-created_at');\n const { body } = await requestJson(`${root}/${id}/comments?${params.toString()}`, { fetch, origin, headers, missing: missing(key) });\n const record = isRecord(body) ? body : {};\n const rawComments = Array.isArray(record.pull_request_comments) ? record.pull_request_comments : [];\n const visible = rawComments.filter((raw) => !(isRecord(raw) && raw.is_deleted === true));\n const filtered = query.updatedAfter === undefined ? visible : visible.filter((raw) => inTimeRange(toTimestamp(isRecord(raw) ? raw.updated_at : undefined), query.updatedAfter, undefined));\n return { items: filtered.map(commentOf), ...nextOf(record.next_page_token) };\n },\n comment: async (key, body) => commentOf((await requestJson(`${root}/${slug(key)}/comments`, { fetch, origin, headers, method: 'POST', body: { body }, missing: missing(key) })).body),\n };\n}\n\n/** Тело создания PR: publish по умолчанию false у трекера — открытый PR шлём явно. */\nfunction createBody(input: NewPullRequestInput): Record<string, unknown> {\n return {\n title: input.title,\n source_branch: input.source,\n target_branch: input.target,\n ...(input.description === undefined ? {} : { description: input.description }),\n publish: input.draft !== true,\n };\n}\n\n/** Конечная точка перехода состояния из текущего; переход «в то же состояние» — без запроса. */\nfunction statusActionOf(requested: Exclude<PullRequestStatusCategory, 'merged'>, current: PullRequestStatusCategory): string | undefined {\n if (current === requested) return undefined;\n if (requested === 'draft') return 'draft';\n if (requested === 'open') return current === 'draft' ? 'publish' : 'reopen';\n return 'discard';\n}\n\n/** Статусы списка: пустой массив — без фильтра; неизвестная категория — invalid_request до запроса. */\nfunction usedStatuses(status: readonly PullRequestStatusCategory[] | undefined): readonly PullRequestStatusCategory[] | undefined {\n if (status === undefined || status.length === 0) return undefined;\n for (const item of status) {\n if (!pullRequestStatusCategorySchema.options.includes(item)) {\n throw new TrackerError('invalid_request', `PR SourceCraft: неизвестная категория статуса ${String(item)}.`);\n }\n }\n return status;\n}\n\n/** Фильтры, которые QL SourceCraft не умеет, — по полученной странице (D-004). */\nfunction matchesPage(pull: PullRequest, query: PullRequestQuery): boolean {\n if (query.labels !== undefined && !query.labels.every((label) => pull.labels.includes(label))) return false;\n if (query.search !== undefined && !containsText([pull.title, pull.description], query.search)) return false;\n return inTimeRange(pull.createdAt, query.createdAfter, query.createdBefore) && inTimeRange(pull.updatedAt, query.updatedAfter, query.updatedBefore);\n}\n\n/** QL фильтр списка PR: статус — слаги через обратную таблицу; метки, поиск и время — на странице. */\nfunction pullFilterOf(query: PullRequestQuery, status: readonly PullRequestStatusCategory[] | undefined): string | undefined {\n const clauses: string[] = [];\n if (status !== undefined) {\n const slugs = [...new Set(keysFor(SOURCECRAFT_PULL_STATUSES, status))];\n clauses.push(`status in (${slugs.join(', ')})`);\n }\n if (query.author !== undefined) clauses.push(`author_slug=${quoted(query.author)}`);\n if (query.source !== undefined) clauses.push(`source_branch=${quoted(query.source)}`);\n if (query.target !== undefined) clauses.push(`target_branch=${quoted(query.target)}`);\n return clauses.length === 0 ? undefined : clauses.join(' and ');\n}\n\n/** Токен следующей страницы; пустая строка — последняя страница. */\nfunction nextOf(token: unknown): { nextCursor?: string } {\n const value = text(token);\n return value === undefined ? {} : { nextCursor: value };\n}\n\n/** PR единой модели из ответа трекера; веб-адрес PR не подтверждён (Q9) — ссылки пустые. */\nfunction pullOf(raw: unknown): PullRequest {\n const item = isRecord(raw) ? raw : {};\n const source = isRecord(item.source) ? item.source : {};\n const target = isRecord(item.target) ? item.target : {};\n const headSha = text(source.sha);\n const description = text(item.description);\n const author = isRecord(item.author) ? text(item.author.slug) : undefined;\n const createdAt = toTimestamp(item.created_at);\n const updatedAt = toTimestamp(item.updated_at);\n const mergedAt = toTimestamp(item.merged_at);\n const closedAt = toTimestamp(item.closed_at);\n const key = text(item.slug) ?? '?';\n const statusName = text(item.status) ?? 'open';\n return {\n key,\n title: text(item.title) ?? key,\n ...(description === undefined ? {} : { description }),\n status: { category: lookup(SOURCECRAFT_PULL_STATUSES, statusName, 'open'), name: statusName },\n ...(author === undefined ? {} : { author }),\n source: text(source.ref) ?? text(item.source_branch) ?? '?',\n target: text(target.ref) ?? text(item.target_branch) ?? '?',\n ...(headSha !== undefined && SHA.test(headSha) ? { headSha } : {}),\n labels: Array.isArray(item.labels) ? stringList(item.labels.map((label) => (isRecord(label) ? label.name : undefined))) : [],\n links: [],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n ...(mergedAt === undefined ? {} : { mergedAt }),\n ...(closedAt === undefined ? {} : { closedAt }),\n };\n}\n\nfunction commentOf(raw: unknown): IssueComment {\n const item = isRecord(raw) ? raw : {};\n const author = isRecord(item.author) ? text(item.author.slug) : undefined;\n const createdAt = toTimestamp(item.created_at);\n return { id: text(item.id) ?? '?', ...(author === undefined ? {} : { author }), body: typeof item.body === 'string' ? item.body : '', ...(createdAt === undefined ? {} : { createdAt }) };\n}\n","// Адаптер репозитория SourceCraft библиотеки @smwb/onreel-git-mcp — свой (#23): раздел repo определения\n// трекера (D-005, D-008) на том же подключении, что и задачи; карточка и ветки репозитория через REST API.\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { branchFilterSchema, repoVisibilitySchema } from './repo.schema.ts';\nimport type { Branch, Repo, RepoVisibility } from './repo.schema.ts';\nimport type { RepoAdapter, RepoCapabilities, RepoDefinition } from './repo.types.ts';\nimport { TrackerError, assertListQuery, isRecord, requireTarget, text } from './tracker.lib.ts';\nimport type { AdapterContext } from './tracker.types.ts';\n\n// Карточка и ветки SourceCraft (D-008). Поиск веток фильтрует сервер (параметр filter — подстрока имени),\n// поэтому на странице он не перепроверяется. Ветка SourceCraft — имя и коммит: ни признака защиты, ни\n// признака ветки по умолчанию площадка в списке не отдаёт, ветка по умолчанию есть в карточке.\n\nconst DEFAULT_API = 'https://api.sourcecraft.tech';\nconst TARGET = /^[\\w.-]+\\/[\\w.-]+$/;\nconst SHA = /^[0-9a-f]{7,64}$/;\nconst BRANCHES_SUBJECT = 'Ветки SourceCraft';\nconst BRANCH_FILTERS = branchFilterSchema.options;\n/** Потолок `page_size` площадки: запрос больше — 400, поэтому limit сверх потолка урезается до него. */\nconst PAGE_SIZE_MAX = 100;\n\n/** Возможности раздела repo SourceCraft (#23): поиск веток — параметр сервера, сортировки нет. */\nconst CAPABILITIES: RepoCapabilities = {\n branches: { filters: BRANCH_FILTERS, clientSide: [], sorts: [] },\n};\n\nexport function sourcecraftRepo(): RepoDefinition {\n return { capabilities: CAPABILITIES, create: (context) => createSourceCraftRepoAdapter(context) };\n}\n\nfunction createSourceCraftRepoAdapter({ connection, fetch }: AdapterContext): RepoAdapter {\n const target = requireTarget(connection.target, 'org/repo репозитория SourceCraft');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target SourceCraft — org/repo.');\n const api = baseUrl(connection.url, DEFAULT_API);\n const origin = new URL(api).origin;\n const repo = `${api}/repos/${target}`;\n const headers = { authorization: `Bearer ${connection.token ?? ''}` };\n const missing = { failure: 'not_found', message: `В SourceCraft нет репозитория ${target}.` } as const;\n return {\n get: async () => repoOf((await requestJson(repo, { fetch, origin, headers, missing })).body, target),\n branches: async (query) => {\n assertListQuery(BRANCHES_SUBJECT, CAPABILITIES.branches, query, BRANCH_FILTERS);\n const params = new URLSearchParams({ page_size: String(Math.min(query.limit, PAGE_SIZE_MAX)) });\n if (query.cursor !== undefined) params.set('page_token', query.cursor);\n if (query.search !== undefined) params.set('filter', query.search);\n const { body } = await requestJson(`${repo}/branches?${params.toString()}`, { fetch, origin, headers, missing });\n const record = isRecord(body) ? body : {};\n const branches = Array.isArray(record.branches) ? record.branches : [];\n const next = text(record.next_page_token);\n return { items: branches.map(branchOf), ...(next === undefined ? {} : { nextCursor: next }) };\n },\n };\n}\n\n/** Карточка репозитория: имя — slug (поле name площадка объявила устаревшим), видимость — её же слово. */\nfunction repoOf(raw: unknown, target: string): Repo {\n const item = isRecord(raw) ? raw : {};\n const defaultBranch = text(item.default_branch);\n const description = text(item.description);\n const visibility = visibilityOf(item.visibility);\n const url = text(item.web_url);\n return {\n name: text(item.slug) ?? text(item.name) ?? target,\n ...(defaultBranch === undefined ? {} : { defaultBranch }),\n ...(description === undefined ? {} : { description }),\n ...(visibility === undefined ? {} : { visibility }),\n links: url === undefined ? [] : [{ url, title: 'SourceCraft' }],\n };\n}\n\n/** Ветка SourceCraft: sha — hash её коммита; защиты и признака ветки по умолчанию список не отдаёт. */\nfunction branchOf(raw: unknown): Branch {\n const item = isRecord(raw) ? raw : {};\n const sha = isRecord(item.commit) ? text(item.commit.hash) : undefined;\n return {\n name: text(item.name) ?? '?',\n ...(sha === undefined || !SHA.test(sha) ? {} : { sha }),\n };\n}\n\n/** Видимость единой модели: значение трекера из перечисления схемы, незнакомое — поле не заполняется. */\nfunction visibilityOf(value: unknown): RepoVisibility | undefined {\n const parsed = repoVisibilitySchema.safeParse(value);\n return parsed.success ? parsed.data : undefined;\n}\n","// Адаптер SourceCraft библиотеки @smwb/onreel-git-mcp (часть E выделения).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/sourcecraft.lib.ts — дословная копия, импорт типов из среза контракта библиотеки;\n// фильтры и сортировка списков — свои (#14): QL filter, sort_by, проверка по возможностям.\nimport type { Issue, IssueComment } from '../contract/contract.types.ts';\nimport { baseUrl, requestJson } from './http.lib.ts';\nimport { sourcecraftCi } from './sourcecraft-ci.lib.ts';\nimport { ALL_STATUSES, SOURCECRAFT_PRIORITIES, SOURCECRAFT_STATUSES, SOURCECRAFT_STATUS_FILTER, SOURCECRAFT_STATUS_SLUGS } from './mapping.const.ts';\nimport { COMMENT_FILTERS, ISSUE_FILTERS } from './tracker.const.ts';\nimport type { IssueSortField } from './tracker.const.ts';\nimport { TrackerError, assertCommentQuery, assertListQuery, inTimeRange, isRecord, isoTime, lookup, quoted, requireTarget, stringList, text, toTimestamp } from './tracker.lib.ts';\nimport type { AdapterContext, IssueCapabilities, IssuePatchInput, IssueQuery, TrackerAdapter, TrackerDefinition } from './tracker.types.ts';\nimport { sourcecraftPulls } from './sourcecraft-pull.lib.ts';\nimport { sourcecraftRepo } from './sourcecraft-repo.lib.ts';\n\n// Трекер SourceCraft (D-350): задачи репозитория `org/repo` через REST API, токен — Bearer. Исполнитель и метки\n// у SourceCraft задаются по id, а не по имени: адаптер их показывает, но не меняет.\n\nconst DEFAULT_API = 'https://api.sourcecraft.tech';\nconst DEFAULT_WEB = 'https://sourcecraft.dev';\nconst TARGET = /^[\\w.-]+\\/[\\w.-]+$/;\nconst SLUG = /^[\\w-]{1,100}$/;\n\n/** Поля сортировки единой модели → поля sort_by SourceCraft; comments адаптер не поддерживает (отказ в assertListQuery). */\nconst ISSUE_SORT_FIELDS_UPSTREAM: Readonly<Partial<Record<IssueSortField, string>>> = {\n created: 'created_at',\n updated: 'updated_at',\n priority: 'priority',\n title: 'title',\n};\n\n/** Возможности списков SourceCraft: QL фильтрует сервером; null исполнителя в списке и updatedAfter\n * комментариев проверяются по полученной странице (D-004). */\nconst ISSUE_CAPABILITIES: IssueCapabilities = {\n list: { filters: ISSUE_FILTERS, clientSide: ['assignee'], sorts: ['created', 'updated', 'priority', 'title'] },\n comments: { filters: COMMENT_FILTERS, clientSide: COMMENT_FILTERS, order: ['asc', 'desc'] },\n};\n\nexport function sourcecraftTracker(): TrackerDefinition {\n return {\n descriptor: {\n tracker: 'sourcecraft',\n title: 'SourceCraft',\n fields: [\n { name: 'target', required: true, secret: false },\n { name: 'token', required: true, secret: true },\n { name: 'url', required: false, secret: false },\n ],\n features: { create: true, update: true, comment: true, priority: true, labels: false, assignee: false, statuses: [...ALL_STATUSES] },\n },\n issues: ISSUE_CAPABILITIES,\n create: (context) => createSourceCraftAdapter(context),\n origin: (connection) => new URL(baseUrl(connection.url, DEFAULT_API)).origin,\n pulls: sourcecraftPulls(),\n ci: sourcecraftCi(),\n repo: sourcecraftRepo(),\n };\n}\n\nfunction createSourceCraftAdapter({ connection, fetch }: AdapterContext): TrackerAdapter {\n const target = requireTarget(connection.target, 'org/repo репозитория SourceCraft');\n if (!TARGET.test(target)) throw new TrackerError('invalid_request', 'target SourceCraft — org/repo.');\n const api = baseUrl(connection.url, DEFAULT_API);\n const origin = new URL(api).origin;\n const root = `${api}/repos/${target}/issues`;\n const headers = { authorization: `Bearer ${connection.token ?? ''}` };\n const web = connection.url === undefined ? `${DEFAULT_WEB}/${target}/issues` : undefined;\n const slug = (key: string): string => {\n if (!SLUG.test(key)) throw new TrackerError('unknown_issue', `В SourceCraft нет задачи ${key}.`);\n return key;\n };\n const toIssue = (raw: unknown): Issue => issueOf(raw, web);\n return {\n list: async (query) => {\n assertListQuery('Задачи SourceCraft', ISSUE_CAPABILITIES.list, query, ISSUE_FILTERS);\n const params = new URLSearchParams({ page_size: String(query.limit) });\n if (query.cursor !== undefined) params.set('page_token', query.cursor);\n const filter = issueFilterOf(query);\n if (filter !== undefined) params.set('filter', filter);\n if (query.sort !== undefined) params.set('sort_by', `${query.sort.direction === 'asc' ? '' : '-'}${issueSortFieldOf(query.sort.field)}`);\n const { body } = await requestJson(`${root}?${params.toString()}`, { fetch, origin, headers });\n const record = isRecord(body) ? body : {};\n let issues = (Array.isArray(record.issues) ? record.issues : []).map(toIssue);\n if (query.status !== undefined) issues = issues.filter((issue) => query.status?.includes(issue.status.category) === true);\n if (query.assignee === null) issues = issues.filter((issue) => issue.assignee === undefined);\n return { items: issues, ...nextOf(record.next_page_token) };\n },\n get: async (key) => toIssue((await requestJson(`${root}/${slug(key)}`, { fetch, origin, headers, missingIsIssue: true })).body),\n create: async (input) => {\n const body = { title: input.title, ...(input.description === undefined ? {} : { description: input.description }), ...(input.priority === undefined ? {} : { priority: input.priority }) };\n return toIssue((await requestJson(root, { fetch, origin, headers, method: 'POST', body })).body);\n },\n update: async (key, patch) => toIssue((await requestJson(`${root}/${slug(key)}`, { fetch, origin, headers, method: 'PATCH', body: patchBody(patch), missingIsIssue: true })).body),\n comments: async (key, query) => {\n assertCommentQuery('Комментарии SourceCraft', ISSUE_CAPABILITIES.comments, query);\n const params = new URLSearchParams({ page_size: String(query.limit) });\n if (query.cursor !== undefined) params.set('page_token', query.cursor);\n if (query.order !== undefined) params.set('sort_by', query.order === 'asc' ? 'created_at' : '-created_at');\n const { body } = await requestJson(`${root}/${slug(key)}/comments?${params.toString()}`, { fetch, origin, headers, missingIsIssue: true });\n const record = isRecord(body) ? body : {};\n const rawComments = Array.isArray(record.issue_comments) ? record.issue_comments : [];\n const filtered = query.updatedAfter === undefined ? rawComments : rawComments.filter((raw) => inTimeRange(toTimestamp(isRecord(raw) ? raw.updated_at : undefined), query.updatedAfter, undefined));\n return { items: filtered.map(commentOf), ...nextOf(record.next_page_token) };\n },\n comment: async (key, body) => commentOf((await requestJson(`${root}/${slug(key)}/comments`, { fetch, origin, headers, method: 'POST', body: { body }, missingIsIssue: true })).body),\n };\n}\n\nfunction patchBody(patch: IssuePatchInput): Record<string, unknown> {\n return {\n ...(patch.title === undefined ? {} : { title: patch.title }),\n ...(patch.description === undefined ? {} : { description: patch.description }),\n ...(patch.status === undefined ? {} : { status_slug: SOURCECRAFT_STATUS_SLUGS[patch.status] }),\n ...(patch.priority === undefined ? {} : { priority: patch.priority }),\n };\n}\n\n/** Токен следующей страницы; пустая строка — последняя страница. */\nfunction nextOf(token: unknown): { nextCursor?: string } {\n const value = text(token);\n return value === undefined ? {} : { nextCursor: value };\n}\n\n/** Поле сортировки единой модели → поле sort_by SourceCraft; неподдерживаемое поле — отказ (R-002). */\nfunction issueSortFieldOf(field: IssueSortField): string {\n const upstream = ISSUE_SORT_FIELDS_UPSTREAM[field];\n if (upstream === undefined) throw new TrackerError('unsupported', `Задачи SourceCraft: сортировка по ${field} не поддерживается.`);\n return upstream;\n}\n\n/** QL фильтр списка задач: предложения через ` and `; исполнитель null — на странице, а не в QL (assignee_id=null даёт 500). */\nfunction issueFilterOf(query: IssueQuery): string | undefined {\n const clauses: string[] = [];\n if (query.status !== undefined && query.status.length > 0) {\n const slugs = [...new Set(query.status.flatMap((category) => SOURCECRAFT_STATUS_FILTER[category]))];\n clauses.push(`status in (${slugs.join(', ')})`);\n }\n for (const label of query.labels ?? []) clauses.push(`label_slug=${quoted(label)}`);\n if (typeof query.assignee === 'string') clauses.push(`assignee_slug=${quoted(query.assignee)}`);\n if (query.author !== undefined) clauses.push(`author_slug=${quoted(query.author)}`);\n if (query.search !== undefined) clauses.push(`title=${quoted(query.search)}`);\n if (query.createdAfter !== undefined) clauses.push(`created_at>=${quoted(isoTime(query.createdAfter))}`);\n if (query.createdBefore !== undefined) clauses.push(`created_at<=${quoted(isoTime(query.createdBefore))}`);\n if (query.updatedAfter !== undefined) clauses.push(`updated_at>=${quoted(isoTime(query.updatedAfter))}`);\n if (query.updatedBefore !== undefined) clauses.push(`updated_at<=${quoted(isoTime(query.updatedBefore))}`);\n return clauses.length === 0 ? undefined : clauses.join(' and ');\n}\n\nfunction issueOf(raw: unknown, web: string | undefined): Issue {\n const item = isRecord(raw) ? raw : {};\n const status = isRecord(item.status) ? item.status : {};\n const slug = text(item.slug) ?? '?';\n const statusSlug = text(status.slug) ?? 'open';\n const priority = lookup<Issue['priority']>(SOURCECRAFT_PRIORITIES, item.priority, undefined);\n const assignee = isRecord(item.assignee) ? text(item.assignee.slug) : undefined;\n const labels = Array.isArray(item.labels) ? stringList(item.labels.map((label) => (isRecord(label) ? label.name : undefined))) : [];\n const description = text(item.description);\n const createdAt = toTimestamp(item.created_at);\n const updatedAt = toTimestamp(item.updated_at);\n return {\n key: slug,\n title: text(item.title) ?? slug,\n ...(description === undefined ? {} : { description }),\n status: { category: lookup(SOURCECRAFT_STATUSES, statusSlug, 'open'), name: text(status.name) ?? statusSlug },\n ...(priority === undefined ? {} : { priority }),\n labels,\n ...(assignee === undefined ? {} : { assignee }),\n links: web === undefined ? [] : [{ url: `${web}/${slug}`, title: 'SourceCraft' }],\n ...(createdAt === undefined ? {} : { createdAt }),\n ...(updatedAt === undefined ? {} : { updatedAt }),\n };\n}\n\nfunction commentOf(raw: unknown): IssueComment {\n const item = isRecord(raw) ? raw : {};\n const author = isRecord(item.author) ? text(item.author.slug) : undefined;\n const createdAt = toTimestamp(item.created_at);\n return { id: text(item.id) ?? '?', ...(author === undefined ? {} : { author }), body: typeof item.body === 'string' ? item.body : '', ...(createdAt === undefined ? {} : { createdAt }) };\n}\n","// Встроенные трекеры библиотеки @smwb/onreel-git-mcp (часть E выделения, R-001).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/builtin.lib.ts — дословная копия. Регистрация была побочным эффектом импорта\n// guard.lib (onreel); в библиотеке она — только явный вызов registerBuiltinTrackers(), идемпотентный.\nimport { githubTracker } from './github.lib.ts';\nimport { gitlabTracker } from './gitlab.lib.ts';\nimport { jiraTracker } from './jira.lib.ts';\nimport { localTracker } from './local.lib.ts';\nimport { registerTracker } from './registry.lib.ts';\nimport { sourcecraftTracker } from './sourcecraft.lib.ts';\n\n// Трекеры, которые библиотека поставляет сама (D-350). Новый трекер добавляется модулем с\n// `TrackerDefinition` и строкой здесь: реестр и адаптеры не меняются.\n\nlet registered = false;\n\nexport function registerBuiltinTrackers(): void {\n if (registered) return;\n registered = true;\n for (const definition of [localTracker(), sourcecraftTracker(), githubTracker(), gitlabTracker(), jiraTracker()]) registerTracker(definition);\n}\n","// Хранение токенов подключений трекеров библиотеки @smwb/onreel-git-mcp (часть E выделения, D-352).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d:\n// src/host/tracker/secrets.lib.ts — копия; шов журнала host заменён на SecretSink ядра\n// (kernel/log.types.ts): по умолчанию defaultSecretSink общего redactor'а ядра (kernel/redact.lib.ts),\n// потребитель со своим журналом подставляет свой приёмник. Регистрация секрета не обязательна\n// для работы хранилища — это подсказка для маскирования текстов ошибок и журналов.\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { defaultSecretSink } from '../kernel/redact.lib.ts';\nimport type { SecretSink } from '../kernel/log.types.ts';\nimport { TRACKER_SECRETS_FILE } from './tracker.const.ts';\nimport { isRecord } from './tracker.lib.ts';\n\n// Секреты подключений (D-352): токены по projectId в файле 0600 каталога данных потребителя. В хранилище\n// задач, ответы и журналы они не попадают: наружу идёт только признак «токен есть», а значение при чтении\n// и записи регистрируется в приёмнике секретов как известный секрет (D-194).\n\n/** Записи идут по одной: чтение-правка-запись двух подключений не затирает друг друга. */\nlet queue: Promise<unknown> = Promise.resolve();\n\nfunction exclusive<T>(task: () => Promise<T>): Promise<T> {\n const run = queue.then(task, task);\n queue = run.catch(() => undefined);\n return run;\n}\n\nasync function readAll(dataDir: string): Promise<Record<string, string>> {\n let raw: string;\n try {\n raw = await readFile(join(dataDir, TRACKER_SECRETS_FILE), 'utf8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return {};\n throw error;\n }\n const parsed: unknown = JSON.parse(raw);\n if (!isRecord(parsed)) return {};\n return Object.fromEntries(Object.entries(parsed).filter((entry): entry is [string, string] => typeof entry[1] === 'string'));\n}\n\nasync function writeAll(dataDir: string, secrets: Record<string, string>): Promise<void> {\n await mkdir(dataDir, { recursive: true, mode: 0o700 });\n const target = join(dataDir, TRACKER_SECRETS_FILE);\n const temp = `${target}.${String(process.pid)}.tmp`;\n await writeFile(temp, JSON.stringify(secrets), { mode: 0o600 });\n await rename(temp, target);\n}\n\n/** Токен проекта; undefined — не задан. Значение регистрируется в приёмнике секретов. */\nexport async function readTrackerToken(dataDir: string, projectId: string, sink: SecretSink = defaultSecretSink): Promise<string | undefined> {\n const token = (await readAll(dataDir))[projectId];\n if (token !== undefined) sink.register(token);\n return token;\n}\n\nexport function hasTrackerToken(dataDir: string, projectId: string): Promise<boolean> {\n return readAll(dataDir).then((secrets) => secrets[projectId] !== undefined);\n}\n\n/** Задаёт токен проекта; пустая строка убирает. */\nexport function writeTrackerToken(dataDir: string, projectId: string, token: string, sink: SecretSink = defaultSecretSink): Promise<void> {\n if (token !== '') sink.register(token);\n return exclusive(async () => {\n const secrets = await readAll(dataDir);\n if (token === '') delete secrets[projectId];\n else secrets[projectId] = token;\n await writeAll(dataDir, secrets);\n });\n}\n\nexport function deleteTrackerToken(dataDir: string, projectId: string, sink: SecretSink = defaultSecretSink): Promise<void> {\n return writeTrackerToken(dataDir, projectId, '', sink);\n}\n","// Помощники pull request-ов библиотеки @smwb/onreel-git-mcp — свои (#15).\nimport type { PullRequestAdapter } from './pull.types.ts';\nimport { TrackerError } from './tracker.lib.ts';\nimport type { AdapterContext, TrackerDefinition } from './tracker.types.ts';\n\n/** Адаптер PR трекера (D-005); трекер без раздела pulls — TrackerError('unsupported', 'Трекер <title> не ведёт pull request-ы.'). */\nexport function pullRequestAdapterOf(definition: TrackerDefinition, context: AdapterContext): PullRequestAdapter {\n if (definition.pulls === undefined) throw new TrackerError('unsupported', `Трекер ${definition.descriptor.title} не ведёт pull request-ы.`);\n return definition.pulls.create(context);\n}\n","// Помощники раздела репозитория библиотеки @smwb/onreel-git-mcp — свои (#23).\nimport type { RepoAdapter } from './repo.types.ts';\nimport { TrackerError } from './tracker.lib.ts';\nimport type { AdapterContext, TrackerDefinition } from './tracker.types.ts';\n\n/** Адаптер репозитория трекера (D-008); трекер без раздела repo — TrackerError('unsupported', 'Трекер <title> не ведёт репозиторий.'). */\nexport function repoAdapterOf(definition: TrackerDefinition, context: AdapterContext): RepoAdapter {\n if (definition.repo === undefined) throw new TrackerError('unsupported', `Трекер ${definition.descriptor.title} не ведёт репозиторий.`);\n return definition.repo.create(context);\n}\n"],"mappings":";;;;;;;;;;;AAQO,IAAM,qBAAqB;AAG3B,IAAM,6BAA6B;AAGnC,IAAM,yBAAyB;AAG/B,IAAM,uBAAuB;AAG7B,IAAM,uBAAuB;AAG7B,IAAM,gBAAgB,CAAC,UAAU,UAAU,YAAY,UAAU,UAAU,gBAAgB,iBAAiB,gBAAgB,eAAe;AAI3I,IAAM,oBAAoB,CAAC,WAAW,WAAW,YAAY,SAAS,UAAU;AAIhF,IAAM,kBAAkB,CAAC,cAAc;AAIvC,IAAM,4BAA+C;AAAA,EAC1D,MAAM,EAAE,SAAS,CAAC,QAAQ,GAAG,YAAY,CAAC,QAAQ,GAAG,OAAO,CAAC,EAAE;AAAA,EAC/D,UAAU,EAAE,SAAS,CAAC,GAAG,YAAY,CAAC,GAAG,OAAO,CAAC,KAAK,EAAE;AAC1D;AAGO,IAAM,uBAAuB,KAAK;AAClC,IAAM,mBAAmB,OAAO;AAEhC,IAAM,wBAAwB,KAAK,OAAO;AAE1C,IAAM,uBAAuB;AAE7B,IAAM,oBAAoB;AAE1B,IAAM,mBAAmB;AAEzB,IAAM,uBAAoD,CAAC,WAAW,UAAU,YAAY,SAAS;;;AC3CrG,IAAM,eAAN,cAA2B,MAAM;AAAA,EAC7B;AAAA,EACT,YAAY,SAAyB,SAAiB;AACpD,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,UAAU;AAAA,EACjB;AACF;AAGO,SAAS,YAAY,OAAoC;AAC9D,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,KAAK,KAAK,MAAM,KAAK;AAC3B,SAAO,OAAO,SAAS,EAAE,KAAK,MAAM,IAAI,KAAK;AAC/C;AAGO,SAAS,KAAK,OAAoC;AACvD,SAAO,OAAO,UAAU,YAAY,UAAU,KAAK,QAAQ;AAC7D;AAEO,SAAS,SAAS,OAAe,KAAqB;AAC3D,SAAO,MAAM,UAAU,MAAM,QAAQ,MAAM,MAAM,GAAG,GAAG;AACzD;AAGO,SAAS,WAAW,OAA0B;AACnD,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACnC,SAAO,CAAC,GAAG,IAAI,IAAI,MAAM,OAAO,CAAC,SAAyB,OAAO,SAAS,YAAY,SAAS,EAAE,CAAC,CAAC;AACrG;AAEO,SAAS,SAAS,OAAkD;AACzE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAGO,SAAS,OAAU,OAAoC,KAAc,UAAgB;AAC1F,SAAO,OAAO,QAAQ,YAAY,OAAO,OAAO,OAAO,GAAG,IAAK,MAAM,GAAG,IAAU;AACpF;AAEO,SAAS,cAAc,QAA4B,MAAsB;AAC9E,MAAI,WAAW,OAAW,OAAM,IAAI,aAAa,mBAAmB,0HAAgC,IAAI,GAAG;AAC3G,SAAO;AACT;AAGO,SAAS,OAAO,OAAsD,UAAmD;AAC9H,SAAO,OAAO,QAAQ,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,MAAM,UAAU,QAAQ,IAAI,CAAC;AAC1E;AAEO,SAAS,aAAa,OAAgD,UAA6C;AACxH,SAAO,OAAO,QAAQ,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,MAAM,UAAU,QAAQ,IAAI,CAAC;AAC1E;AAGO,SAAS,YAA8B,OAA8C,OAA0B;AACpH,SAAO,MAAM,OAAO,CAAC,SAAS;AAC5B,UAAM,QAAQ,MAAM,IAAI;AACxB,WAAO,UAAU,UAAa,EAAE,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW;AAAA,EAC3E,CAAC;AACH;AAQO,SAAS,gBACd,SACA,cACA,OACA,OACM;AACN,QAAM,OAAO,YAAY,OAAO,KAAK;AACrC,aAAW,QAAQ,MAAM;AACvB,QAAI,CAAC,aAAa,QAAQ,SAAS,IAAI,EAAG,OAAM,IAAI,aAAa,eAAe,GAAG,OAAO,0CAAY,IAAI,qGAAqB;AAAA,EACjI;AACA,QAAM,OAAO,MAAM;AACnB,MAAI,SAAS,UAAa,CAAC,aAAa,MAAM,SAAS,KAAK,KAAK,GAAG;AAClE,UAAM,IAAI,aAAa,eAAe,GAAG,OAAO,+EAAmB,KAAK,KAAK,qGAAqB;AAAA,EACpG;AACA,MAAI,MAAM,cAAc,UAAa,KAAK,cAAc,SAAS,KAAK,cAAc,QAAQ;AAC1F,UAAM,IAAI,aAAa,mBAAmB,GAAG,OAAO,uKAA0C;AAAA,EAChG;AAEA,QAAM,QAAS,MAAuC;AACtD,MAAI,UAAU,UAAa,EAAE,OAAO,UAAU,YAAY,OAAO,cAAc,KAAK,KAAK,SAAS,IAAI;AACpG,UAAM,IAAI,aAAa,mBAAmB,GAAG,OAAO,8FAA6B;AAAA,EACnF;AACA,aAAW,QAAQ,MAAM;AACvB,UAAM,QAAQ,MAAM,IAAI;AACxB,QAAI,aAAa,IAAI,GAAG;AACtB,UAAI,OAAO,UAAU,YAAY,EAAE,OAAO,cAAc,KAAK,KAAK,SAAS,IAAI;AAC7E,cAAM,IAAI,aAAa,mBAAmB,GAAG,OAAO,0CAAY,IAAI,2IAAkC;AAAA,MACxG;AACA;AAAA,IACF;AACA,QAAI,cAAc,IAAI,GAAG;AACvB,UAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,KAAK,CAAC,SAAS,OAAO,SAAS,YAAY,KAAK,KAAK,MAAM,EAAE,GAAG;AACjG,cAAM,IAAI,aAAa,mBAAmB,GAAG,OAAO,0CAAY,IAAI,+HAA2B;AAAA,MACjG;AACA;AAAA,IACF;AACA,QAAI,UAAU,KAAM;AACpB,QAAI,OAAO,UAAU,UAAU;AAC7B,UAAI,MAAM,KAAK,MAAM,GAAI,OAAM,IAAI,aAAa,mBAAmB,GAAG,OAAO,0CAAY,IAAI,oFAAmB;AAChH;AAAA,IACF;AACA,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,UAAI,MAAM,KAAK,CAAC,SAAS,OAAO,SAAS,YAAY,KAAK,KAAK,MAAM,EAAE,GAAG;AACxE,cAAM,IAAI,aAAa,mBAAmB,GAAG,OAAO,0CAAY,IAAI,+HAA2B;AAAA,MACjG;AACA;AAAA,IACF;AACA,UAAM,IAAI,aAAa,mBAAmB,GAAG,OAAO,0CAAY,IAAI,4IAAmC;AAAA,EACzG;AACF;AAGA,SAAS,aAAa,MAAuB;AAC3C,SAAO,KAAK,SAAS,OAAO,KAAK,KAAK,SAAS,QAAQ;AACzD;AAGA,SAAS,cAAc,MAAuB;AAC5C,SAAO,SAAS,YAAY,SAAS;AACvC;AAGO,SAAS,mBAAmB,SAAiB,cAAmC,OAA2B;AAChH,kBAAgB,SAAS,EAAE,SAAS,aAAa,SAAS,YAAY,aAAa,YAAY,OAAO,CAAC,EAAE,GAAG,OAAO,eAAe;AAClI,MAAI,MAAM,UAAU,UAAa,CAAC,aAAa,MAAM,SAAS,MAAM,KAAK,GAAG;AAC1E,UAAM,IAAI,aAAa,eAAe,GAAG,OAAO,gDAAa,MAAM,KAAK,qGAAqB;AAAA,EAC/F;AACF;AAGO,SAAS,oBAAoB,YAAkD;AACpF,SAAO,WAAW,UAAU;AAC9B;AAGO,SAAS,QAAQ,IAAoB;AAC1C,SAAO,IAAI,KAAK,EAAE,EAAE,YAAY;AAClC;AAGO,SAAS,YAAY,OAA2B,OAA2B,QAAqC;AACrH,MAAI,UAAU,UAAa,WAAW,OAAW,QAAO;AACxD,MAAI,UAAU,OAAW,QAAO;AAChC,UAAQ,UAAU,UAAa,SAAS,WAAW,WAAW,UAAa,SAAS;AACtF;AAGO,SAAS,aAAa,OAAwC,QAAyB;AAC5F,QAAM,QAAQ,OAAO,YAAY;AACjC,SAAO,MAAM,KAAK,CAAC,UAAU,UAAU,UAAa,MAAM,YAAY,EAAE,SAAS,KAAK,CAAC;AACzF;AAGO,SAAS,OAAO,OAAuB;AAC5C,SAAO,IAAI,MAAM,QAAQ,UAAU,MAAM,CAAC;AAC5C;AAGO,SAAS,QAAW,OAAoC,QAAgC;AAC7F,SAAO,OAAO,QAAQ,KAAK,EACxB,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,OAAO,SAAS,KAAK,CAAC,EAC5C,IAAI,CAAC,CAAC,GAAG,MAAM,GAAG;AACvB;;;ACvKO,IAAM,uBAAsE;AAAA,EACjF,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,WAAW;AACb;AAGO,IAAM,2BAA0E;AAAA,EACrF,MAAM;AAAA,EACN,aAAa;AAAA,EACb,MAAM;AAAA,EACN,UAAU;AACZ;AAGO,IAAM,4BAAsF;AAAA,EACjG,MAAM,CAAC,QAAQ,QAAQ;AAAA,EACvB,aAAa,CAAC,aAAa;AAAA,EAC3B,MAAM,CAAC,QAAQ;AAAA,EACf,UAAU,CAAC,YAAY,WAAW;AACpC;AAGO,IAAM,yBAAkE;AAAA,EAC7E,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,SAAS;AACX;AAGO,IAAM,yBAAwE;AAAA,EACnF,KAAK;AAAA,EACL,eAAe;AAAA,EACf,MAAM;AACR;AAGO,IAAM,kBAA2D;AAAA,EACtE,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,SAAS;AACX;AAGO,IAAM,sBAA+D;AAAA,EAC1E,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,SAAS;AACX;AAGO,IAAM,kBAAkB;AAGxB,IAAM,uBAAsE;AAAA,EACjF,WAAW;AAAA,EACX,aAAa;AAAA,EACb,WAAW;AACb;AAGO,IAAM,yBAAkE;AAAA,EAC7E,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,qBAAqB;AACvB;AAGO,IAAM,2BAA2B;AAGjC,IAAM,2BAA2B;AAGjC,IAAM,yBAAkE;AAAA,EAC7E,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,qBAAqB;AACvB;AAEO,IAAM,eAA+C,CAAC,QAAQ,eAAe,QAAQ,UAAU;AAK/F,IAAM,8BAAmF;AAAA,EAC9F,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AACV;AAGO,IAAM,sBAAsB;AAG5B,IAAM,uBAAuB;AAG7B,IAAM,4BAAiF;AAAA,EAC5F,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,WAAW;AACb;AAOO,IAAM,sBAAkE;AAAA,EAC7E,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,aAAa;AACf;AAGO,IAAM,yBAAqE;AAAA,EAChF,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,OAAO;AAAA,EACP,SAAS;AAAA,EACT,iBAAiB;AACnB;AAGO,IAAM,oBAA+D;AAAA,EAC1E,MAAM;AAAA,EACN,cAAc;AAAA,EACd,qBAAqB;AAAA,EACrB,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB,UAAU;AAAA,EACV,qBAAqB;AAAA,EACrB,cAAc;AAAA,EACd,eAAe;AACjB;AAGO,IAAM,qBAAiE;AAAA,EAC5E,SAAS;AAAA,EACT,sBAAsB;AAAA,EACtB,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,sBAAsB;AAAA,EACtB,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,SAAS;AACX;AAGO,IAAM,0BAAqE;AAAA,EAChF,MAAM;AAAA,EACN,qBAAqB;AAAA,EACrB,6BAA6B;AAAA,EAC7B,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,oCAAoC;AAAA,EACpC,SAAS;AAAA,EACT,UAAU;AAAA,EACV,iBAAiB;AACnB;AAGO,IAAM,0BAAsE;AAAA,EACjF,SAAS;AAAA,EACT,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,mBAAmB;AAAA,EACnB,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,UAAU;AAAA,EACV,UAAU;AAAA,EACV,SAAS;AACX;AAGO,IAAM,yBAAoE;AAAA,EAC/E,MAAM;AAAA,EACN,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,UAAU;AAAA,EACV,kBAAkB;AACpB;;;ACtNA,eAAsB,YAAY,KAAa,SAA6C;AAC1F,QAAM,SAAS,EAAE,QAAQ,mBAAmB;AAC5C,QAAM,EAAE,UAAU,KAAK,MAAM,IAAI,MAAM,KAAK,KAAK,SAAS,YAAY,QAAQ,kBAAkB,GAAG,QAAQ;AAAA,IACzG,QAAQ,QAAQ,UAAU;AAAA,IAC1B,SAAS,EAAE,GAAG,QAAQ,GAAI,QAAQ,SAAS,SAAY,CAAC,IAAI,EAAE,gBAAgB,mBAAmB,GAAI,GAAG,QAAQ,QAAQ;AAAA,IACxH,MAAM,QAAQ,SAAS,SAAY,SAAY,KAAK,UAAU,QAAQ,IAAI;AAAA,EAC5E,CAAC;AACD,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,SAAS,KAAK;AAAA,EAC5B,SAAS,OAAO;AACd,UAAM,YAAY,OAAO,KAAK;AAAA,EAChC;AACA,MAAI,CAAC,SAAS,GAAI,OAAM,UAAU,OAAO,UAAU,KAAK,OAAO;AAC/D,MAAI,QAAQ,GAAI,QAAO,EAAE,MAAM,QAAW,SAAS,SAAS,QAAQ;AACpE,MAAI;AACF,WAAO,EAAE,MAAM,KAAK,MAAM,GAAG,GAAc,SAAS,SAAS,QAAQ;AAAA,EACvE,QAAQ;AACN,UAAM,IAAI,aAAa,UAAU,wCAAU,OAAO,KAAK,CAAC,0DAAkB;AAAA,EAC5E;AACF;AAMA,IAAM,oBAAyC,oBAAI,IAAI,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG,CAAC;AAUhF,eAAe,KAAK,KAAa,SAAuE,QAAqB,WAAmC,OAA0D;AACxN,QAAM,OAAO,SAAS,QAAQ,UAAU,KAAK,2EAAoB;AACjE,MAAI,SAAS,KAAK,2EAAe,MAAM,KAAM,OAAM,IAAI,aAAa,mBAAmB,6EAAiB,OAAO,GAAG,CAAC,iGAA2B,OAAO,IAAI,CAAC,6GAAwB;AAClL,MAAI,UAAU;AACd,MAAI,MAAM;AACV,MAAI,OAAO;AACX,WAAS,YAAY,KAAK,aAAa,GAAG;AACxC,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,QAAQ,MAAM,SAAS,EAAE,QAAQ,IAAI,QAAQ,SAAS,IAAI,SAAS,GAAI,IAAI,SAAS,SAAY,CAAC,IAAI,EAAE,MAAM,IAAI,KAAK,GAAI,UAAU,UAAU,OAAO,CAAC;AAAA,IACzK,SAAS,OAAO;AACd,YAAM,YAAY,SAAS,KAAK;AAAA,IAClC;AACA,UAAM,SAAS,gBAAgB,UAAU,OAAO;AAChD,QAAI,WAAW,QAAW;AACxB,YAAM,SAAS,MAAM,OAAO,EAAE,MAAM,MAAM,MAAS;AACnD,YAAM,IAAI,aAAa,UAAU,wCAAU,OAAO,OAAO,CAAC,KAAK,MAAM,oFAAmB;AAAA,IAC1F;AAEA,UAAM,WAAW,kBAAkB,IAAI,SAAS,MAAM,IAAI,SAAS,QAAQ,IAAI,UAAU,IAAI;AAC7F,QAAI,aAAa,QAAQ,aAAa,GAAI,QAAO,EAAE,UAAU,KAAK,QAAQ;AAC1E,UAAM,SAAS,MAAM,OAAO,EAAE,MAAM,MAAM,MAAS;AACnD,QAAI,aAAa,qBAAsB,OAAM,IAAI,aAAa,UAAU,wCAAU,OAAO,GAAG,CAAC,0CAAY,OAAO,oBAAoB,CAAC,qGAAqB;AAC1J,UAAM,OAAO,eAAe,UAAU,OAAO;AAC7C,QAAK,SAAS,WAAW,OAAO,IAAI,WAAW,UAAY,SAAS,WAAW,OAAO,SAAS,WAAW,QAAQ,IAAI,WAAW,QAAS;AACxI,YAAM,EAAE,gBAAgB,OAAO,GAAG,QAAQ,IAAI,IAAI;AAClD,YAAM,EAAE,QAAQ,OAAO,SAAS,MAAM,OAAU;AAAA,IAClD;AACA,aAAS,IAAI,IAAI,IAAI,EAAE,WAAW;AAClC,QAAI,MAAM;AACR,UAAI,IAAI,WAAW,MAAO,OAAM,IAAI,aAAa,UAAU,wCAAU,OAAO,OAAO,CAAC,6EAAiB,IAAI,MAAM,uDAAoB,OAAO,IAAI,CAAC,6GAAwB;AACvK,YAAM,EAAE,QAAQ,OAAO,SAAS,WAAW,MAAM,OAAU;AAAA,IAC7D;AACA,cAAU;AAAA,EACZ;AACF;AAOA,SAAS,gBAAgB,UAAoB,SAAqC;AAChF,MAAI,SAAS,SAAS,iBAAkB,QAAO;AAC/C,MAAI,QAAQ,SAAS;AACrB,MAAI,CAAC,SAAS,SAAS,QAAQ,IAAI;AACjC,QAAI;AACF,cAAQ,IAAI,IAAI,SAAS,GAAG,EAAE,WAAW,IAAI,IAAI,OAAO,EAAE;AAAA,IAC5D,QAAQ;AACN,cAAQ;AAAA,IACV;AAAA,EACF;AACA,SAAO,QAAQ,uXAA+F;AAChH;AAGA,SAAS,eAAe,UAAkB,SAAyB;AACjE,MAAI;AACJ,MAAI;AACF,WAAO,IAAI,IAAI,UAAU,OAAO;AAAA,EAClC,QAAQ;AACN,UAAM,IAAI,aAAa,UAAU,wCAAU,OAAO,OAAO,CAAC,uHAA6B;AAAA,EACzF;AACA,MAAI,KAAK,aAAa,WAAW,KAAK,aAAa,SAAU,OAAM,IAAI,aAAa,UAAU,wCAAU,OAAO,OAAO,CAAC,iJAAwC;AAC/J,SAAO,KAAK;AACd;AAGA,SAAS,SAAS,OAAe,SAAyB;AACxD,MAAI;AACJ,MAAI;AACF,aAAS,IAAI,IAAI,KAAK;AAAA,EACxB,QAAQ;AACN,UAAM,IAAI,aAAa,mBAAmB,GAAG,OAAO,2BAAY;AAAA,EAClE;AACA,MAAI,OAAO,aAAa,WAAW,OAAO,aAAa,SAAU,OAAM,IAAI,aAAa,mBAAmB,GAAG,OAAO,+FAA8B;AACnJ,SAAO,OAAO;AAChB;AAGA,IAAM,sBAAsB,KAAK;AASjC,eAAsB,YAAY,KAAa,SAA6C;AAC1F,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,EAAE,OAAO,KAAK,IAAI,QAAQ;AAChC,QAAM,UAAU,QAAQ,WAAW;AACnC,MAAI,CAAC,CAAC,MAAM,OAAO,OAAO,EAAE,MAAM,CAAC,UAAU,OAAO,cAAc,KAAK,KAAK,SAAS,CAAC,GAAG;AACvF,UAAM,IAAI,aAAa,mBAAmB,uPAAoD;AAAA,EAChG;AACA,QAAM,SAAS,EAAE,QAAQ,QAAQ,UAAU,aAAa;AACxD,QAAM,EAAE,UAAU,KAAK,MAAM,IAAI,MAAM,KAAK,KAAK,SAAS,YAAY,QAAQ,QAAQ,aAAa,iBAAiB,GAAG,QAAQ;AAAA,IAC7H,QAAQ;AAAA,IACR,SAAS,EAAE,GAAG,QAAQ,GAAG,QAAQ,QAAQ;AAAA,IACzC,MAAM;AAAA,EACR,CAAC;AACD,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,OAAO,MAAM,SAAS,OAAO,UAAU,EAAE,MAAM,GAAG,OAAO,qBAAqB,MAAM,QAAQ,SAAS,oBAAoB,CAAC;AAChI,UAAM,UAAU,OAAO,UAAU,WAAW,KAAK,MAAM,GAAG,OAAO;AAAA,EACnE;AACA,QAAM,OAAO,MAAM,SAAS,OAAO,UAAU,EAAE,MAAM,OAAO,MAAM,QAAQ,CAAC;AAC3E,MAAI,QAAQ,KAAK,IAAI,KAAK,OAAO,KAAK,GAAG;AACzC,MAAI,MAAM,KAAK;AACf,MAAI,SAAS,KAAK;AAElB,QAAM,OAAO,QAAQ,IAAI,oBAAoB,MAAM,IAAI;AAGvD,QAAM,OAAO,gBAAgB,OAAO,SAAS,IAAI,CAAC;AAClD,MAAI,OAAO,KAAK,OAAO,GAAG;AACxB,aAAS,OAAO,SAAS,MAAM,OAAO,SAAS,IAAI;AACnD,aAAS;AACT,WAAO;AAAA,EACT;AACA,SAAO,EAAE,MAAM,WAAW,MAAM,GAAG,OAAO,KAAK,MAAM,KAAK,MAAM,OAAO,KAAK,OAAO,SAAS,SAAS,QAAQ;AAC/G;AASA,eAAe,SAAS,KAAa,UAAoB,QAAsG;AAC7J,QAAM,EAAE,MAAM,OAAO,MAAM,QAAQ,IAAI;AACvC,QAAM,SAAS,SAAS,MAAM,UAAU;AACxC,QAAM,OAAO,SAAS,SAAS,WAAW,KAAK,IAAI,WAAW,KAAK;AACnE,MAAI,OAAO;AACX,MAAI,QAAQ;AACZ,MAAI,WAAW,QAAW;AACxB,QAAI;AACF,iBAAS;AACP,cAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,YAAI,KAAM;AACV,cAAM,QAAQ,MAAM,SAAS,GAAG,KAAK,IAAI,GAAG,UAAU,IAAI,CAAC;AAE3D,cAAM,MAAM,MAAM,SAAS,MAAM;AACjC,cAAM,SAAS,KAAK,IAAI,GAAG,OAAO,IAAI;AACtC,YAAI,SAAS,MAAM,OAAQ,MAAK,KAAK,MAAM,SAAS,MAAM,CAAC;AAC3D,gBAAQ,MAAM;AACd,YAAI,OAAO,KAAK,KAAK,GAAG;AACtB,kBAAQ;AACR,gBAAM,OAAO,OAAO,EAAE,MAAM,MAAM,MAAS;AAC3C;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,OAAO,OAAO,EAAE,MAAM,MAAM,MAAS;AAC3C,YAAM,YAAY,KAAK,KAAK;AAAA,IAC9B;AAAA,EACF;AACA,QAAM,OAAO,KAAK,MAAM;AACxB,QAAM,QAAQ,SAAS,SAAS,OAAO,KAAK,IAAI,MAAM,OAAO,KAAK,MAAM;AACxE,SAAO,EAAE,QAAQ,MAAM,OAAO,KAAK,SAAS,SAAS,OAAO,KAAK,SAAS,MAAM,MAAM,MAAM;AAC9F;AAMA,SAAS,WAAW,UAAgC;AAClD,QAAM,SAAS,IAAI,WAAW,QAAQ;AACtC,MAAI,SAAS;AACb,MAAI,WAAW;AACf,SAAO;AAAA,IACL,KAAK,OAAO;AACV,YAAM,OAAO,WAAW;AACxB,aAAO,IAAI,MAAM,SAAS,GAAG,IAAI,GAAG,MAAM;AAC1C,gBAAU,KAAK,IAAI,MAAM,MAAM,MAAM;AACrC,UAAI,MAAM,SAAS,KAAM,YAAW;AAAA,IACtC;AAAA,IACA,MAAM,MAAM;AAAA,IACZ,OAAO,MAAM,OAAO,SAAS,GAAG,MAAM;AAAA,EACxC;AACF;AAGA,SAAS,WAAW,UAAgC;AAClD,QAAM,SAAS,IAAI,WAAW,QAAQ;AACtC,MAAI,OAAO;AACX,MAAI,SAAS;AACb,SAAO;AAAA,IACL,KAAK,OAAO;AACV,UAAI,aAAa,EAAG;AACpB,YAAM,OAAO,MAAM,SAAS,KAAK,IAAI,GAAG,MAAM,SAAS,QAAQ,CAAC;AAChE,YAAM,QAAQ,KAAK,IAAI,KAAK,QAAQ,WAAW,IAAI;AACnD,aAAO,IAAI,KAAK,SAAS,GAAG,KAAK,GAAG,IAAI;AACxC,aAAO,IAAI,KAAK,SAAS,KAAK,GAAG,CAAC;AAClC,cAAQ,OAAO,KAAK,UAAU;AAC9B,eAAS,KAAK,IAAI,UAAU,SAAS,KAAK,MAAM;AAAA,IAClD;AAAA,IACA,MAAM,MAAM;AAAA,IACZ,QAAQ;AACN,UAAI,SAAS,SAAU,QAAO,OAAO,SAAS,GAAG,MAAM;AACvD,YAAM,UAAU,IAAI,WAAW,QAAQ;AACvC,cAAQ,IAAI,OAAO,SAAS,IAAI,GAAG,CAAC;AACpC,cAAQ,IAAI,OAAO,SAAS,GAAG,IAAI,GAAG,WAAW,IAAI;AACrD,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAGA,SAAS,oBAAoB,QAA4B;AACvD,MAAI,QAAQ;AACZ,SAAO,QAAQ,KAAK,QAAQ,OAAO,YAAY,OAAO,KAAK,KAAK,KAAK,SAAU,IAAM,UAAS;AAC9F,SAAO;AACT;AAGA,SAAS,gBAAgB,QAA4B;AACnD,WAAS,OAAO,GAAG,QAAQ,KAAK,IAAI,GAAG,OAAO,MAAM,GAAG,QAAQ,GAAG;AAChE,UAAM,OAAO,OAAO,OAAO,SAAS,IAAI,KAAK;AAC7C,SAAK,OAAO,SAAU,IAAM;AAC5B,UAAM,SAAS,QAAQ,MAAO,IAAI,QAAQ,MAAO,IAAI,QAAQ,MAAO,IAAI;AACxE,WAAO,SAAS,OAAO,OAAO;AAAA,EAChC;AACA,SAAO;AACT;AAEA,SAAS,WAAW,OAA2B;AAC7C,SAAO,IAAI,YAAY,OAAO,EAAE,OAAO,KAAK;AAC9C;AAGA,SAAS,YAAY,KAAa,OAA8B;AAC9D,SAAO,IAAI,aAAa,UAAU,iBAAiB,iGAAsB,OAAO,GAAG,CAAC,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE,CAAC;AACrJ;AAOA,SAAS,UAAU,KAAa,UAAoB,KAAa,SAAuF;AACtJ,QAAM,SAAS,SAAS;AACxB,MAAI,WAAW,OAAO,QAAQ,YAAY,OAAW,QAAO,IAAI,aAAa,QAAQ,QAAQ,SAAS,QAAQ,QAAQ,OAAO;AAC7H,MAAI,WAAW,OAAO,QAAQ,mBAAmB,KAAM,QAAO,IAAI,aAAa,iBAAiB,iJAA8B;AAC9H,QAAM,SAAS,iBAAiB,IAAI,QAAQ,QAAQ,GAAG,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,sBAAsB;AAChG,QAAM,WAAW,wCAAU,OAAO,GAAG,CAAC,+CAAY,OAAO,MAAM,CAAC,GAAG,WAAW,KAAK,KAAK,KAAK,MAAM,EAAE;AACrG,MAAI,QAAQ,YAAY,SAAS,MAAM,MAAM,KAAM,QAAO,IAAI,aAAa,YAAY,QAAQ;AAC/F,QAAM,iBAAiB,WAAW,QAAQ,SAAS,QAAQ,IAAI,uBAAuB,GAAG,KAAK,MAAM,OAAO,aAAa,SAAS,QAAQ,IAAI,aAAa,GAAG,KAAK,GAAG,KAAK,IAAI,CAAC,MAAM;AACrL,MAAI,WAAW,OAAO,gBAAgB;AACpC,UAAM,QAAQ,aAAa,SAAS,OAAO;AAC3C,WAAO,IAAI,aAAa,gBAAgB,wCAAU,OAAO,GAAG,CAAC,sJAA8B,UAAU,SAAY,KAAK,yEAAkB,OAAO,KAAK,CAAC,SAAI,GAAG;AAAA,EAC9J;AACA,SAAO,IAAI,aAAa,UAAU,QAAQ;AAC5C;AAMA,SAAS,aAAa,SAAkB,MAAc,KAAK,IAAI,GAAuB;AACpF,QAAM,aAAa,aAAa,QAAQ,IAAI,aAAa,GAAG,KAAK,GAAG,GAAG;AACvE,MAAI,eAAe,OAAW,QAAO;AACrC,aAAW,QAAQ,CAAC,qBAAqB,iBAAiB,GAAG;AAC3D,UAAM,QAAQ,QAAQ,IAAI,IAAI,GAAG,KAAK;AACtC,QAAI,UAAU,UAAa,QAAQ,KAAK,KAAK,EAAG,QAAO,WAAW,OAAO,KAAK,GAAG,GAAG;AAAA,EACtF;AACA,SAAO;AACT;AAGA,SAAS,aAAa,OAA2B,KAAiC;AAChF,MAAI,UAAU,UAAa,UAAU,GAAI,QAAO;AAChD,MAAI,QAAQ,KAAK,KAAK,EAAG,QAAO,OAAO,KAAK;AAC5C,QAAM,KAAK,KAAK,MAAM,KAAK;AAC3B,SAAO,OAAO,SAAS,EAAE,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,OAAO,GAAI,CAAC,IAAI;AAC3E;AAGA,SAAS,WAAW,OAAe,KAAqB;AACtD,SAAO,SAAS,MAAgB,KAAK,IAAI,GAAG,QAAQ,KAAK,MAAM,MAAM,GAAI,CAAC,IAAI;AAChF;AAGA,SAAS,OAAO,KAAqB;AACnC,MAAI;AACF,WAAO,IAAI,IAAI,GAAG,EAAE;AAAA,EACtB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,QAAQ,OAA2B,UAA0B;AAC3E,QAAM,OAAO,SAAS,UAAU,QAAQ,QAAQ,EAAE;AAClD,MAAI;AACJ,MAAI;AACF,aAAS,IAAI,IAAI,GAAG;AAAA,EACtB,QAAQ;AACN,UAAM,IAAI,aAAa,mBAAmB,oGAAyB;AAAA,EACrE;AACA,MAAI,OAAO,aAAa,WAAW,OAAO,aAAa,SAAU,OAAM,IAAI,aAAa,mBAAmB,wKAA2C;AACtJ,SAAO;AACT;;;AC7VA,SAAS,SAAS;AAKX,IAAM,yBAAyB,EAAE,KAAK,CAAC,UAAU,WAAW,WAAW,WAAW,UAAU,YAAY,SAAS,CAAC;AAElH,IAAM,wBAAwB,EAAE,KAAK,CAAC,QAAQ,gBAAgB,UAAU,YAAY,SAAS,WAAW,OAAO,CAAC;AAChH,IAAM,oBAAoB,EAAE,KAAK,CAAC,UAAU,OAAO,OAAO,SAAS,YAAY,SAAS,eAAe,gBAAgB,iBAAiB,gBAAgB,eAAe,CAAC;AACxK,IAAM,uBAAuB,EAAE,KAAK,CAAC,WAAW,SAAS,CAAC;AAC1D,IAAM,oBAAoB,EAAE,KAAK,CAAC,UAAU,aAAa,CAAC;AAE1D,IAAM,iBAAiB,EAAE,OAAO,EAAE,UAAU,wBAAwB,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,CAAC;AAEtG,IAAM,mBAAmB,EAAE,OAAO;AAAA;AAAA,EAEvC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAC9B,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAC/B,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI,EAAE,SAAS;AAAA,EAC3C,SAAS,EAAE,QAAQ;AACrB,CAAC;AAEM,IAAM,cAAc,EAAE,OAAO;AAAA;AAAA,EAElC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA;AAAA,EAE9B,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAAA;AAAA,EAEhD,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG;AAAA,EACtD,QAAQ;AAAA,EACR,OAAO,EAAE,OAAO,EAAE,UAAU,uBAAuB,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,CAAC,EAAE,SAAS;AAAA;AAAA,EAEhG,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACzC,KAAK,EACF,OAAO,EACP,MAAM,kBAAkB,EACxB,SAAS;AAAA;AAAA,EAEZ,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA;AAAA,EAE3C,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA;AAAA,EAEjD,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA;AAAA,EAE9C,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EAC9D,OAAO,EAAE,MAAM,eAAe,EAAE,IAAI,EAAE;AAAA,EACtC,WAAW,gBAAgB,SAAS;AAAA,EACpC,WAAW,gBAAgB,SAAS;AAAA,EACpC,YAAY,gBAAgB,SAAS;AAAA,EACrC,WAAW,gBAAgB,SAAS;AACtC,CAAC;AAEM,IAAM,cAAc,EAAE,OAAO;AAAA;AAAA,EAElC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI;AAAA,EAC/B,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EACjC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA;AAAA,EAE/B,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI,EAAE,SAAS;AAAA,EAC5C,QAAQ;AAAA;AAAA,EAER,OAAO,EACJ,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,GAAG,QAAQ,eAAe,CAAC,CAAC,EACpH,IAAI,GAAI,EACR,SAAS;AAAA,EACZ,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EAC9C,OAAO,EAAE,MAAM,eAAe,EAAE,IAAI,EAAE;AAAA,EACtC,WAAW,gBAAgB,SAAS;AAAA,EACpC,WAAW,gBAAgB,SAAS;AAAA,EACpC,YAAY,gBAAgB,SAAS;AACvC,CAAC;AAEM,IAAM,cAAc,EAAE,OAAO;AAAA;AAAA,EAElC,MAAM,EAAE,OAAO,EAAE,IAAI,gBAAgB;AAAA;AAAA,EAErC,WAAW,EAAE,QAAQ;AAAA;AAAA,EAErB,UAAU,EAAE,QAAQ;AAAA;AAAA,EAEpB,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA;AAAA,EAEhD,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAChD,CAAC;;;AC3EM,SAAS,YAAY,YAA+B,SAAoC;AAC7F,MAAI,WAAW,OAAO,OAAW,OAAM,IAAI,aAAa,eAAe,wCAAU,WAAW,WAAW,KAAK,kDAAe;AAC3H,SAAO,WAAW,GAAG,OAAO,OAAO;AACrC;AAGA,IAAM,aAAa;AAMZ,SAAS,UAAU,OAAgC;AACxD,QAAM,QAAQ,MAAM,YAAY;AAChC,MAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,KAAK,QAAQ,kBAAkB;AACrE,UAAM,IAAI,aAAa,mBAAmB,gIAAsC,OAAO,gBAAgB,CAAC,GAAG;AAAA,EAC7G;AACA,QAAM,OAAO,MAAM,QAAQ;AAC3B,MAAI,SAAS,UAAU,SAAS,OAAQ,OAAM,IAAI,aAAa,mBAAmB,kIAAwC;AAC1H,MAAI,MAAM,WAAW,OAAW,QAAO,EAAE,OAAO,KAAK;AACrD,QAAM,QAAQ,WAAW,KAAK,MAAM,MAAM;AAC1C,MAAI,UAAU,MAAM;AAClB,UAAM,IAAI,aAAa,mBAAmB,oXAA4F;AAAA,EACxI;AAEA,SAAO,EAAE,OAAO,MAAM,QAAQ,QAAQ,EAAE,MAAM,OAAO,MAAM,CAAC,CAAC,GAAG,QAAQ,OAAO,MAAM,CAAC,CAAC,EAAE,EAAE;AAC7F;AAGO,SAAS,UAAU,MAAc,QAAwB;AAC9D,SAAO,KAAK,OAAO,IAAI,CAAC,IAAI,OAAO,MAAM,CAAC;AAC5C;AAWO,SAAS,MAAM,OAUZ;AACR,QAAM,UAAU,MAAM,SAAS,MAAM,MAAM;AAC3C,QAAM,SAAS,CAAC,MAAM,YAAa,MAAM,QAAQ,CAAC;AAClD,QAAM,SAAS,WAAW,MAAM,MAAM,EAAE,OAAO,MAAM,aAAa,MAAM,aAAa,CAAC,MAAM,OAAO,KAAK,QAAQ,UAAU,MAAM,IAAI,CAAC;AACrI,QAAM,QAAQ,YAAY,MAAM,MAAM,OAAO,OAAO,aAAa,OAAO,IAAI,CAAC;AAE7E,QAAMA,QAAO,SAAS,iBAAiB,KAAK,GAAG,gBAAgB;AAC/D,SAAO;AAAA,IACL,MAAAA;AAAA,IACA,WAAW,MAAM;AAAA,IACjB,UAAU,MAAM;AAAA,IAChB,GAAI,SAAS,EAAE,YAAY,UAAU,MAAM,MAAM,MAAM,MAAM,OAAO,IAAI,EAAE,IAAI,CAAC;AAAA,IAC/E,GAAI,MAAM,SAAS,SAAY,CAAC,IAAI,EAAE,MAAM,MAAM,KAAK;AAAA,EACzD;AACF;AAQA,IAAM,YAAY;AAClB,IAAM,UAAU;AAGhB,IAAM,sBAAsB;AAE5B,IAAM,YAAY;AAElB,IAAM,qBAAqB;AAO3B,SAAS,WAAWA,OAAc,KAAyF;AACzH,MAAI,KAAKA,MAAK;AACd,MAAI,IAAI,KAAK;AACX,UAAM,OAAOA,MAAK,YAAY,IAAI;AAClC,SAAK,SAASA,OAAM,QAAQ,IAAI,OAAO,IAAI,QAAQA,OAAM,QAAQA,KAAI,CAAC,CAAC;AAAA,EACzE;AACA,MAAI,OAAO,OAAOA,MAAK,SAAS,IAAI,WAAWA,MAAK,MAAM,EAAE,CAAC;AAC7D,MAAI,OAAO,IAAI,UAAU;AACvB,SAAK,YAAYA,OAAM,IAAI,QAAQ;AACnC,WAAO,IAAI;AAAA,EACb;AACA,MAAI,OAAO;AACX,MAAI,IAAI,OAAO;AACb,UAAM,OAAOA,MAAK,QAAQ,IAAI;AAC9B,WAAO,KAAK,IAAI,QAAQ,IAAI,OAAO,IAAI,aAAaA,KAAI,GAAG,EAAE;AAAA,EAC/D;AACA,SAAO,EAAE,MAAMA,MAAK,MAAM,MAAM,EAAE,GAAG,KAAK;AAC5C;AAGA,SAAS,QAAQA,OAAsB;AACrC,MAAI,KAAKA,MAAK;AACd,QAAM,SAASA,MAAK,YAAY,MAAM;AACtC,MAAI,SAAS,KAAK,CAAC,oBAAoB,KAAKA,MAAK,MAAM,MAAM,CAAC,EAAG,MAAK;AACtE,MAAI,KAAK,KAAKA,MAAK,KAAK,CAAC,MAAM,KAAM,OAAM;AAC3C,SAAO;AACT;AAGA,SAAS,QAAQA,OAAc,IAAoB;AACjD,MAAI,QAAQ,KAAK;AACjB,SAAO,SAAS,KAAK,CAAC,KAAK,KAAKA,MAAK,OAAO,KAAK,CAAC,EAAG,UAAS;AAC9D,MAAI,QAAQ,EAAG,QAAO;AACtB,QAAM,OAAO,QAAQ;AACrB,QAAM,SAASA,MAAK,MAAM,KAAK,IAAI,GAAG,OAAO,kBAAkB,GAAG,IAAI;AACtE,QAAM,MAAM,UAAU,KAAK,MAAM;AACjC,QAAM,QAAQ,QAAQ,OAAO,OAAO,OAAO,OAAO,SAAS,IAAI;AAC/D,SAAO,QAAQ,IAAI,QAAQ;AAC7B;AAGA,SAAS,aAAaA,OAAsB;AAC1C,QAAM,QAAQ,MAAM,KAAKA,KAAI;AAC7B,SAAO,UAAU,OAAO,IAAI,MAAM,QAAQ,MAAM,CAAC,EAAE;AACrD;AAGA,SAAS,SAASA,OAAc,IAAoB;AAClD,QAAM,OAAOA,MAAK,MAAM,GAAG,EAAE;AAC7B,QAAM,QAAQ,CAAC,GAAG,KAAK,SAAS,SAAS,CAAC,EAAE,GAAG,EAAE;AACjD,MAAI,UAAU,UAAa,QAAQ,KAAK,KAAK,MAAM,MAAM,KAAK,CAAC,EAAG,QAAO;AACzE,QAAM,OAAO,KAAK,YAAY,MAAM,MAAM,KAAK,IAAI;AACnD,SAAO,OAAO,IAAI,OAAO,MAAM,QAAQ,IAAI,MAAM,QAAQ;AAC3D;AAMA,SAAS,YAAYA,OAAsB;AACzC,QAAM,MAAM,QAAQ,KAAKA,KAAI;AAC7B,MAAI,QAAQ,QAAQ,CAAC,GAAGA,MAAK,MAAM,GAAG,IAAI,KAAK,EAAE,SAAS,SAAS,CAAC,EAAE,WAAW,EAAG,QAAO,WAAWA,MAAK,MAAM,IAAI,QAAQ,IAAI,CAAC,EAAE,MAAM;AAC1I,MAAI,KAAK;AACT,aAAS;AACP,UAAM,OAAOA,MAAK,QAAQ,MAAM,EAAE;AAClC,QAAI,CAAC,cAAcA,MAAK,MAAM,IAAI,OAAO,IAAIA,MAAK,SAAS,IAAI,CAAC,EAAG;AACnE,SAAK,OAAO,IAAIA,MAAK,SAAS,OAAO;AACrC,QAAI,OAAO,EAAG;AAAA,EAChB;AACA,MAAI,OAAO,EAAG,QAAOA;AACrB,SAAO,YAAYA,MAAK,KAAK,CAAC,MAAM,OAAOA,MAAK,MAAM,KAAK,CAAC,IAAI;AAClE;AAGA,SAAS,cAAc,MAAuB;AAC5C,QAAM,OAAO,KAAK,SAAS,IAAI,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI;AACvD,SAAO,+BAA+B,KAAK,IAAI,KAAK,QAAQ,KAAK,IAAI,KAAK,QAAQ,KAAK,IAAI,KAAK,KAAK,KAAK,IAAI;AAChH;AAEA,IAAM,OAAO,IAAI,YAAY;AAE7B,SAAS,WAAWA,OAAsB;AACxC,SAAO,KAAK,OAAOA,KAAI,EAAE;AAC3B;AAGA,SAAS,YAAYA,OAAc,OAAuB;AACxD,MAAI,QAAQA,MAAK;AACjB,MAAI,QAAQ;AACZ,SAAO,QAAQ,KAAK,QAAQ,OAAO;AACjC,UAAM,MAAMA,MAAK,WAAW,QAAQ,CAAC;AACrC,UAAM,OAAO,QAAQ,KAAK,OAAO,SAAU,OAAO,SAAUA,MAAK,WAAW,QAAQ,CAAC,KAAK,SAAUA,MAAK,WAAW,QAAQ,CAAC,KAAK;AAClI,aAAS,WAAWA,MAAK,MAAM,SAAS,OAAO,IAAI,IAAI,KAAK,CAAC;AAC7D,aAAS,OAAO,IAAI;AAAA,EACtB;AACA,SAAO;AACT;AAKA,IAAM,gBAAgB;AAEtB,IAAM,wBAAwB;AAGvB,SAAS,aAAaA,OAAsB;AACjD,QAAM,QAAQA,MAAK,QAAQ,eAAe,EAAE,EAAE,QAAQ,uBAAuB,EAAE,EAAE,QAAQ,UAAU,IAAI;AACvG,MAAI,CAAC,MAAM,SAAS,IAAI,EAAG,QAAO;AAElC,SAAO,MACJ,MAAM,IAAI,EACV,IAAI,CAAC,SAAU,KAAK,SAAS,IAAI,IAAK,KAAK,MAAM,IAAI,EAAE,SAAS,CAAC,SAAS,SAAS,EAAE,KAAK,KAAM,IAAK,EACrG,KAAK,IAAI;AACd;AAGO,SAAS,WAAW,UAAqC;AAC9D,SAAO,qBAAqB,SAAS,QAAQ;AAC/C;;;AC1MA,IAAM,cAAc;AACpB,IAAM,SAAS;AACf,IAAM,KAAK;AACX,IAAM,MAAM;AAEZ,IAAM,sBAAsB;AAG5B,IAAM,cAAc,kBAAkB;AACtC,IAAM,cAAc,kBAAkB;AAEtC,IAAM,eAAe;AACrB,IAAM,eAAe;AACrB,IAAM,oBAAoB;AAC1B,IAAM,kBAAkB;AAGxB,IAAM,eAA+B;AAAA,EACnC,WAAW;AAAA,EACX,MAAM,EAAE,SAAS,aAAa,YAAY,CAAC,UAAU,SAAS,gBAAgB,eAAe,GAAG,OAAO,CAAC,EAAE;AAAA,EAC1G,MAAM,EAAE,SAAS,aAAa,YAAY,CAAC,QAAQ,GAAG,OAAO,CAAC,EAAE;AAAA,EAChE,KAAK,EAAE,MAAM,OAAO,QAAQ,KAAK;AAAA,EACjC,SAAS,EAAE,WAAW,MAAM,WAAW,OAAO,QAAQ,MAAM,MAAM,KAAK;AAAA,EACvE,OAAO,EAAE,KAAK,MAAM,YAAY,MAAM,KAAK,MAAM,OAAO,KAAK;AAAA,EAC7D,QAAQ,EAAE,KAAK,MAAM,KAAK,MAAM;AAClC;AAEO,SAAS,WAAyB;AACvC,SAAO,EAAE,cAAc,cAAc,QAAQ,CAAC,YAAY,sBAAsB,OAAO,EAAE;AAC3F;AAEA,SAAS,sBAAsB,EAAE,YAAY,MAAM,GAA8B;AAC/E,QAAM,SAAS,cAAc,WAAW,QAAQ,sFAA+B;AAC/E,MAAI,CAAC,OAAO,KAAK,MAAM,EAAG,OAAM,IAAI,aAAa,mBAAmB,kCAA6B;AACjG,QAAM,MAAM,QAAQ,WAAW,KAAK,WAAW;AAC/C,QAAM,SAAS,IAAI,IAAI,GAAG,EAAE;AAC5B,QAAM,OAAO,GAAG,GAAG,UAAU,MAAM;AACnC,QAAM,UAAU,GAAG,IAAI;AACvB,QAAM,UAAU;AAAA,IACd,QAAQ;AAAA,IACR,wBAAwB;AAAA,IACxB,GAAI,WAAW,UAAU,UAAa,WAAW,UAAU,KAAK,CAAC,IAAI,EAAE,eAAe,UAAU,WAAW,KAAK,GAAG;AAAA,EACrH;AACA,QAAM,SAAS,CAAC,QAAwB;AACtC,QAAI,CAAC,GAAG,KAAK,GAAG,EAAG,OAAM,IAAI,aAAa,aAAa,+EAAwB,GAAG,GAAG;AACrF,WAAO;AAAA,EACT;AACA,QAAM,SAAS,CAAC,QAAwB;AACtC,QAAI,CAAC,GAAG,KAAK,GAAG,EAAG,OAAM,IAAI,aAAa,aAAa,+EAAwB,GAAG,GAAG;AACrF,WAAO;AAAA,EACT;AACA,QAAM,aAAa,CAAC,SAA4D,EAAE,SAAS,aAAa,SAAS,+EAAwB,GAAG,IAAI;AAChJ,QAAM,aAAa,CAAC,SAA4D,EAAE,SAAS,aAAa,SAAS,+EAAwB,GAAG,IAAI;AAChJ,QAAM,SAAS,OAAO,QAAgC,OAAO,MAAM,YAAY,GAAG,OAAO,SAAS,OAAO,GAAG,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,WAAW,GAAG,EAAE,CAAC,GAAG,IAAI;AAK5K,QAAM,YAAY,OAAO,UAAmD;AAC1E,QAAI,MAAM,gBAAgB,OAAW,QAAO,MAAM;AAClD,QAAI,MAAM,QAAQ,OAAW,OAAM,IAAI,aAAa,mBAAmB,GAAG,YAAY,iUAAiF;AACvK,UAAM,OAAO,MAAM;AACnB,QAAI,CAAC,GAAG,KAAK,IAAI,EAAG,OAAM,IAAI,aAAa,aAAa,iDAA6B,IAAI,GAAG;AAC5F,UAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,IAAI,UAAU,IAAI,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,EAAE,SAAS,aAAa,SAAS,iDAA6B,IAAI,IAAI,EAAE,CAAC;AACxK,UAAM,OAAO,SAAS,IAAI,KAAK,SAAS,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,GAAG,IAAI;AAC3E,QAAI,SAAS,OAAW,OAAM,IAAI,aAAa,UAAU,6GAAuC;AAChG,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,eAAe,OAAO,UAAU;AAC9B,sBAAgB,mBAAmB,EAAE,SAAS,CAAC,GAAG,YAAY,CAAC,GAAG,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC;AACxF,YAAM,OAAO,OAAO,MAAM,MAAM;AAChC,YAAM,SAAS,IAAI,gBAAgB,EAAE,UAAU,OAAO,MAAM,KAAK,GAAG,MAAM,OAAO,IAAI,EAAE,CAAC;AACxF,YAAM,EAAE,MAAM,SAAS,gBAAgB,IAAI,MAAM,YAAY,GAAG,OAAO,cAAc,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,QAAQ,CAAC;AACpI,aAAO,EAAE,OAAO,OAAO,MAAM,WAAW,EAAE,IAAI,UAAU,GAAG,GAAG,aAAa,MAAM,gBAAgB,IAAI,MAAM,KAAK,EAAE,EAAE;AAAA,IACtH;AAAA,IACA,UAAU,OAAO,UAAU;AACzB,sBAAgB,cAAc,aAAa,MAAM,OAAO,WAAW;AACnE,YAAM,OAAO,OAAO,MAAM,MAAM;AAChC,YAAM,MAAM,MAAM,UAAU,KAAK;AACjC,YAAM,SAAS,IAAI,gBAAgB,EAAE,UAAU,OAAO,MAAM,KAAK,GAAG,MAAM,OAAO,IAAI,EAAE,CAAC;AACxF,UAAI,MAAM,QAAQ,OAAW,QAAO,IAAI,UAAU,MAAM,GAAG;AAC3D,UAAI,QAAQ,OAAW,QAAO,IAAI,YAAY,GAAG;AACjD,UAAI,MAAM,UAAU,OAAW,QAAO,IAAI,SAAS,MAAM,KAAK;AAC9D,YAAM,SAAS,YAAY,MAAM,MAAM;AACvC,UAAI,WAAW,OAAW,QAAO,IAAI,UAAU,MAAM;AACrD,YAAM,QAAQ,WAAW,MAAM,KAAK;AACpC,UAAI,UAAU,OAAW,QAAO,IAAI,SAAS,KAAK;AAClD,YAAM,UAAU,aAAa,KAAK;AAClC,UAAI,YAAY,OAAW,QAAO,IAAI,WAAW,OAAO;AAExD,YAAM,OAAO,MAAM,aAAa,SAAY,GAAG,OAAO,UAAU,GAAG,OAAO,cAAc,mBAAmB,MAAM,QAAQ,CAAC;AAC1H,YAAM,EAAE,MAAM,SAAS,gBAAgB,IAAI,MAAM,YAAY,GAAG,IAAI,IAAI,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,QAAQ,CAAC;AACvH,YAAM,QAAQ,OAAO,MAAM,eAAe,EACvC,IAAI,KAAK,EACT;AAAA,QAAO,CAAC,SACN,MAAM,WAAW,UAAa,MAAM,OAAO,SAAS,IAAI,OAAO,QAAQ,OACvE,MAAM,UAAU,UAAc,IAAI,UAAU,UAAa,MAAM,MAAM,SAAS,IAAI,MAAM,QAAQ,MACjG,YAAY,IAAI,WAAW,MAAM,cAAc,MAAM,aAAa;AAAA,MACpE;AACF,aAAO,EAAE,OAAO,GAAG,aAAa,MAAM,gBAAgB,IAAI,MAAM,KAAK,EAAE,EAAE;AAAA,IAC3E;AAAA,IACA;AAAA,IACA,UAAU,OAAO,KAAK,UAAU;AAC9B,YAAM,MAAM,OAAO,GAAG;AAEtB,YAAM,EAAE,aAAa,GAAG,KAAK,IAAI;AACjC,sBAAgB,cAAc,aAAa,MAAM,MAAM,WAAW;AAClE,YAAM,OAAO,OAAO,MAAM,MAAM;AAChC,YAAM,SAAS,IAAI,gBAAgB,EAAE,UAAU,OAAO,MAAM,KAAK,GAAG,MAAM,OAAO,IAAI,GAAG,QAAQ,gBAAgB,OAAO,QAAQ,SAAS,CAAC;AACzI,YAAM,EAAE,MAAM,SAAS,gBAAgB,IAAI,MAAM,YAAY,GAAG,OAAO,SAAS,GAAG,SAAS,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,WAAW,GAAG,EAAE,CAAC;AACrK,YAAM,QAAQ,OAAO,MAAM,MAAM,EAC9B,IAAI,KAAK,EACT,OAAO,CAAC,QAAQ,MAAM,WAAW,UAAa,MAAM,OAAO,SAAS,IAAI,OAAO,QAAQ,CAAC;AAC3F,aAAO,EAAE,OAAO,GAAG,aAAa,MAAM,gBAAgB,IAAI,MAAM,KAAK,EAAE,EAAE;AAAA,IAC3E;AAAA,IACA,QAAQ,OAAO,QAAQ;AACrB,YAAM,KAAK,OAAO,GAAG;AACrB,aAAO,OAAO,MAAM,YAAY,GAAG,OAAO,SAAS,EAAE,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,WAAW,EAAE,EAAE,CAAC,GAAG,IAAI;AAAA,IACrH;AAAA,IACA,KAAK,OAAO,KAAK,UAAU;AACzB,YAAM,KAAK,OAAO,GAAG;AACrB,YAAM,SAAS,UAAU,KAAK;AAC9B,YAAM,OAAO,MAAM,YAAY,GAAG,OAAO,SAAS,EAAE,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,WAAW,EAAE,EAAE,CAAC,GAAG;AAC9G,YAAM,WAAW,WAAW,SAAS,SAAS,GAAG,IAAI,MAAM,CAAC,CAAC,EAAE,QAAQ;AAEvE,UAAI,CAAC,SAAU,QAAO,EAAE,MAAM,IAAI,WAAW,OAAO,UAAU,OAAO,YAAY,UAAU,GAAG,CAAC,EAAE;AAEjG,YAAM,WAAW,MAAM,YAAY,GAAG,OAAO,SAAS,EAAE,SAAS;AAAA,QAC/D;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM,OAAO,QAAQ,UAAU;AAAA,QAC/B,MAAM,EAAE,OAAO,OAAO,OAAO,MAAM,OAAO,KAAK;AAAA,QAC/C,SAAS,WAAW,EAAE;AAAA,MACxB,CAAC;AACD,aAAO,MAAM;AAAA,QACX,MAAM,SAAS;AAAA,QACf,WAAW,OAAO,SAAS,SAAS,SAAS,QAAQ,IAAI,CAAC,SAAS;AAAA,QACnE;AAAA,QACA,MAAM;AAAA,QACN,KAAK,SAAS;AAAA;AAAA,QAEd,MAAM,OAAO,SAAS,UAAU,CAAC,SAAS;AAAA,QAC1C,GAAI,SAAS,QAAQ,EAAE,MAAM,SAAS,KAAK,IAAI,CAAC;AAAA,QAChD,KAAK,MAAM,OAAO;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,IACA,SAAS,OAAO,UAAU;AACxB,YAAM,YAAY,MAAM,aAAa,CAAC;AACtC,YAAM,WAAW,UAAU,CAAC;AAC5B,UAAI,UAAU,WAAW,KAAK,aAAa,QAAW;AACpD,cAAM,IAAI,aAAa,mBAAmB,GAAG,eAAe,mLAAiD;AAAA,MAC/G;AACA,YAAM,SAAS,MAAM,UAAU,CAAC;AAChC,YAAM,QAAQ,OAAO,KAAK,MAAM,EAAE;AAClC,UAAI,QAAQ,oBAAqB,OAAM,IAAI,aAAa,mBAAmB,GAAG,eAAe,gIAA2C,OAAO,mBAAmB,CAAC,gEAAc;AACjL,YAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,OAAO,cAAc,mBAAmB,QAAQ,CAAC,eAAe;AAAA,QACpG;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR,MAAM,EAAE,KAAK,MAAM,KAAK,GAAI,UAAU,IAAI,CAAC,IAAI,EAAE,OAAO,GAAI,oBAAoB,KAAK;AAAA,MACvF,CAAC;AAED,YAAM,MAAM,QAAQ,SAAS,IAAI,IAAI,KAAK,kBAAkB,MAAS;AACrE,aAAO,QAAQ,SAAY,CAAC,IAAI,EAAE,KAAK,MAAM,OAAO,GAAG,EAAE;AAAA,IAC3D;AAAA,IACA,OAAO,OAAO,KAAK,UAAU;AAC3B,YAAM,MAAM,OAAO,GAAG;AAEtB,YAAM,YAAY,GAAG,OAAO,SAAS,GAAG,IAAI,MAAM,eAAe,OAAO,sBAAsB,OAAO,IAAI;AAAA,QACvG;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR,MAAM,EAAE,sBAAsB,MAAM,UAAU,KAAK;AAAA,QACnD,SAAS,WAAW,GAAG;AAAA,MACzB,CAAC;AACD,aAAO,OAAO,GAAG;AAAA,IACnB;AAAA,IACA,UAAU,OAAO,KAAK,UAAU;AAC9B,YAAM,KAAK,OAAO,GAAG;AACrB,YAAM,OAAO,MAAM,YAAY,GAAG,OAAO,SAAS,EAAE,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,WAAW,EAAE,EAAE,CAAC,GAAG;AAC9G,YAAM,MAAM,QAAQ,SAAS,GAAG,IAAI,IAAI,SAAS,MAAS;AAC1D,UAAI,QAAQ,OAAW,OAAM,IAAI,aAAa,UAAU,2IAAkC;AAC1F,YAAM,YAAY,GAAG,OAAO,SAAS,EAAE,UAAU,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,MAAM,EAAE,sBAAsB,MAAM,UAAU,KAAK,GAAG,SAAS,WAAW,EAAE,EAAE,CAAC;AAE1K,aAAO,OAAO,GAAG;AAAA,IACnB;AAAA,IACA,QAAQ,OAAO,QAAQ;AACrB,YAAM,MAAM,OAAO,GAAG;AACtB,YAAM,YAAY,GAAG,OAAO,SAAS,GAAG,WAAW,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,YAAY,CAAC,GAAG,GAAG,SAAS,WAAW,GAAG,EAAE,CAAC;AAC1I,aAAO,OAAO,GAAG;AAAA,IACnB;AAAA,IACA,WAAW,YAAY;AACrB,YAAM,IAAI,aAAa,eAAe,0VAA4E;AAAA,IACpH;AAAA,EACF;AACF;AAGA,SAAS,OAAO,QAAoC;AAClD,QAAM,OAAO,WAAW,SAAY,IAAI,OAAO,MAAM;AACrD,SAAO,OAAO,UAAU,IAAI,KAAK,QAAQ,IAAI,OAAO;AACtD;AAGA,SAAS,aAAa,MAAc,MAAuC;AACzE,SAAO,aAAa,KAAK,IAAI,IAAI,EAAE,YAAY,OAAO,OAAO,CAAC,EAAE,IAAI,CAAC;AACvE;AAGA,SAAS,OAAO,MAAe,OAAmC;AAChE,QAAM,OAAO,SAAS,IAAI,IAAI,KAAK,KAAK,IAAI;AAC5C,SAAO,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC;AACvC;AAGA,SAAS,MAAM,OAAwB;AACrC,MAAI,OAAO,UAAU,YAAY,OAAO,cAAc,KAAK,EAAG,QAAO,OAAO,KAAK;AACjF,SAAO,OAAO,UAAU,YAAY,UAAU,KAAK,QAAQ;AAC7D;AAGA,SAAS,YAAY,OAAoC;AACvD,SAAO,OAAO,UAAU,YAAY,OAAO,cAAc,KAAK,KAAK,QAAQ,IAAI,QAAQ;AACzF;AAGA,SAAS,QAAQ,OAAoC;AACnD,QAAM,KAAK,YAAY,KAAK;AAC5B,SAAO,OAAO,SAAY,SAAY,OAAO,EAAE;AACjD;AAMA,SAAS,SAAS,MAAyC;AACzD,QAAM,MAAM,KAAK,KAAK,MAAM,KAAK;AACjC,MAAI,QAAQ,YAAa,QAAO,EAAE,UAAU,OAAO,qBAAqB,KAAK,SAAS,GAAG,MAAM,IAAI;AACnG,QAAM,aAAa,KAAK,KAAK,UAAU;AACvC,SAAO,EAAE,UAAU,OAAO,wBAAwB,YAAY,QAAQ,GAAG,MAAM,cAAc,IAAI;AACnG;AAGA,SAAS,YAAY,QAAqE;AACxF,MAAI,WAAW,UAAa,OAAO,WAAW,EAAG,QAAO;AACxD,MAAI,OAAO,MAAM,UAAU,EAAG,QAAO;AACrC,SAAO,OAAO,WAAW,KAAK,OAAO,CAAC,MAAM,YAAY,gBAAgB;AAC1E;AAGA,SAAS,WAAW,OAAmE;AACrF,MAAI,UAAU,UAAa,MAAM,WAAW,EAAG,QAAO;AACtD,QAAM,OAAO,QAAQ,mBAAmB,KAAK;AAC7C,SAAO,KAAK,WAAW,IAAI,KAAK,CAAC,IAAI;AACvC;AAGA,SAAS,aAAa,OAAuC;AAC3D,QAAM,EAAE,cAAc,OAAO,eAAe,OAAO,IAAI;AACvD,MAAI,UAAU,UAAa,WAAW,OAAW,QAAO,GAAG,QAAQ,KAAK,CAAC,KAAK,QAAQ,MAAM,CAAC;AAC7F,MAAI,UAAU,OAAW,QAAO,KAAK,QAAQ,KAAK,CAAC;AACnD,SAAO,WAAW,SAAY,KAAK,QAAQ,MAAM,CAAC,KAAK;AACzD;AAGA,SAAS,WAAW,KAA0B;AAC5C,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,MAAM,MAAM,KAAK,EAAE;AACzB,QAAM,OAAO,KAAK,KAAK,IAAI;AAC3B,SAAO,EAAE,KAAK,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,GAAI,SAAS,SAAY,CAAC,IAAI,EAAE,KAAK,GAAI,SAAS,KAAK,UAAU,SAAS;AACxH;AAGA,SAAS,MAAM,KAAqB;AAClC,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,MAAM,MAAM,KAAK,EAAE;AACzB,QAAM,SAAS,SAAS,IAAI;AAC5B,QAAM,OAAO,KAAK,KAAK,IAAI,KAAK,KAAK,KAAK,IAAI;AAC9C,QAAM,SAAS,KAAK,KAAK,WAAW;AACpC,QAAM,MAAM,KAAK,KAAK,QAAQ;AAC9B,QAAM,QAAQ,SAAS,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,KAAK,IAAI;AAC9D,QAAM,OAAO,MAAM,QAAQ,KAAK,aAAa,IAAI,KAAK,cAAc,CAAC,IAAI;AACzE,QAAM,aAAa,SAAS,IAAI,KAAK,OAAO,KAAK,WAAW,WAAW,OAAO,KAAK,MAAM,IAAI;AAC7F,QAAM,SAAS,YAAY,KAAK,UAAU;AAC1C,QAAM,UAAU,YAAY,KAAK,WAAW;AAC5C,QAAM,MAAM,KAAK,KAAK,QAAQ;AAC9B,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,QAAM,YAAY,YAAY,KAAK,cAAc;AACjD,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,QAAM,aAAa,KAAK,KAAK,MAAM,MAAM,cAAc,YAAY;AACnE,QAAM,QAAQ,KAAK,KAAK,KAAK;AAC7B,SAAO;AAAA,IACL;AAAA,IACA,GAAI,WAAW,SAAY,CAAC,IAAI,EAAE,OAAO;AAAA,IACzC,WAAW,SAAS,SAAY,CAAC,IAAI,CAAC,IAAI;AAAA,IAC1C;AAAA,IACA,GAAI,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,OAAO,mBAAmB,OAAO,OAAO,GAAG,MAAM,MAAM,EAAE;AAAA,IAC7G,GAAI,WAAW,SAAY,CAAC,IAAI,EAAE,KAAK,OAAO;AAAA,IAC9C,GAAI,QAAQ,UAAa,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI;AAAA,IACrD,GAAI,UAAU,SAAY,CAAC,IAAI,EAAE,MAAM;AAAA,IACvC,GAAI,eAAe,SAAY,CAAC,IAAI,EAAE,aAAa,WAAW;AAAA,IAC9D,GAAI,YAAY,SAAY,CAAC,IAAI,EAAE,QAAQ;AAAA,IAC3C,OAAO,QAAQ,SAAY,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,iBAAiB,CAAC;AAAA,IACjE,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,eAAe,SAAY,CAAC,IAAI,EAAE,WAAW;AAAA,IACjD,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,EACjD;AACF;AAGA,SAAS,MAAM,KAAqB;AAClC,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,MAAM,MAAM,KAAK,EAAE;AACzB,QAAM,MAAM,KAAK,KAAK,QAAQ;AAC9B,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,QAAM,aAAa,YAAY,KAAK,YAAY;AAChD,QAAM,QAAQ,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,MAAM,IAAI,MAAM,IAAI;AACnE,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,QAAQ,KAAK,MAAM,KAAK;AAAA,IAChC,MAAM,KAAK,KAAK,IAAI,KAAK;AAAA,IACzB,QAAQ,SAAS,IAAI;AAAA,IACrB,GAAI,UAAU,SAAY,CAAC,IAAI,EAAE,MAAM;AAAA,IACvC,OAAO,QAAQ,SAAY,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,iBAAiB,CAAC;AAAA,IACjE,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,eAAe,SAAY,CAAC,IAAI,EAAE,WAAW;AAAA,EACnD;AACF;AAGA,SAAS,OAAO,KAAkE;AAChF,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,SAAS,YAAY,KAAK,MAAM,KAAK;AAC3C,SAAO,EAAE,QAAQ,MAAM,KAAK,KAAK,IAAI,KAAK,OAAO,MAAM,GAAG,QAAQ,SAAS,IAAI,EAAE;AACnF;;;ACpVA,IAAM,cAAc;AACpB,IAAMC,UAAS;AACf,IAAMC,MAAK;AAGX,IAAMC,eAAc,kBAAkB;AACtC,IAAMC,eAAc,kBAAkB;AAGtC,IAAMC,gBAA+B;AAAA,EACnC,WAAW;AAAA,EACX,MAAM,EAAE,SAASF,cAAa,YAAY,CAAC,UAAU,OAAO,GAAG,OAAO,CAAC,WAAW,SAAS,EAAE;AAAA,EAC7F,MAAM,EAAE,SAASC,cAAa,YAAY,CAAC,GAAG,OAAO,CAAC,EAAE;AAAA,EACxD,KAAK,EAAE,MAAM,MAAM,QAAQ,KAAK;AAAA,EAChC,SAAS,EAAE,WAAW,MAAM,WAAW,QAAQ,QAAQ,MAAM,MAAM,KAAK;AAAA,EACxE,OAAO,EAAE,KAAK,OAAO,YAAY,MAAM,KAAK,MAAM,OAAO,MAAM;AAAA,EAC/D,QAAQ,EAAE,KAAK,MAAM,KAAK,KAAK;AACjC;AAEO,SAAS,WAAyB;AACvC,SAAO,EAAE,cAAcC,eAAc,QAAQ,CAAC,YAAY,sBAAsB,OAAO,EAAE;AAC3F;AAEA,SAAS,sBAAsB,EAAE,YAAY,MAAM,GAA8B;AAC/E,QAAM,SAAS,cAAc,WAAW,QAAQ,qIAAgD;AAChG,MAAI,CAACJ,QAAO,KAAK,MAAM,EAAG,OAAM,IAAI,aAAa,mBAAmB,4GAAgD;AACpH,QAAM,OAAO,QAAQ,WAAW,KAAK,WAAW;AAChD,QAAM,SAAS,IAAI,IAAI,IAAI,EAAE;AAC7B,QAAM,MAAM,GAAG,IAAI;AACnB,QAAM,UAAU,GAAG,GAAG,aAAa,mBAAmB,MAAM,CAAC;AAC7D,QAAM,UAAkC,WAAW,UAAU,UAAa,WAAW,UAAU,KAAK,CAAC,IAAI,EAAE,iBAAiB,WAAW,MAAM;AAG7I,QAAM,QAAQ,CAAmB,OAAoC,eAA6D;AAChI,QAAI,eAAe,UAAa,WAAW,WAAW,EAAG,QAAO;AAChE,UAAM,OAAO,QAAQ,OAAO,UAAU;AACtC,WAAO,KAAK,WAAW,IAAI,KAAK,CAAC,IAAI;AAAA,EACvC;AACA,QAAM,cAAc,CAAC,QAAwB;AAC3C,QAAI,CAACC,IAAG,KAAK,GAAG,EAAG,OAAM,IAAI,aAAa,aAAa,+EAAwB,GAAG,GAAG;AACrF,WAAO;AAAA,EACT;AACA,QAAM,SAAS,CAAC,QAAwB;AACtC,QAAI,CAACA,IAAG,KAAK,GAAG,EAAG,OAAM,IAAI,aAAa,aAAa,+EAAwB,GAAG,GAAG;AACrF,WAAO;AAAA,EACT;AACA,QAAM,kBAAkB,CAAC,SAA4D,EAAE,SAAS,aAAa,SAAS,+EAAwB,GAAG,IAAI;AACrJ,QAAM,aAAa,CAAC,SAA4D,EAAE,SAAS,aAAa,SAAS,+EAAwB,GAAG,IAAI;AAChJ,QAAM,cAAc,OAAO,QACzBI,QAAO,MAAM,YAAY,GAAG,OAAO,cAAc,YAAY,GAAG,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,gBAAgB,GAAG,EAAE,CAAC,GAAG,IAAI;AACvI,SAAO;AAAA,IACL,eAAe,YAAY;AACzB,YAAM,IAAI,aAAa,eAAe,uIAAkD;AAAA,IAC1F;AAAA,IACA,UAAU,OAAO,UAAU;AACzB,sBAAgB,wDAAqBD,cAAa,MAAM,OAAOF,YAAW;AAC1E,YAAM,SAAS,IAAI,gBAAgB,EAAE,UAAU,OAAO,MAAM,KAAK,GAAG,MAAM,OAAOI,QAAO,MAAM,MAAM,CAAC,EAAE,CAAC;AACxG,UAAI;AACJ,UAAI;AACJ,UAAI;AACJ,UAAI,MAAM,gBAAgB,QAAW;AAGnC,cAAM,KAAK,MAAM;AACjB,YAAI,CAACL,IAAG,KAAK,EAAE,EAAG,OAAM,IAAI,aAAa,aAAa,kDAA8B,EAAE,GAAG;AACzF,YAAI,MAAM,SAAS,OAAW,OAAM,IAAI,aAAa,eAAe,wPAAoE;AACxI,YAAI,MAAM,UAAU,OAAW,OAAM,IAAI,aAAa,eAAe,sOAAsE;AAC3I,YAAI,MAAM,aAAa,OAAW,OAAM,IAAI,aAAa,eAAe,yOAAyE;AACjJ,cAAM,SAAS,MAAM,YAAY,GAAG,OAAO,mBAAmB,EAAE,cAAc,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,EAAE,SAAS,aAAa,SAAS,kDAA8B,EAAE,IAAI,EAAE,CAAC;AAC9M,eAAO,OAAO;AACd,0BAAkB,OAAO;AACzB,eAAO,CAAC,SACL,MAAM,WAAW,UAAa,MAAM,OAAO,SAAS,IAAI,OAAO,QAAQ,OACvE,MAAM,UAAU,UAAc,IAAI,UAAU,UAAa,MAAM,MAAM,SAAS,IAAI,MAAM,QAAQ,OAChG,MAAM,QAAQ,UAAa,IAAI,QAAQ,MAAM,SAC7C,MAAM,QAAQ,UAAa,IAAI,QAAQ,MAAM,QAC9C,YAAY,IAAI,WAAW,MAAM,cAAc,MAAM,aAAa,KAClE,YAAY,IAAI,WAAW,MAAM,cAAc,MAAM,aAAa;AAAA,MACtE,OAAO;AACL,YAAI,MAAM,QAAQ,OAAW,QAAO,IAAI,OAAO,MAAM,GAAG;AACxD,YAAI,MAAM,QAAQ,OAAW,QAAO,IAAI,OAAO,MAAM,GAAG;AACxD,YAAI,MAAM,UAAU,OAAW,QAAO,IAAI,YAAY,MAAM,KAAK;AACjE,YAAI,MAAM,aAAa,OAAW,QAAO,IAAI,QAAQ,MAAM,QAAQ;AACnE,YAAI,MAAM,WAAW,UAAa,MAAM,OAAO,SAAS,GAAG;AACzD,gBAAM,SAAS,MAAM,oBAAoB,MAAM,MAAM;AACrD,cAAI,WAAW,OAAW,QAAO,IAAI,UAAU,MAAM;AACrD,cAAI,WAAW,UAAa,MAAM,OAAO,MAAM,UAAU,EAAG,QAAO,IAAI,SAAS,UAAU;AAAA,QAC5F;AACA,cAAM,SAAS,MAAM,yBAAyB,MAAM,KAAK;AACzD,YAAI,WAAW,OAAW,QAAO,IAAI,UAAU,MAAM;AACrD,YAAI,MAAM,iBAAiB,OAAW,QAAO,IAAI,iBAAiB,QAAQ,MAAM,YAAY,CAAC;AAC7F,YAAI,MAAM,kBAAkB,OAAW,QAAO,IAAI,kBAAkB,QAAQ,MAAM,aAAa,CAAC;AAChG,YAAI,MAAM,iBAAiB,OAAW,QAAO,IAAI,iBAAiB,QAAQ,MAAM,YAAY,CAAC;AAC7F,YAAI,MAAM,kBAAkB,OAAW,QAAO,IAAI,kBAAkB,QAAQ,MAAM,aAAa,CAAC;AAChG,eAAO,IAAI,YAAY,MAAM,MAAM,UAAU,YAAY,eAAe,IAAI;AAC5E,eAAO,IAAI,QAAQ,MAAM,MAAM,aAAa,MAAM;AAClD,cAAM,SAAS,MAAM,YAAY,GAAG,OAAO,cAAc,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,QAAQ,CAAC;AACxG,eAAO,OAAO;AACd,0BAAkB,OAAO;AACzB,eAAO,CAAC,SACL,MAAM,WAAW,UAAa,MAAM,OAAO,SAAS,IAAI,OAAO,QAAQ,OACvE,MAAM,UAAU,UAAc,IAAI,UAAU,UAAa,MAAM,MAAM,SAAS,IAAI,MAAM,QAAQ;AAAA,MACrG;AACA,YAAM,SAAS,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,GAAG,IAAII,MAAK,EAAE,OAAO,IAAI;AACtE,YAAM,OAAO,gBAAgB,IAAI,aAAa;AAC9C,aAAO,EAAE,OAAO,GAAI,SAAS,QAAQ,SAAS,KAAK,CAAC,IAAI,EAAE,YAAY,KAAK,EAAG;AAAA,IAChF;AAAA,IACA,QAAQ;AAAA,IACR,UAAU,OAAO,QAAQ,UAAU;AAEjC,YAAM,EAAE,aAAa,GAAG,KAAK,IAAI;AACjC,sBAAgB,wDAAqBD,cAAa,MAAM,MAAMD,YAAW;AACzE,YAAM,SAAS,IAAI,gBAAgB,EAAE,UAAU,OAAO,MAAM,KAAK,GAAG,MAAM,OAAOG,QAAO,MAAM,MAAM,CAAC,GAAG,iBAAiB,OAAO,eAAe,KAAK,EAAE,CAAC;AACvJ,iBAAW,SAAS,QAAQ,oBAAoB,MAAM,UAAU,CAAC,CAAC,EAAG,QAAO,OAAO,WAAW,KAAK;AACnG,YAAM,EAAE,MAAM,SAAS,gBAAgB,IAAI,MAAM,YAAY,GAAG,OAAO,cAAc,YAAY,MAAM,CAAC,SAAS,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,gBAAgB,MAAM,EAAE,CAAC;AAClM,YAAM,SAAS,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,GAAG,IAAIC,MAAK;AACzD,YAAM,OAAO,gBAAgB,IAAI,aAAa;AAC9C,aAAO,EAAE,OAAO,GAAI,SAAS,QAAQ,SAAS,KAAK,CAAC,IAAI,EAAE,YAAY,KAAK,EAAG;AAAA,IAChF;AAAA,IACA,QAAQ,OAAO,QAAQA,QAAO,MAAM,YAAY,GAAG,OAAO,SAAS,OAAO,GAAG,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,WAAW,GAAG,EAAE,CAAC,GAAG,IAAI;AAAA,IAC7I,KAAK,OAAO,KAAK,UAAU;AACzB,YAAM,SAAS,UAAU,KAAK;AAC9B,YAAM,OAAO,MAAM,YAAY,GAAG,OAAO,SAAS,OAAO,GAAG,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,WAAW,GAAG,EAAE,CAAC,GAAG;AACxH,YAAM,YAAY,SAAS,GAAG,KAAK,OAAO,IAAI,WAAW,WAAW,IAAI,SAAS;AACjF,YAAM,WAAW,WAAW,OAAO,oBAAoB,WAAW,SAAS,CAAC;AAE5E,YAAM,WAAW,MAAM,YAAY,GAAG,OAAO,SAAS,OAAO,GAAG,CAAC,UAAU,EAAE,OAAO,QAAQ,SAAS,MAAM,OAAO,QAAQ,UAAU,GAAG,MAAM,EAAE,OAAO,OAAO,OAAO,MAAM,OAAO,KAAK,GAAG,SAAS,WAAW,GAAG,EAAE,CAAC;AACnN,aAAO,MAAM;AAAA,QACX,MAAM,SAAS;AAAA,QACf,WAAW,OAAO,SAAS,SAAS,SAAS,QAAQ,IAAI,CAAC,SAAS;AAAA,QACnE;AAAA,QACA,MAAM;AAAA,QACN,KAAK,SAAS;AAAA,QACd,MAAM,CAAC,SAAS;AAAA,QAChB,GAAI,SAAS,QAAQ,EAAE,MAAM,SAAS,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,QAGhD,UAAU,OAAO,SAAS,UAAU,SAAS,QAAQ;AAAA,QACrD,KAAK,MAAM,OAAO;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,IACA,SAAS,OAAO,UAA0B;AACxC,UAAI,MAAM,cAAc,UAAa,MAAM,UAAU,SAAS,GAAG;AAC/D,cAAM,IAAI,aAAa,eAAe,6OAAmE;AAAA,MAC3G;AACA,YAAM,YAAY,OAAO,QAAQ,MAAM,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,OAAO,EAAE,KAAK,OAAO,eAAe,UAAU,EAAE;AACrH,YAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,OAAO,aAAa;AAAA,QACxD;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR,MAAM,EAAE,KAAK,MAAM,KAAK,GAAI,UAAU,WAAW,IAAI,CAAC,IAAI,EAAE,UAAU,EAAG;AAAA,QACzE,SAAS,EAAE,SAAS,aAAa,SAAS,+GAA+B,MAAM,GAAG,IAAI;AAAA,MACxF,CAAC;AACD,aAAO,EAAE,KAAKF,OAAM,IAAI,EAAE;AAAA,IAC5B;AAAA,IACA,OAAO,OAAO,QAAQ,UAAwB;AAC5C,UAAI,MAAM,eAAe,KAAM,OAAM,IAAI,aAAa,eAAe,0RAAwE;AAC7I,UAAI,MAAM,UAAU,KAAM,OAAM,IAAI,aAAa,eAAe,+RAA8D;AAC9H,aAAOA,QAAO,MAAM,YAAY,GAAG,OAAO,cAAc,YAAY,MAAM,CAAC,UAAU,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,SAAS,gBAAgB,MAAM,EAAE,CAAC,GAAG,IAAI;AAAA,IAC1K;AAAA,IACA,UAAU,OAAO,aAAa,UAA2B;AACvD,UAAI,MAAM,UAAU,KAAM,OAAM,IAAI,aAAa,eAAe,uUAAmE;AACnI,YAAM,QAAQ,MAAM,YAAY,GAAG,OAAO,SAAS,OAAO,WAAW,CAAC,UAAU,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,SAAS,WAAW,WAAW,EAAE,CAAC,GAAG;AAC/J,YAAM,WAAW,SAAS,IAAI,KAAK,SAAS,KAAK,QAAQ,KAAK,OAAO,KAAK,SAAS,OAAO,WAAW,OAAO,KAAK,SAAS,EAAE,IAAI;AAChI,UAAI,aAAa,OAAW,OAAM,IAAI,aAAa,UAAU,4LAA2C;AACxG,aAAO,YAAY,QAAQ;AAAA,IAC7B;AAAA,IACA,QAAQ,OAAO,WACbA,QAAO,MAAM,YAAY,GAAG,OAAO,cAAc,YAAY,MAAM,CAAC,WAAW,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,SAAS,gBAAgB,MAAM,EAAE,CAAC,GAAG,IAAI;AAAA,IACpK,WAAW,OAAO,gBAAgBE,QAAO,MAAM,YAAY,GAAG,OAAO,SAAS,OAAO,WAAW,CAAC,WAAW,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,SAAS,WAAW,WAAW,EAAE,CAAC,GAAG,IAAI;AAAA,EACjM;AACF;AAEA,SAASD,QAAO,QAAoC;AAClD,QAAM,OAAO,WAAW,SAAY,IAAI,OAAO,MAAM;AACrD,SAAO,OAAO,UAAU,IAAI,KAAK,QAAQ,IAAI,OAAO;AACtD;AAGA,SAASD,OAAM,KAAqB;AAClC,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,MAAM,OAAO,KAAK,OAAO,WAAW,OAAO,KAAK,EAAE,IAAI;AAC5D,QAAM,YAAY,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AAClE,QAAM,YAAY,KAAK,KAAK,MAAM;AAClC,QAAM,KAAK,OAAO,KAAK,QAAQ,WAAW,sCAAsC,KAAK,KAAK,GAAG,IAAI;AACjG,QAAM,OAAO,SAAS,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,QAAQ,IAAI;AAC9D,QAAM,MAAM,KAAK,KAAK,OAAO;AAC7B,QAAM,OAAO,KAAK,KAAK,IAAI;AAC3B,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,QAAM,aAAa,YAAY,KAAK,WAAW;AAC/C,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,SAAO;AAAA,IACL;AAAA,IACA,GAAI,OAAO,KAAK,QAAQ,WAAW,EAAE,QAAQ,KAAK,IAAI,IAAI,CAAC;AAAA,IAC3D,WAAW,SAAS,SAAY,CAAC,IAAI,CAAC,IAAI;AAAA,IAC1C,QAAQ,EAAE,UAAU,OAAO,oBAAoB,WAAW,SAAS,GAAG,MAAM,UAAU;AAAA,IACtF,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,OAAO,yBAAyB,WAAW,OAAO,GAAG,MAAM,UAAU,EAAE;AAAA,IAC/H,GAAI,OAAO,KAAK,QAAQ,YAAY,KAAK,QAAQ,KAAK,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC;AAAA,IAC3E,GAAI,OAAO,KAAK,QAAQ,YAAY,mBAAmB,KAAK,KAAK,GAAG,IAAI,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC;AAAA,IAC7F,GAAI,SAAS,SAAY,CAAC,IAAI,EAAE,OAAO,KAAK;AAAA,IAC5C,GAAI,OAAO,OAAO,CAAC,IAAI,EAAE,aAAa,GAAG,CAAC,EAAE;AAAA,IAC5C,OAAO,QAAQ,SAAY,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,SAAS,CAAC;AAAA,IACzD,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,eAAe,SAAY,CAAC,IAAI,EAAE,WAAW;AAAA,IACjD,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,EACjD;AACF;AAGA,SAASE,OAAM,KAAqB;AAClC,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,MAAM,OAAO,KAAK,OAAO,WAAW,OAAO,KAAK,EAAE,IAAI;AAC5D,QAAM,YAAY,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AAClE,QAAM,WAAW,SAAS,KAAK,QAAQ,KAAK,OAAO,KAAK,SAAS,OAAO,WAAW,OAAO,KAAK,SAAS,EAAE,IAAI;AAC9G,QAAM,MAAM,KAAK,KAAK,OAAO;AAC7B,QAAM,QAAQ,KAAK,KAAK,KAAK;AAC7B,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,QAAM,aAAa,YAAY,KAAK,WAAW;AAC/C,SAAO;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,IACR,MAAM,KAAK,KAAK,IAAI,KAAK;AAAA,IACzB,GAAI,UAAU,SAAY,CAAC,IAAI,EAAE,MAAM;AAAA,IACvC,QAAQ,EAAE,UAAU,OAAO,oBAAoB,WAAW,SAAS,GAAG,MAAM,UAAU;AAAA,IACtF,OAAO,QAAQ,SAAY,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,SAAS,CAAC;AAAA,IACzD,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,eAAe,SAAY,CAAC,IAAI,EAAE,WAAW;AAAA,EACnD;AACF;;;ACjOA,IAAMC,eAAc;AACpB,IAAMC,UAAS;AAGf,IAAM,WAAW;AAGjB,IAAM,UAAU;AAGhB,IAAM,UAAU;AAGhB,IAAM,gBAAgB;AAGtB,IAAM,oBAAoB;AAG1B,IAAM,mBAAmB,kBAAkB;AAC3C,IAAMC,eAAc,iBAAiB,OAAO,CAAC,SAAS,SAAS,SAAS,SAAS,KAAK;AACtF,IAAM,mBAAmB,kBAAkB;AAC3C,IAAMC,eAAsC,CAAC,QAAQ;AAGrD,IAAMC,gBAA+B;AAAA,EACnC,WAAW;AAAA,EACX,MAAM,EAAE,SAASF,cAAa,YAAYA,cAAa,OAAO,CAAC,EAAE;AAAA,EACjE,MAAM,EAAE,SAASC,cAAa,YAAYA,cAAa,OAAO,CAAC,EAAE;AAAA,EACjE,KAAK,EAAE,MAAM,MAAM,QAAQ,KAAK;AAAA,EAChC,SAAS,EAAE,WAAW,MAAM,WAAW,QAAQ,QAAQ,MAAM,MAAM,KAAK;AAAA,EACxE,OAAO,EAAE,KAAK,OAAO,YAAY,OAAO,KAAK,OAAO,OAAO,MAAM;AAAA,EACjE,QAAQ,EAAE,KAAK,OAAO,KAAK,MAAM;AACnC;AAEO,SAAS,gBAA8B;AAC5C,SAAO,EAAE,cAAcC,eAAc,QAAQ,CAAC,YAAY,2BAA2B,OAAO,EAAE;AAChG;AAKA,SAAS,2BAA2B,EAAE,YAAY,MAAM,GAA8B;AACpF,QAAM,SAAS,cAAc,WAAW,QAAQ,yFAAkC;AAClF,MAAI,CAACH,QAAO,KAAK,MAAM,EAAG,OAAM,IAAI,aAAa,mBAAmB,qCAAgC;AACpG,QAAM,MAAM,QAAQ,WAAW,KAAKD,YAAW;AAC/C,QAAM,SAAS,IAAI,IAAI,GAAG,EAAE;AAC5B,QAAM,OAAO,GAAG,GAAG,UAAU,MAAM;AACnC,QAAM,OAAO,GAAG,IAAI;AACpB,QAAM,UAAU,EAAE,eAAe,UAAU,WAAW,SAAS,EAAE,GAAG;AACpE,QAAM,aAAa,CAAC,SAA4D,EAAE,SAAS,aAAa,SAAS,oFAA6B,GAAG,IAAI;AACrJ,QAAM,aAAa,CAAC,SAA4D,EAAE,SAAS,aAAa,SAAS,oFAA6B,GAAG,IAAI;AACrJ,QAAM,kBAAkB,CAAC,KAAa,cAAiE,EAAE,SAAS,aAAa,SAAS,qDAAa,GAAG,4CAA6B,QAAQ,IAAI;AACjM,QAAM,SAAS,CAAC,QAAwB;AACtC,QAAI,CAAC,SAAS,KAAK,GAAG,EAAG,OAAM,IAAI,aAAa,aAAa,oFAA6B,GAAG,GAAG;AAChG,WAAO;AAAA,EACT;AACA,QAAM,UAAU,CAAC,QAAyB;AACxC,UAAM,QAAQ,QAAQ,KAAK,GAAG;AAC9B,QAAI,UAAU,KAAM,OAAM,IAAI,aAAa,aAAa,oFAA6B,GAAG,GAAG;AAC3F,UAAM,OAAgB,EAAE,KAAK,OAAO,MAAM,CAAC,GAAG,GAAG,GAAG,UAAU,OAAO,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,OAAO,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,OAAO,MAAM,CAAC,GAAG,GAAG,EAAE;AAC9I,WAAO,KAAK,GAAG;AACf,WAAO;AAAA,EACT;AACA,QAAM,SAAS,OAAO,QAAgCK,QAAO,MAAM,YAAY,GAAG,IAAI,SAAS,OAAO,GAAG,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,WAAW,GAAG,EAAE,CAAC,GAAG,IAAI;AAEzK,QAAM,cAAc,OAAO,KAAa,aAAuD;AAC7F,UAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,IAAI,SAAS,OAAO,GAAG,CAAC,IAAI,mBAAmB,QAAQ,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,gBAAgB,KAAK,QAAQ,EAAE,CAAC;AACrK,WAAO,SAAS,IAAI,IAAI,OAAO,CAAC;AAAA,EAClC;AAKA,QAAM,WAAW,OAAO,SAAkC;AACxD,QAAI,CAAC,QAAQ,KAAK,IAAI,EAAG,OAAM,IAAI,aAAa,mBAAmB,kMAA0E;AAC7I,UAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,IAAI,UAAU,IAAI,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,EAAE,SAAS,aAAa,SAAS,sDAAkC,IAAI,IAAI,EAAE,CAAC;AAC7K,UAAM,KAAK,SAAS,IAAI,IAAI,KAAK,KAAK,EAAE,IAAI;AAC5C,QAAI,OAAO,OAAW,OAAM,IAAI,aAAa,UAAU,kEAA+B,IAAI,oEAAkB;AAC5G,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,OAAO,QAAkC;AAC3D,UAAM,OAAgB,CAAC;AACvB,eAAW,aAAa,MAAM,OAAO,GAAG,GAAG,WAAW;AACpD,YAAM,OAAO,MAAM,YAAY,KAAK,QAAQ;AAC5C,iBAAW,QAAQ,WAAW,KAAK,KAAK,GAAG;AACzC,cAAM,WAAW,KAAK,KAAK,IAAI;AAC/B,YAAI,aAAa,OAAW;AAC5B,mBAAW,QAAQ,WAAW,KAAK,KAAK,GAAG;AACzC,gBAAM,WAAW,KAAK,KAAK,IAAI;AAC/B,cAAI,aAAa,OAAW;AAC5B,eAAK,KAAKC,OAAM,KAAK,UAAU,UAAU,UAAU,IAAI,CAAC;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,eAAe,YAAY;AACzB,YAAM,IAAI,aAAa,eAAe,gRAAkF;AAAA,IAC1H;AAAA,IACA,UAAU,OAAO,UAAU;AACzB,sBAAgB,6DAA0BF,cAAa,MAAM,OAAO,gBAAgB;AACpF,YAAM,SAAS,MAAM,gBAAgB,SAAY,SAAY,MAAM,SAAS,MAAM,WAAW;AAC7F,YAAM,SAAS,IAAI,gBAAgB,EAAE,WAAW,OAAO,MAAM,KAAK,EAAE,CAAC;AACrE,UAAI,MAAM,WAAW,OAAW,QAAO,IAAI,cAAc,MAAM,MAAM;AACrE,YAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,IAAI,SAAS,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,QAAQ,CAAC;AAClG,YAAM,SAAS,SAAS,IAAI,IAAI,OAAO,CAAC;AACxC,YAAM,QAAQ,WAAW,OAAO,IAAI,EACjC,IAAI,CAAC,QAAQ,WAAWC,OAAM,GAAG,GAAG,KAAK,QAAQ,MAAM,WAAW,CAAC,EACnE,OAAO,CAAC,QAAQ,SAAS,KAAK,KAAK,CAAC;AACvC,YAAM,QAAQ,KAAK,OAAO,eAAe;AACzC,aAAO,EAAE,OAAO,GAAI,UAAU,SAAY,CAAC,IAAI,EAAE,YAAY,MAAM,EAAG;AAAA,IACxE;AAAA,IACA;AAAA,IACA,UAAU,OAAO,aAAa,UAAU;AACtC,sBAAgB,6DAA0BD,cAAa,MAAM,OAAO,gBAAgB;AACpF,YAAM,OAAO,MAAM,YAAY,OAAO,WAAW,CAAC;AAClD,YAAM,OAAO,SAAS,MAAM,MAAM;AAClC,YAAM,OAAO,OAAO,MAAM;AAC1B,YAAM,OAAO,KAAK,MAAM,MAAM,IAAI;AAClC,YAAM,QAAQ,MAAM,WAAW,SAAY,OAAO,KAAK,OAAO,CAAC,QAAQ,MAAM,QAAQ,SAAS,IAAI,OAAO,QAAQ,MAAM,IAAI;AAC3H,aAAO,EAAE,OAAO,GAAI,OAAO,KAAK,SAAS,EAAE,YAAY,KAAK,OAAO,IAAI,CAAC,GAAG,IAAI,CAAC,EAAG;AAAA,IACrF;AAAA,IACA,QAAQ,OAAO,QAAQ;AACrB,YAAM,OAAO,QAAQ,GAAG;AACxB,YAAM,OAAO,MAAM,YAAY,KAAK,KAAK,KAAK,QAAQ;AACtD,iBAAW,QAAQ,WAAW,KAAK,KAAK,GAAG;AACzC,YAAI,KAAK,KAAK,IAAI,MAAM,KAAK,KAAM;AACnC,cAAM,OAAO,WAAW,KAAK,KAAK,EAAE,KAAK,CAAC,SAAS,KAAK,KAAK,IAAI,MAAM,KAAK,IAAI;AAChF,YAAI,SAAS,OAAW,QAAOE,OAAM,KAAK,KAAK,KAAK,UAAU,KAAK,MAAM,KAAK,MAAM,IAAI;AAAA,MAC1F;AACA,YAAM,IAAI,aAAa,aAAa,oFAA6B,GAAG,GAAG;AAAA,IACzE;AAAA,IACA,KAAK,OAAO,KAAK,UAAU;AACzB,YAAM,SAAS,QAAQ,GAAG;AAE1B,UAAI,OAAO,KAAK,WAAW,GAAG,GAAG;AAC/B,cAAM,IAAI,aAAa,eAAe,6EAA2B,GAAG,kMAA4C;AAAA,MAClH;AACA,YAAM,SAAS,UAAU,KAAK;AAC9B,YAAM,OAAO,OAAO,MAAM;AAC1B,YAAM,OAAO,OAAO,WAAW,UAAa,OAAO,SAAS;AAC5D,YAAM,QAAQ,OAAO,QAAQ,QAAQ;AACrC,YAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,UAAI,OAAO;AACX,UAAI,OAAO,OAAO,QAAQ,UAAU;AACpC,UAAI,OAAoC,IAAI,WAAW,CAAC;AACxD,UAAI,UAAU;AACd,UAAI,OAAO;AACX,UAAI,WAAW;AACf,UAAI,UAAU;AACd,UAAI,OAAO;AACX,UAAI,SAAS;AACb,YAAM,UAAU,IAAI,YAAY;AAChC,YAAM,UAAU,IAAI,YAAY,OAAO;AACvC,iBAAS;AAGP,YAAI,CAAC,QAAQ,KAAK,UAAU,OAAO,OAAO;AACxC,mBAAS;AACT;AAAA,QACF;AACA,cAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,IAAI,SAAS,IAAI,SAAS,OAAO,IAAI,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,WAAW,GAAG,EAAE,CAAC;AACpI,cAAM,SAAS,SAAS,IAAI,IAAI,OAAO,CAAC;AACxC,cAAM,OAAO,QAAQ,OAAO,KAAK,OAAO,IAAI,KAAK,EAAE;AACnD,cAAM,OAAO,QAAQ,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS,IAAI;AAGzE,YAAI,QAAQ;AACZ,YAAI,CAAC,MAAM;AACT,gBAAM,OAAO,KAAK,SAAS,GAAG,KAAK,IAAI,OAAO,QAAQ,KAAK,QAAQ,KAAK,MAAM,CAAC;AAC/E,kBAAQ,KAAK,SAAS,GAAG,KAAK,SAAS,aAAa,IAAI,CAAC;AAAA,QAC3D;AACA,cAAM,SAAS,OAAO,MAAM,KAAK;AACjC,YAAI,OAAO,SAAS,OAAO,OAAO;AAChC,gBAAM,SAAS,OAAO,SAAS,OAAO,SAAS,OAAO,KAAK;AAC3D,qBAAW,OAAO,SAAS,OAAO;AAClC,iBAAO;AAAA,QACT,OAAO;AACL,iBAAO;AAAA,QACT;AACA,gBAAQ,KAAK;AAGb,mBAAW;AACX,kBAAU,OAAO,KAAK,SAAS,OAAO,MAAM;AAC5C,eAAO;AACP,eAAO,OAAO,SAAS;AAIvB,YAAI,CAAC,QAAQ,KAAK,SAAS,MAAM,QAAQ;AACvC,mBAAS;AACT;AAAA,QACF;AAEA,YAAI,QAAQ,OAAO,kBAAkB,MAAO;AAG5C,YAAI,OAAO,QAAQ,KAAK,oBAAoB,QAAQ,yBAAyB,KAAK,IAAI,KAAK,UAAU;AACnG,mBAAS;AACT;AAAA,QACF;AACA,gBAAQ;AAAA,MACV;AACA,aAAO,MAAM;AAAA,QACX,MAAM,QAAQ,OAAO,KAAK,SAAS,YAAY,IAAI,CAAC,CAAC;AAAA,QACrD,WAAW,UAAU,KAAK;AAAA,QAC1B,UAAU;AAAA,QACV,MAAM;AAAA,QACN,KAAK;AAAA,QACL,MAAM;AAAA;AAAA,QAEN,MAAM,OAAO,WAAW,UAAa,CAAC,SAAS,OAAO;AAAA;AAAA;AAAA,QAGtD,UAAU,QAAQ,UAAU;AAAA,QAC5B,KAAK,MAAM,OAAO;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,IACA,SAAS,OAAO,UAA0B;AACxC,YAAM,YAAY,MAAM,aAAa,CAAC;AACtC,UAAI,UAAU,WAAW,EAAG,OAAM,IAAI,aAAa,mBAAmB,8JAAqD;AAC3H,YAAM,SAAS,OAAO,QAAQ,MAAM,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,EAAE,MAAM,MAAM,EAAE;AAC1F,YAAM,OAAO,MAAM,YAAY,QAAQ,EAAE,KAAK,MAAM,IAAI,IAAI,EAAE,QAAQ,MAAM,IAAI;AAChF,YAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,IAAI,SAAS,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,MAAM,EAAE,MAAM,WAAW,UAAU,IAAI,CAAC,UAAU,EAAE,MAAM,OAAO,EAAE,EAAE,EAAE,CAAC;AACrK,aAAO,EAAE,KAAKD,OAAM,IAAI,EAAE;AAAA,IAC5B;AAAA;AAAA,IAEA,OAAO,YAAY;AACjB,YAAM,IAAI,aAAa,eAAe,6VAAoF;AAAA,IAC5H;AAAA,IACA,UAAU,YAAY;AACpB,YAAM,IAAI,aAAa,eAAe,6VAAoF;AAAA,IAC5H;AAAA,IACA,QAAQ,YAAY;AAClB,YAAM,IAAI,aAAa,eAAe,qUAAgF;AAAA,IACxH;AAAA,IACA,WAAW,YAAY;AACrB,YAAM,IAAI,aAAa,eAAe,qUAAgF;AAAA,IACxH;AAAA,EACF;AACF;AAGA,SAAS,OAAO,OAA2B,KAAqB;AAC9D,QAAM,UAAU,IAAI,aAAa,aAAa,oFAA6B,GAAG,GAAG;AACjF,MAAI,UAAU,OAAW,OAAM;AAC/B,MAAI;AACJ,MAAI;AACF,cAAU,mBAAmB,KAAK;AAAA,EACpC,QAAQ;AACN,UAAM;AAAA,EACR;AACA,MAAI,YAAY,GAAI,OAAM;AAC1B,SAAO;AACT;AAGA,SAAS,OAAO,MAAuB;AACrC,SAAO,CAAC,KAAK,KAAK,KAAK,UAAU,KAAK,MAAM,KAAK,IAAI,EAAE,IAAI,kBAAkB,EAAE,KAAK,GAAG;AACzF;AAGA,SAAS,WAAW,OAA2C;AAC7D,SAAO,MAAM,QAAQ,KAAK,IAAI,MAAM,OAAO,QAAQ,IAAI,CAAC;AAC1D;AAGA,SAAS,SAAS,QAAoC;AACpD,MAAI,WAAW,OAAW,QAAO;AACjC,QAAM,QAAQ,kBAAkB,KAAK,MAAM;AAC3C,MAAI,UAAU,KAAM,QAAO;AAC3B,QAAM,OAAO,OAAO,MAAM,CAAC,CAAC;AAC5B,SAAO,OAAO,cAAc,IAAI,KAAK,QAAQ,IAAI,OAAO;AAC1D;AAGA,SAASA,OAAM,KAAqB;AAClC,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,MAAM,KAAK,KAAK,IAAI,KAAK;AAC/B,QAAM,YAAY,KAAK,KAAK,MAAM,KAAK;AACvC,QAAM,WAAW,KAAK,KAAK,UAAU;AACrC,QAAM,OAAO,SAAS,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,IAAI,IAAI;AAC1D,QAAM,OAAO,SAAS,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,IAAI,IAAI;AAC1D,QAAM,QAAQ,SAAS,KAAK,KAAK,IAAI,KAAK,QAAQ,CAAC;AACnD,QAAM,YAAY,YAAY,MAAM,UAAU;AAC9C,QAAM,YAAY,YAAY,MAAM,UAAU;AAC9C,QAAM,aAAa,YAAY,MAAM,WAAW;AAChD,QAAM,YAAY,YAAY,MAAM,UAAU;AAC9C,QAAM,SAAS,WAAW,KAAK,cAAc;AAC7C,SAAO;AAAA,IACL;AAAA,IACA,GAAI,SAAS,KAAK,GAAG,IAAI,EAAE,QAAQ,OAAO,GAAG,EAAE,IAAI,CAAC;AAAA,IACpD,WAAW,WAAW,WAAW,KAAK,SAAS,EAAE,IAAI,CAAC,aAAa,SAAS,IAAI,CAAC;AAAA,IACjF,QAAQ,EAAE,UAAU,OAAO,yBAAyB,WAAW,SAAS,GAAG,MAAM,UAAU;AAAA,IAC3F,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,OAAO,wBAAwB,UAAU,OAAO,GAAG,MAAM,SAAS,EAAE;AAAA,IAC3H,GAAI,SAAS,UAAa,SAAS,gBAAgB,CAAC,IAAI,EAAE,OAAO,KAAK;AAAA,IACtE,GAAI,SAAS,SAAY,CAAC,IAAI,EAAE,aAAa,KAAK;AAAA,IAClD,GAAI,OAAO,WAAW,IAAI,CAAC,IAAI,EAAE,OAAO;AAAA,IACxC,OAAO,CAAC;AAAA,IACR,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,eAAe,SAAY,CAAC,IAAI,EAAE,WAAW;AAAA,IACjD,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,EACjD;AACF;AAGA,SAASC,OAAM,KAAa,UAAkB,MAAc,UAAkB,MAAsC;AAClH,QAAM,YAAY,KAAK,KAAK,MAAM,KAAK;AACvC,QAAM,QAAQ,SAAS,KAAK,KAAK,IAAI,KAAK,QAAQ,CAAC;AACnD,QAAM,YAAY,YAAY,MAAM,UAAU;AAC9C,QAAM,YAAY,YAAY,MAAM,UAAU;AAC9C,QAAM,aAAa,YAAY,MAAM,WAAW;AAChD,SAAO;AAAA,IACL,KAAK,CAAC,KAAK,UAAU,MAAM,QAAQ,EAAE,IAAI,kBAAkB,EAAE,KAAK,GAAG;AAAA,IACrE,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO,GAAG,QAAQ,IAAI,IAAI;AAAA,IAC1B,QAAQ,EAAE,UAAU,OAAO,yBAAyB,WAAW,SAAS,GAAG,MAAM,UAAU;AAAA,IAC3F,OAAO,CAAC;AAAA,IACR,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,eAAe,SAAY,CAAC,IAAI,EAAE,WAAW;AAAA,EACnD;AACF;AAGA,SAAS,SAAS,KAAY,OAA4B;AACxD,UACG,MAAM,WAAW,UAAa,MAAM,OAAO,SAAS,IAAI,OAAO,QAAQ,OACvE,MAAM,UAAU,UAAc,IAAI,UAAU,UAAa,MAAM,MAAM,SAAS,IAAI,MAAM,QAAQ,OAChG,MAAM,aAAa,UAAa,IAAI,UAAU,SAAS,MAAM,QAAQ,OACrE,MAAM,UAAU,UAAa,IAAI,UAAU,MAAM,WACjD,MAAM,gBAAgB,UAAa,IAAI,gBAAgB,MAAM,gBAC9D,YAAY,IAAI,WAAW,MAAM,cAAc,MAAM,aAAa,KAClE,YAAY,IAAI,WAAW,MAAM,cAAc,MAAM,aAAa;AAEtE;AAOA,SAAS,WAAW,KAAY,KAA8B,QAA4B,MAAiC;AACzH,MAAI,IAAI,gBAAgB,UAAa,WAAW,UAAa,SAAS,OAAW,QAAO;AACxF,QAAM,KAAK,SAAS,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,EAAE,IAAI;AACpD,SAAO,OAAO,SAAS,EAAE,GAAG,KAAK,aAAa,KAAK,IAAI;AACzD;AAGA,SAAS,YAAY,QAA4B;AAC/C,MAAI,QAAQ;AACZ,SAAO,QAAQ,KAAK,QAAQ,OAAO,YAAY,OAAO,KAAK,KAAK,KAAK,SAAU,IAAM,UAAS;AAC9F,SAAO;AACT;AAGA,SAAS,aAAa,QAA4B;AAChD,WAAS,OAAO,GAAG,QAAQ,KAAK,IAAI,GAAG,OAAO,MAAM,GAAG,QAAQ,GAAG;AAChE,UAAM,OAAO,OAAO,OAAO,SAAS,IAAI,KAAK;AAC7C,SAAK,OAAO,SAAU,IAAM;AAC5B,UAAM,OAAO,QAAQ,MAAO,IAAI,QAAQ,MAAO,IAAI,QAAQ,MAAO,IAAI;AACtE,WAAO,OAAO,OAAO,OAAO;AAAA,EAC9B;AACA,SAAO;AACT;AAEA,SAAS,OAAO,MAAkB,MAA8B;AAC9D,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,QAAM,SAAS,IAAI,WAAW,KAAK,SAAS,KAAK,MAAM;AACvD,SAAO,IAAI,MAAM,CAAC;AAClB,SAAO,IAAI,MAAM,KAAK,MAAM;AAC5B,SAAO;AACT;;;ACvYA,IAAM,cAAc,oBAAI,IAA+B;AAGhD,SAAS,gBAAgB,YAAqC;AACnE,QAAM,OAAO,WAAW,WAAW;AACnC,MAAI,YAAY,IAAI,IAAI,EAAG,OAAM,IAAI,MAAM,wCAAU,IAAI,iHAAuB;AAChF,cAAY,IAAI,MAAM,UAAU;AAClC;AAEO,SAAS,YAAY,MAA6C;AACvE,SAAO,YAAY,IAAI,IAAI;AAC7B;AAEO,SAAS,eAAoC;AAClD,SAAO,CAAC,GAAG,YAAY,OAAO,CAAC;AACjC;;;ACtBA,SAAS,KAAAC,UAAS;AAIX,IAAM,kCAAkCC,GAAE,KAAK,CAAC,SAAS,QAAQ,UAAU,QAAQ,CAAC;AACpF,IAAM,0BAA0BA,GAAE,KAAK,CAAC,UAAU,UAAU,UAAU,UAAU,UAAU,UAAU,gBAAgB,iBAAiB,gBAAgB,eAAe,CAAC;AACrK,IAAM,6BAA6BA,GAAE,KAAK,CAAC,WAAW,WAAW,OAAO,CAAC;AACzE,IAAM,oBAAoBA,GAAE,KAAK,CAAC,SAAS,UAAU,QAAQ,CAAC;AAE9D,IAAM,oBAAoBA,GAAE,OAAO;AAAA;AAAA,EAExC,KAAKA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAC9B,OAAOA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,IAAI;AAAA,EACjC,aAAaA,GAAE,OAAO,EAAE,IAAI,OAAS,EAAE,SAAS;AAAA,EAChD,QAAQA,GAAE,OAAO,EAAE,UAAU,iCAAiC,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,CAAC;AAAA;AAAA,EAEhG,QAAQA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA;AAAA,EAE5C,QAAQA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EACjC,QAAQA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA;AAAA,EAEjC,SAASA,GAAE,OAAO,EAAE,MAAM,kBAAkB,EAAE,SAAS;AAAA,EACvD,QAAQA,GAAE,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG;AAAA;AAAA,EAEnD,WAAWA,GAAE,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACjE,OAAOA,GAAE,MAAM,eAAe,EAAE,IAAI,GAAG;AAAA,EACvC,WAAW,gBAAgB,SAAS;AAAA,EACpC,WAAW,gBAAgB,SAAS;AAAA,EACpC,UAAU,gBAAgB,SAAS;AAAA,EACnC,UAAU,gBAAgB,SAAS;AACrC,CAAC;;;AChBD,IAAMC,eAAc;AACpB,IAAMC,UAAS;AACf,IAAM,SAAS;AACf,IAAMC,OAAM;AACZ,IAAM,eAAe;AACrB,IAAM,mBAAmB;AAGzB,IAAM,oBAA6C;AAAA,EACjD,MAAM;AAAA,IACJ,SAAS,wBAAwB;AAAA,IACjC,YAAY,CAAC,UAAU,UAAU,UAAU,UAAU,gBAAgB,iBAAiB,gBAAgB,eAAe;AAAA,IACrH,OAAO,CAAC,WAAW,SAAS;AAAA,EAC9B;AAAA,EACA,UAAU,EAAE,SAAS,iBAAiB,YAAY,CAAC,GAAG,OAAO,CAAC,KAAK,EAAE;AAAA,EACrE,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,QAAQ,CAAC,SAAS,eAAe,QAAQ;AAAA,EACzC,UAAU,CAAC,QAAQ,QAAQ;AAAA,EAC3B,SAAS;AAAA,EACT,OAAO,CAAC,SAAS,UAAU,QAAQ;AAAA,EACnC,qBAAqB;AACvB;AAEO,SAAS,cAAqC;AACnD,SAAO;AAAA,IACL,cAAc;AAAA,IACd,QAAQ,CAAC,YAAY,wBAAwB,OAAO;AAAA,EACtD;AACF;AAEA,SAAS,wBAAwB,EAAE,YAAY,MAAM,GAAuC;AAC1F,QAAM,SAAS,cAAc,WAAW,QAAQ,sFAA+B;AAC/E,MAAI,CAACD,QAAO,KAAK,MAAM,EAAG,OAAM,IAAI,aAAa,mBAAmB,kCAA6B;AACjG,QAAM,MAAM,QAAQ,WAAW,KAAKD,YAAW;AAC/C,QAAM,SAAS,IAAI,IAAI,GAAG,EAAE;AAC5B,QAAM,OAAO,GAAG,GAAG,UAAU,MAAM;AACnC,QAAM,SAAS,GAAG,GAAG,UAAU,MAAM;AAErC,QAAM,QAAQ,OAAO,MAAM,GAAG,EAAE,CAAC,KAAK;AACtC,QAAM,UAAU;AAAA,IACd,QAAQ;AAAA,IACR,wBAAwB;AAAA,IACxB,GAAI,WAAW,UAAU,UAAa,WAAW,UAAU,KAAK,CAAC,IAAI,EAAE,eAAe,UAAU,WAAW,KAAK,GAAG;AAAA,EACrH;AACA,QAAM,UAAU,CAAC,SAA4D,EAAE,SAAS,aAAa,SAAS,uCAAmB,GAAG,IAAI;AACxI,QAAM,SAAS,CAAC,QAAwB;AACtC,QAAI,CAAC,OAAO,KAAK,GAAG,EAAG,OAAM,IAAI,aAAa,aAAa,uCAAmB,GAAG,GAAG;AACpF,WAAO;AAAA,EACT;AACA,QAAM,UAAU,OAAO,QACrB,QAAQ,MAAM,YAAY,GAAG,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,QAAQ,GAAG,EAAE,CAAC,GAAG,IAAI;AAC9G,SAAO;AAAA,IACL,MAAM,OAAO,UAAU;AACrB,sBAAgB,cAAc,kBAAkB,MAAM,OAAO,wBAAwB,OAAO;AAC5F,YAAM,SAAS,aAAa,MAAM,MAAM;AACxC,YAAM,OAAOG,QAAO,MAAM,MAAM;AAChC,YAAM,SAAS,IAAI,gBAAgB,EAAE,OAAO,YAAY,MAAM,GAAG,UAAU,OAAO,MAAM,KAAK,GAAG,MAAM,OAAO,IAAI,EAAE,CAAC;AACpH,UAAI,MAAM,WAAW,OAAW,QAAO,IAAI,QAAQ,GAAG,KAAK,IAAI,MAAM,MAAM,EAAE;AAC7E,UAAI,MAAM,WAAW,OAAW,QAAO,IAAI,QAAQ,MAAM,MAAM;AAC/D,UAAI,MAAM,SAAS,QAAW;AAC5B,eAAO,IAAI,QAAQ,MAAM,KAAK,KAAK;AACnC,eAAO,IAAI,aAAa,MAAM,KAAK,aAAa,MAAM;AAAA,MACxD;AACA,YAAM,EAAE,MAAM,SAAS,gBAAgB,IAAI,MAAM,YAAY,GAAG,IAAI,IAAI,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,QAAQ,CAAC;AACvH,YAAM,SAAS,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,GAAG,IAAI,MAAM,EAAE,OAAO,CAAC,SAAS,YAAY,MAAM,OAAO,MAAM,CAAC;AAC7G,aAAO,EAAE,OAAO,GAAG,OAAO,gBAAgB,IAAI,MAAM,GAAG,IAAI,EAAE;AAAA,IAC/D;AAAA,IACA,KAAK,CAAC,QAAQ,QAAQ,GAAG;AAAA,IACzB,QAAQ,OAAO,UAAU,QAAQ,MAAM,YAAY,MAAM,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,MAAM,WAAW,KAAK,EAAE,CAAC,GAAG,IAAI;AAAA,IACnI,QAAQ,OAAO,KAAK,UAAU;AAE5B,UAAI,MAAM,WAAW,QAAS,OAAM,IAAI,aAAa,eAAe,iNAAsD;AAC1H,YAAM,UAAU,MAAM,WAAW,SAAS,MAAM,QAAQ,GAAG,IAAI;AAC/D,UAAI,SAAS,OAAO,aAAa,QAAS,OAAM,IAAI,aAAa,eAAe,0MAAoD;AAEpI,UAAI,YAAY,UAAa,QAAQ,OAAO,aAAa,UAAU,MAAM,UAAU,UAAa,MAAM,gBAAgB,UAAa,MAAM,WAAW,OAAW,QAAO;AACtK,aAAO,QAAQ,MAAM,YAAY,GAAG,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,QAAQ,SAAS,MAAM,UAAU,KAAK,GAAG,SAAS,QAAQ,GAAG,EAAE,CAAC,GAAG,IAAI;AAAA,IAC9J;AAAA,IACA,OAAO,OAAO,KAAK,UAAU;AAC3B,UAAI,MAAM,iBAAiB,KAAM,OAAM,IAAI,aAAa,eAAe,+QAA6D;AACpI,UAAI,MAAM,WAAW,UAAa,CAAC,kBAAkB,MAAM,SAAS,MAAM,MAAM,GAAG;AACjF,cAAM,IAAI,aAAa,eAAe,0GAA+B,MAAM,MAAM,qGAAqB;AAAA,MACxG;AAEA,YAAM,YAAY,GAAG,IAAI,IAAI,OAAO,GAAG,CAAC,UAAU,EAAE,OAAO,QAAQ,SAAS,QAAQ,OAAO,MAAM,UAAU,KAAK,GAAG,YAAY,CAAC,KAAK,GAAG,GAAG,SAAS,QAAQ,GAAG,EAAE,CAAC;AAClK,aAAO,QAAQ,GAAG;AAAA,IACpB;AAAA,IACA,UAAU,OAAO,KAAK,UAAU;AAC9B,yBAAmB,kBAAkB,kBAAkB,UAAU,KAAK;AACtE,YAAM,OAAOA,QAAO,MAAM,MAAM;AAChC,YAAM,SAAS,IAAI,gBAAgB,EAAE,UAAU,OAAO,MAAM,KAAK,GAAG,MAAM,OAAO,IAAI,EAAE,CAAC;AAExF,UAAI,MAAM,iBAAiB,OAAW,QAAO,IAAI,SAAS,QAAQ,MAAM,YAAY,CAAC;AACrF,YAAM,EAAE,MAAM,SAAS,gBAAgB,IAAI,MAAM,YAAY,GAAG,MAAM,IAAI,OAAO,GAAG,CAAC,aAAa,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,QAAQ,GAAG,EAAE,CAAC;AACxK,aAAO,EAAE,QAAQ,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,GAAG,IAAI,SAAS,GAAG,GAAG,OAAO,gBAAgB,IAAI,MAAM,GAAG,IAAI,EAAE;AAAA,IACjH;AAAA,IACA,SAAS,OAAO,KAAK,SAAS,WAAW,MAAM,YAAY,GAAG,MAAM,IAAI,OAAO,GAAG,CAAC,aAAa,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,MAAM,EAAE,KAAK,GAAG,SAAS,QAAQ,GAAG,EAAE,CAAC,GAAG,IAAI;AAAA,EAC1L;AACF;AAEA,SAASA,QAAO,QAAoC;AAClD,QAAM,OAAO,WAAW,SAAY,IAAI,OAAO,MAAM;AACrD,SAAO,OAAO,UAAU,IAAI,KAAK,QAAQ,IAAI,OAAO;AACtD;AAGA,SAAS,OAAO,MAAqB,MAAuC;AAC1E,SAAO,SAAS,QAAQ,aAAa,KAAK,IAAI,IAAI,EAAE,YAAY,OAAO,OAAO,CAAC,EAAE,IAAI,CAAC;AACxF;AAIA,SAAS,YAAY,QAAkE;AACrF,MAAI,WAAW,OAAW,QAAO;AACjC,MAAI,OAAO,MAAM,CAAC,SAAS,SAAS,WAAW,SAAS,MAAM,EAAG,QAAO;AACxE,MAAI,OAAO,MAAM,CAAC,SAAS,SAAS,YAAY,SAAS,QAAQ,EAAG,QAAO;AAC3E,SAAO;AACT;AAIA,SAAS,YAAY,MAAmB,OAAyB,QAAmE;AAClI,MAAI,WAAW,UAAa,CAAC,OAAO,SAAS,KAAK,OAAO,QAAQ,EAAG,QAAO;AAC3E,MAAI,MAAM,WAAW,UAAa,KAAK,WAAW,MAAM,OAAQ,QAAO;AACvE,MAAI,MAAM,WAAW,UAAa,CAAC,MAAM,OAAO,MAAM,CAAC,UAAU,KAAK,OAAO,SAAS,KAAK,CAAC,EAAG,QAAO;AACtG,MAAI,MAAM,WAAW,UAAa,CAAC,aAAa,CAAC,KAAK,OAAO,KAAK,WAAW,GAAG,MAAM,MAAM,EAAG,QAAO;AACtG,SAAO,YAAY,KAAK,WAAW,MAAM,cAAc,MAAM,aAAa,KAAK,YAAY,KAAK,WAAW,MAAM,cAAc,MAAM,aAAa;AACpJ;AAGA,SAAS,aAAa,QAA4G;AAChI,MAAI,WAAW,UAAa,OAAO,WAAW,EAAG,QAAO;AACxD,aAAW,QAAQ,QAAQ;AACzB,QAAI,CAAC,gCAAgC,QAAQ,SAAS,IAAI,GAAG;AAC3D,YAAM,IAAI,aAAa,mBAAmB,mLAA4C,OAAO,IAAI,CAAC,GAAG;AAAA,IACvG;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,WAAW,OAAqD;AACvE,SAAO;AAAA,IACL,OAAO,MAAM;AAAA,IACb,MAAM,MAAM;AAAA,IACZ,MAAM,MAAM;AAAA,IACZ,GAAI,MAAM,gBAAgB,SAAY,CAAC,IAAI,EAAE,MAAM,MAAM,YAAY;AAAA,IACrE,GAAI,MAAM,UAAU,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;AAAA,EAChD;AACF;AAGA,SAAS,UAAU,OAAuD;AACxE,SAAO;AAAA,IACL,GAAI,MAAM,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;AAAA,IAC1D,GAAI,MAAM,gBAAgB,SAAY,CAAC,IAAI,EAAE,MAAM,MAAM,YAAY;AAAA,IACrE,GAAI,MAAM,WAAW,SAAY,CAAC,IAAI,EAAE,MAAM,MAAM,OAAO;AAAA,IAC3D,GAAI,MAAM,WAAW,SAAY,CAAC,IAAI,EAAE,OAAO,MAAM,WAAW,WAAW,WAAW,OAAO;AAAA,EAC/F;AACF;AAGA,SAAS,UAAU,OAA4C;AAC7D,QAAM,QAAQ,MAAM,SAAS,MAAM,IAAI,KAAK,CAAC;AAC7C,SAAO;AAAA,IACL,GAAI,MAAM,WAAW,SAAY,CAAC,IAAI,EAAE,cAAc,MAAM,OAAO;AAAA,IACnE,GAAI,MAAM,YAAY,SAAY,CAAC,IAAI,EAAE,KAAK,MAAM,QAAQ;AAAA,IAC5D,GAAI,MAAM,YAAY,SAAY,CAAC,IAAI,EAAE,cAAc,MAAM,CAAC,KAAK,GAAG;AAAA,IACtE,GAAI,MAAM,SAAS,IAAI,EAAE,gBAAgB,MAAM,MAAM,CAAC,EAAE,KAAK,IAAI,EAAE,IAAI,CAAC;AAAA,EAC1E;AACF;AAEA,SAAS,OAAO,KAA2B;AACzC,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,OAAO,SAAS,KAAK,IAAI,IAAI,KAAK,OAAO,CAAC;AAChD,QAAM,OAAO,SAAS,KAAK,IAAI,IAAI,KAAK,OAAO,CAAC;AAChD,QAAM,MAAM,OAAO,KAAK,WAAW,WAAW,OAAO,KAAK,MAAM,IAAI;AACpE,QAAM,cAAc,KAAK,KAAK,IAAI;AAClC,QAAM,SAAS,SAAS,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,KAAK,IAAI;AAC7D,QAAM,MAAM,KAAK,KAAK,GAAG;AACzB,QAAM,MAAM,KAAK,KAAK,QAAQ;AAC9B,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,QAAM,WAAW,YAAY,KAAK,SAAS;AAC3C,QAAM,WAAW,YAAY,KAAK,SAAS;AAC3C,QAAM,SAAS,KAAK,UAAU;AAC9B,QAAM,SAAS,KAAK,cAAc,UAAa,KAAK,cAAc;AAElE,QAAM,WAAsC,SAAS,SAAS,WAAW,WAAW,KAAK,UAAU,OAAO,UAAU;AACpH,SAAO;AAAA,IACL;AAAA,IACA,OAAO,KAAK,KAAK,KAAK,KAAK;AAAA,IAC3B,GAAI,gBAAgB,SAAY,CAAC,IAAI,EAAE,YAAY;AAAA,IACnD,QAAQ,EAAE,UAAU,MAAM,SAAS;AAAA,IACnC,GAAI,WAAW,SAAY,CAAC,IAAI,EAAE,OAAO;AAAA,IACzC,QAAQ,KAAK,KAAK,GAAG,KAAK;AAAA,IAC1B,QAAQ,KAAK,KAAK,GAAG,KAAK;AAAA,IAC1B,GAAI,QAAQ,UAAaD,KAAI,KAAK,GAAG,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC;AAAA,IAC7D,QAAQ,MAAM,QAAQ,KAAK,MAAM,IAAI,WAAW,KAAK,OAAO,IAAI,CAAC,UAAW,SAAS,KAAK,IAAI,MAAM,OAAO,KAAM,CAAC,IAAI,CAAC;AAAA,IACvH,WAAW,OAAO,KAAK,mBAAmB;AAAA,IAC1C,OAAO,QAAQ,SAAY,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,SAAS,CAAC;AAAA,IACzD,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS;AAAA,IAC7C,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS;AAAA,EAC/C;AACF;AAGA,SAAS,OAAO,OAA0B;AACxC,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACnC,QAAM,QAAQ,MAAM,IAAI,CAAC,SAAU,SAAS,IAAI,IAAI,KAAK,KAAK,KAAK,IAAI,MAAU;AACjF,SAAO,CAAC,GAAG,IAAI,IAAI,MAAM,OAAO,CAAC,SAAyB,SAAS,MAAS,CAAC,CAAC;AAChF;AAEA,SAAS,UAAU,KAA4B;AAC7C,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,SAAS,SAAS,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,KAAK,IAAI;AAC7D,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,SAAO,EAAE,IAAI,OAAO,KAAK,OAAO,WAAW,OAAO,KAAK,EAAE,IAAI,KAAK,GAAI,WAAW,SAAY,CAAC,IAAI,EAAE,OAAO,GAAI,MAAM,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,IAAI,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU,EAAG;AACzN;;;AC3OA,SAAS,KAAAE,UAAS;AAIX,IAAM,uBAAuBC,GAAE,KAAK,CAAC,UAAU,YAAY,SAAS,CAAC;AAErE,IAAM,qBAAqBA,GAAE,KAAK,CAAC,QAAQ,CAAC;AAE5C,IAAM,aAAaA,GAAE,OAAO;AAAA;AAAA,EAEjC,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA;AAAA,EAE/B,eAAeA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACnD,aAAaA,GAAE,OAAO,EAAE,IAAI,GAAO,EAAE,SAAS;AAAA,EAC9C,YAAY,qBAAqB,SAAS;AAAA;AAAA,EAE1C,OAAOA,GAAE,MAAM,eAAe,EAAE,IAAI,EAAE;AACxC,CAAC;AAEM,IAAM,eAAeA,GAAE,OAAO;AAAA;AAAA,EAEnC,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA;AAAA,EAE/B,KAAKA,GAAE,OAAO,EAAE,MAAM,kBAAkB,EAAE,SAAS;AAAA;AAAA,EAEnD,WAAWA,GAAE,QAAQ,EAAE,SAAS;AAAA;AAAA,EAEhC,WAAWA,GAAE,QAAQ,EAAE,SAAS;AAClC,CAAC;;;AClBD,IAAMC,eAAc;AACpB,IAAMC,UAAS;AACf,IAAMC,OAAM;AACZ,IAAM,mBAAmB;AACzB,IAAM,iBAAiB,mBAAmB;AAG1C,IAAMC,gBAAiC;AAAA,EACrC,UAAU,EAAE,SAAS,gBAAgB,YAAY,gBAAgB,OAAO,CAAC,EAAE;AAC7E;AAEO,SAAS,aAA6B;AAC3C,SAAO,EAAE,cAAcA,eAAc,QAAQ,CAAC,YAAY,wBAAwB,OAAO,EAAE;AAC7F;AAEA,SAAS,wBAAwB,EAAE,YAAY,MAAM,GAAgC;AACnF,QAAM,SAAS,cAAc,WAAW,QAAQ,sFAA+B;AAC/E,MAAI,CAACF,QAAO,KAAK,MAAM,EAAG,OAAM,IAAI,aAAa,mBAAmB,kCAA6B;AACjG,QAAM,MAAM,QAAQ,WAAW,KAAKD,YAAW;AAC/C,QAAM,SAAS,IAAI,IAAI,GAAG,EAAE;AAC5B,QAAM,OAAO,GAAG,GAAG,UAAU,MAAM;AACnC,QAAM,UAAU;AAAA,IACd,QAAQ;AAAA,IACR,wBAAwB;AAAA,IACxB,GAAI,WAAW,UAAU,UAAa,WAAW,UAAU,KAAK,CAAC,IAAI,EAAE,eAAe,UAAU,WAAW,KAAK,GAAG;AAAA,EACrH;AACA,QAAM,UAAU,EAAE,SAAS,aAAa,SAAS,uGAA4B,MAAM,IAAI;AACvF,SAAO;AAAA,IACL,KAAK,YAAY,QAAQ,MAAM,YAAY,MAAM,EAAE,OAAO,QAAQ,SAAS,QAAQ,CAAC,GAAG,MAAM,MAAM;AAAA,IACnG,UAAU,OAAO,UAAU;AACzB,sBAAgB,kBAAkBG,cAAa,UAAU,OAAO,cAAc;AAC9E,YAAM,OAAOC,QAAO,MAAM,MAAM;AAChC,YAAM,SAAS,IAAI,gBAAgB,EAAE,UAAU,OAAO,MAAM,KAAK,GAAG,MAAM,OAAO,IAAI,EAAE,CAAC;AACxF,YAAM,EAAE,MAAM,SAAS,gBAAgB,IAAI,MAAM,YAAY,GAAG,IAAI,aAAa,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,QAAQ,CAAC;AACzI,YAAM,SAAS,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,GAAG,IAAI,QAAQ,EAAE,OAAO,CAAC,WAAW,MAAM,WAAW,UAAa,aAAa,CAAC,OAAO,IAAI,GAAG,MAAM,MAAM,CAAC;AACxJ,aAAO,EAAE,OAAO,GAAGC,QAAO,gBAAgB,IAAI,MAAM,GAAG,IAAI,EAAE;AAAA,IAC/D;AAAA,EACF;AACF;AAGA,SAASD,QAAO,QAAoC;AAClD,QAAM,OAAO,WAAW,SAAY,IAAI,OAAO,MAAM;AACrD,SAAO,OAAO,UAAU,IAAI,KAAK,QAAQ,IAAI,OAAO;AACtD;AAGA,SAASC,QAAO,MAAqB,MAAuC;AAC1E,SAAO,SAAS,QAAQ,aAAa,KAAK,IAAI,IAAI,EAAE,YAAY,OAAO,OAAO,CAAC,EAAE,IAAI,CAAC;AACxF;AAGA,SAAS,OAAO,KAAc,QAAsB;AAClD,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,gBAAgB,KAAK,KAAK,cAAc;AAC9C,QAAM,cAAc,KAAK,KAAK,WAAW;AACzC,QAAM,aAAa,aAAa,KAAK,UAAU;AAC/C,QAAM,MAAM,KAAK,KAAK,QAAQ;AAC9B,SAAO;AAAA,IACL,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,KAAK,SAAS,KAAK;AAAA,IACjD,GAAI,kBAAkB,SAAY,CAAC,IAAI,EAAE,cAAc;AAAA,IACvD,GAAI,gBAAgB,SAAY,CAAC,IAAI,EAAE,YAAY;AAAA,IACnD,GAAI,eAAe,SAAY,CAAC,IAAI,EAAE,WAAW;AAAA,IACjD,OAAO,QAAQ,SAAY,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,SAAS,CAAC;AAAA,EAC3D;AACF;AAGA,SAAS,SAAS,KAAsB;AACtC,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,MAAM,SAAS,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,GAAG,IAAI;AAC5D,SAAO;AAAA,IACL,MAAM,KAAK,KAAK,IAAI,KAAK;AAAA,IACzB,GAAI,QAAQ,UAAa,CAACH,KAAI,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI;AAAA,IACrD,GAAI,OAAO,KAAK,cAAc,YAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,EAC7E;AACF;AAGA,SAAS,aAAa,OAA4C;AAChE,QAAM,SAAS,qBAAqB,UAAU,KAAK;AACnD,SAAO,OAAO,UAAU,OAAO,OAAO;AACxC;;;AC3EA,IAAMI,eAAc;AACpB,IAAMC,UAAS;AACf,IAAMC,UAAS;AACf,IAAMC,gBAAe;AACrB,IAAMC,oBAAmB;AAElB,SAAS,gBAAmC;AAGjD,QAAM,SAA4B;AAAA,IAChC,MAAM,EAAE,SAAS,eAAe,YAAY,CAAC,QAAQ,GAAG,OAAO,CAAC,WAAW,WAAW,UAAU,EAAE;AAAA,IAClG,UAAU,EAAE,SAAS,CAAC,cAAc,GAAG,YAAY,CAAC,GAAG,OAAO,CAAC,KAAK,EAAE;AAAA,EACxE;AACA,SAAO;AAAA,IACL,YAAY;AAAA,MACV,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,QACN,EAAE,MAAM,UAAU,UAAU,MAAM,QAAQ,MAAM;AAAA,QAChD,EAAE,MAAM,SAAS,UAAU,MAAM,QAAQ,KAAK;AAAA,QAC9C,EAAE,MAAM,OAAO,UAAU,OAAO,QAAQ,MAAM;AAAA,MAChD;AAAA,MACA,UAAU,EAAE,QAAQ,MAAM,QAAQ,MAAM,SAAS,MAAM,UAAU,MAAM,QAAQ,MAAM,UAAU,MAAM,UAAU,CAAC,QAAQ,eAAe,QAAQ,UAAU,EAAE;AAAA,IAC7J;AAAA,IACA,QAAQ,CAAC,YAAY,oBAAoB,SAAS,MAAM;AAAA,IACxD,QAAQ,CAAC,eAAe,IAAI,IAAI,QAAQ,WAAW,KAAKJ,YAAW,CAAC,EAAE;AAAA,IACtE;AAAA,IACA,OAAO,YAAY;AAAA,IACnB,IAAI,SAAS;AAAA,IACb,MAAM,WAAW;AAAA,EACnB;AACF;AAEA,SAAS,oBAAoB,EAAE,YAAY,MAAM,GAAmB,cAAiD;AACnH,QAAM,SAAS,cAAc,WAAW,QAAQ,sFAA+B;AAC/E,MAAI,CAACC,QAAO,KAAK,MAAM,EAAG,OAAM,IAAI,aAAa,mBAAmB,kCAA6B;AACjG,QAAM,MAAM,QAAQ,WAAW,KAAKD,YAAW;AAC/C,QAAM,SAAS,IAAI,IAAI,GAAG,EAAE;AAC5B,QAAM,OAAO,GAAG,GAAG,UAAU,MAAM;AACnC,QAAM,UAAU;AAAA,IACd,QAAQ;AAAA,IACR,wBAAwB;AAAA,IACxB,GAAI,WAAW,UAAU,UAAa,WAAW,UAAU,KAAK,CAAC,IAAI,EAAE,eAAe,UAAU,WAAW,KAAK,GAAG;AAAA,EACrH;AACA,QAAM,SAAS,CAAC,QAAwB;AACtC,QAAI,CAACE,QAAO,KAAK,GAAG,EAAG,OAAM,IAAI,aAAa,iBAAiB,yEAAuB,GAAG,GAAG;AAC5F,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,OAAO,QAAkD;AACrE,UAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,gBAAgB,KAAK,CAAC;AAC7G,WAAO,SAAS,IAAI,IAAI,OAAO,CAAC;AAAA,EAClC;AACA,SAAO;AAAA,IACL,MAAM,OAAO,UAAU;AACrB,sBAAgBC,eAAc,aAAa,MAAM,OAAO,aAAa;AACrE,sBAAgB,MAAM,MAAM;AAC5B,YAAM,OAAOE,QAAO,MAAM,MAAM;AAEhC,YAAM,SAAS,YAAY,KAAK;AAChC,YAAM,SAAS,SAAS,aAAa,QAAQ,OAAO,IAAI,IAAI,aAAa,OAAO,IAAI;AACpF,YAAM,EAAE,MAAM,SAAS,gBAAgB,IAAI,MAAM,YAAY,GAAG,SAAS,GAAG,GAAG,mBAAmB,IAAI,IAAI,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,QAAQ,CAAC;AACzJ,aAAO,YAAYC,QAAO,MAAM,MAAM,GAAG,OAAO,gBAAgB,IAAI,MAAM,KAAK,IAAI,IAAI;AAAA,IACzF;AAAA,IACA,KAAK,OAAO,QAAQ,QAAQ,MAAM,MAAM,GAAG,CAAC;AAAA,IAC5C,QAAQ,OAAO,UAAU;AACvB,YAAM,SAAS,cAAc,MAAM,UAAU,CAAC,GAAG,MAAM,UAAU,MAAS;AAC1E,YAAM,OAAO;AAAA,QACX,OAAO,MAAM;AAAA,QACb,GAAI,MAAM,gBAAgB,SAAY,CAAC,IAAI,EAAE,MAAM,MAAM,YAAY;AAAA,QACrE,GAAI,OAAO,WAAW,IAAI,CAAC,IAAI,EAAE,OAAO;AAAA,QACxC,GAAI,MAAM,aAAa,SAAY,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,QAAQ,EAAE;AAAA,MACxE;AACA,aAAO,SAAS,MAAM,YAAY,MAAM,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,KAAK,CAAC,GAAG,IAAI;AAAA,IACjG;AAAA,IACA,QAAQ,OAAO,KAAK,UAAU;AAC5B,YAAM,UAAU,MAAM,WAAW,UAAa,MAAM,aAAa,UAAa,MAAM,WAAW,SAAY,SAAY,QAAQ,MAAM,MAAM,GAAG,CAAC;AAC/I,YAAM,WAAW,MAAM,YAAY,GAAG,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,QAAQ,SAAS,MAAMC,WAAU,OAAO,OAAO,GAAG,gBAAgB,KAAK,CAAC;AAC/J,aAAO,QAAQ,SAAS,IAAI;AAAA,IAC9B;AAAA,IACA,UAAU,OAAO,KAAK,UAAU;AAC9B,yBAAmBH,mBAAkB,aAAa,UAAU,KAAK;AACjE,YAAM,OAAOC,QAAO,MAAM,MAAM;AAChC,YAAM,SAAS,IAAI,gBAAgB,EAAE,UAAU,OAAO,MAAM,KAAK,GAAG,MAAM,OAAO,IAAI,EAAE,CAAC;AAExF,UAAI,MAAM,iBAAiB,OAAW,QAAO,IAAI,SAAS,QAAQ,MAAM,YAAY,CAAC;AACrF,YAAM,EAAE,MAAM,SAAS,gBAAgB,IAAI,MAAM,YAAY,GAAG,IAAI,IAAI,OAAO,GAAG,CAAC,aAAa,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,gBAAgB,KAAK,CAAC;AACrK,aAAO,EAAE,QAAQ,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,GAAG,IAAIG,UAAS,GAAG,GAAI,aAAa,KAAK,gBAAgB,IAAI,MAAM,KAAK,EAAE,IAAI,EAAE,YAAY,OAAO,OAAO,CAAC,EAAE,IAAI,CAAC,EAAG;AAAA,IACtK;AAAA,IACA,SAAS,OAAO,KAAK,SAASA,YAAW,MAAM,YAAY,GAAG,IAAI,IAAI,OAAO,GAAG,CAAC,aAAa,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,MAAM,EAAE,KAAK,GAAG,gBAAgB,KAAK,CAAC,GAAG,IAAI;AAAA,EACvL;AACF;AAEA,SAASH,QAAO,QAAoC;AAClD,QAAM,OAAO,WAAW,SAAY,IAAI,OAAO,MAAM;AACrD,SAAO,OAAO,UAAU,IAAI,KAAK,QAAQ,IAAI,OAAO;AACtD;AAGA,SAASI,aAAY,QAA4D;AAC/E,MAAI,WAAW,OAAW,QAAO;AACjC,MAAI,OAAO,MAAM,CAAC,SAAS,SAAS,UAAU,SAAS,aAAa,EAAG,QAAO;AAC9E,MAAI,OAAO,MAAM,CAAC,SAAS,SAAS,UAAU,SAAS,UAAU,EAAG,QAAO;AAC3E,SAAO;AACT;AAGA,SAAS,YAAY,OAA4B;AAC/C,SAAO,MAAM,WAAW,UAAa,MAAM,iBAAiB,UAAa,MAAM,kBAAkB,UAAa,MAAM,kBAAkB;AACxI;AAGA,SAAS,gBAAgB,QAA6C;AACpE,MAAI,QAAQ,KAAK,CAAC,UAAU,MAAM,SAAS,GAAG,CAAC,MAAM,KAAM,OAAM,IAAI,aAAa,mBAAmB,GAAGN,aAAY,uLAAsC;AAC5J;AAGA,SAAS,aAAa,OAAmB,MAA+B;AACtE,QAAM,SAAS,IAAI,gBAAgB,EAAE,OAAOM,aAAY,MAAM,MAAM,GAAG,UAAU,OAAO,MAAM,KAAK,GAAG,MAAM,OAAO,IAAI,EAAE,CAAC;AAC1H,MAAI,MAAM,WAAW,UAAa,MAAM,OAAO,SAAS,EAAG,QAAO,IAAI,UAAU,MAAM,OAAO,KAAK,GAAG,CAAC;AACtG,MAAI,MAAM,aAAa,OAAW,QAAO,IAAI,YAAY,MAAM,YAAY,MAAM;AACjF,MAAI,MAAM,WAAW,OAAW,QAAO,IAAI,WAAW,MAAM,MAAM;AAClE,MAAI,MAAM,iBAAiB,OAAW,QAAO,IAAI,SAAS,QAAQ,MAAM,YAAY,CAAC;AACrF,MAAI,MAAM,SAAS,QAAW;AAC5B,WAAO,IAAI,QAAQ,MAAM,KAAK,KAAK;AACnC,WAAO,IAAI,aAAa,MAAM,KAAK,aAAa,MAAM;AAAA,EACxD;AACA,SAAO;AACT;AAIA,SAAS,aAAa,QAAgB,OAAmB,MAA+B;AACtF,QAAM,SAAS,IAAI,gBAAgB,EAAE,GAAG,YAAY,QAAQ,KAAK,GAAG,UAAU,OAAO,MAAM,KAAK,GAAG,MAAM,OAAO,IAAI,EAAE,CAAC;AACvH,QAAM,OAAO,MAAM;AACnB,SAAO,IAAI,QAAQ,MAAM,SAAS,SAAS;AAC3C,SAAO,IAAI,SAAS,MAAM,aAAa,MAAM;AAC7C,SAAO;AACT;AAGA,SAAS,YAAY,QAAgB,OAA2B;AAC9D,QAAM,QAAkB,CAAC,QAAQ,MAAM,IAAI,UAAU;AACrD,QAAM,QAAQ,kBAAkB,MAAM,MAAM;AAC5C,MAAI,UAAU,OAAW,OAAM,KAAK,KAAK;AACzC,aAAW,SAAS,MAAM,UAAU,CAAC,EAAG,OAAM,KAAK,SAAS,OAAO,KAAK,CAAC,EAAE;AAC3E,MAAI,MAAM,aAAa,OAAW,OAAM,KAAK,MAAM,aAAa,OAAO,gBAAgB,YAAY,OAAO,MAAM,QAAQ,CAAC,EAAE;AAC3H,MAAI,MAAM,WAAW,OAAW,OAAM,KAAK,UAAU,OAAO,MAAM,MAAM,CAAC,EAAE;AAC3E,QAAM,UAAU,mBAAmB,WAAW,MAAM,cAAc,MAAM,aAAa;AACrF,MAAI,YAAY,OAAW,OAAM,KAAK,OAAO;AAC7C,QAAM,UAAU,mBAAmB,WAAW,MAAM,cAAc,MAAM,aAAa;AACrF,MAAI,YAAY,OAAW,OAAM,KAAK,OAAO;AAC7C,MAAI,MAAM,WAAW,OAAW,OAAM,KAAK,OAAO,MAAM,MAAM,CAAC;AAC/D,SAAO,MAAM,KAAK,GAAG;AACvB;AAIA,SAAS,mBAAmB,OAA8B,OAA2B,QAAgD;AACnI,MAAI,UAAU,UAAa,WAAW,OAAW,QAAO,GAAG,KAAK,IAAI,QAAQ,KAAK,CAAC,KAAK,QAAQ,MAAM,CAAC;AACtG,MAAI,UAAU,OAAW,QAAO,GAAG,KAAK,MAAM,QAAQ,KAAK,CAAC;AAC5D,MAAI,WAAW,OAAW,QAAO,GAAG,KAAK,MAAM,QAAQ,MAAM,CAAC;AAC9D,SAAO;AACT;AAGA,SAASH,QAAO,MAAe,QAAqC;AAClE,MAAI,CAAC,OAAQ,QAAO,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC;AAClD,SAAO,SAAS,IAAI,KAAK,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,QAAQ,CAAC;AACrE;AAGA,SAAS,kBAAkB,QAAwE;AACjG,MAAI,WAAW,OAAW,QAAO;AACjC,MAAI,OAAO,MAAM,CAAC,SAAS,SAAS,UAAU,SAAS,aAAa,EAAG,QAAO;AAC9E,MAAI,OAAO,MAAM,CAAC,SAAS,SAAS,UAAU,SAAS,UAAU,EAAG,QAAO;AAC3E,SAAO;AACT;AAGA,SAAS,YAAY,MAA0B,OAAmB,MAAc,MAAkC;AAChH,QAAM,QAAQ,KAAK,OAAO,CAAC,QAAQ,SAAS,GAAG,KAAK,IAAI,iBAAiB,MAAS,EAAE,IAAI,OAAO;AAC/F,SAAO;AAAA,IACL,OAAO,MAAM,WAAW,SAAY,QAAQ,MAAM,OAAO,CAAC,UAAU,MAAM,QAAQ,SAAS,MAAM,OAAO,QAAQ,MAAM,IAAI;AAAA,IAC1H,GAAI,aAAa,KAAK,IAAI,IAAI,EAAE,YAAY,OAAO,OAAO,CAAC,EAAE,IAAI,CAAC;AAAA,EACpE;AACF;AAGA,SAAS,cAAc,OAA0B,UAAqC,QAAmD;AACvI,QAAM,gBAAgB,aAAa,SAAY,SAAY,aAAa,wBAAwB,QAAQ;AACxG,SAAO,CAAC,GAAG,OAAO,GAAI,kBAAkB,SAAY,CAAC,IAAI,CAAC,aAAa,GAAI,GAAI,WAAW,gBAAgB,CAAC,wBAAwB,IAAI,CAAC,CAAE;AAC5I;AAEA,SAASC,WAAU,OAAwB,SAAqD;AAC9F,QAAM,SAAS,MAAM,UAAU,SAAS,OAAO;AAC/C,QAAM,gBAAgB,MAAM,WAAW,UAAa,MAAM,aAAa,UAAa,MAAM,WAAW;AACrG,SAAO;AAAA,IACL,GAAI,MAAM,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;AAAA,IAC1D,GAAI,MAAM,gBAAgB,SAAY,CAAC,IAAI,EAAE,MAAM,MAAM,YAAY;AAAA,IACrE,GAAI,MAAM,WAAW,SAAY,CAAC,IAAI,EAAE,OAAO,MAAM,WAAW,UAAU,MAAM,WAAW,aAAa,WAAW,QAAQ,GAAI,MAAM,WAAW,aAAa,EAAE,cAAc,cAAc,IAAI,MAAM,WAAW,SAAS,EAAE,cAAc,YAAY,IAAI,EAAE,cAAc,WAAW,EAAG;AAAA,IACvR,GAAI,gBAAgB,EAAE,QAAQ,cAAc,MAAM,UAAU,SAAS,UAAU,CAAC,GAAG,MAAM,YAAY,SAAS,UAAU,MAAM,EAAE,IAAI,CAAC;AAAA,IACrI,GAAI,MAAM,aAAa,SAAY,CAAC,IAAI,EAAE,WAAW,MAAM,aAAa,OAAO,CAAC,IAAI,CAAC,MAAM,QAAQ,EAAE;AAAA,EACvG;AACF;AAEA,SAAS,QAAQ,KAAqB;AACpC,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,QAAQ,MAAM,QAAQ,KAAK,MAAM,IAAI,WAAW,KAAK,OAAO,IAAI,CAAC,UAAW,SAAS,KAAK,IAAI,MAAM,OAAO,KAAM,CAAC,IAAI,CAAC;AAC7H,QAAM,SAAS,KAAK,UAAU;AAC9B,QAAM,WAAgC,SAAS,OAAO,sBAAsB,KAAK,cAAc,MAAM,IAAI,MAAM,SAAS,wBAAwB,IAAI,gBAAgB;AACpK,QAAM,WAAW,MAAM,IAAI,CAAC,SAAS,OAAkC,wBAAwB,MAAM,MAAS,CAAC,EAAE,KAAK,CAAC,UAAU,UAAU,MAAS;AACpJ,QAAM,cAAc,KAAK,KAAK,IAAI;AAClC,QAAM,WAAW,SAAS,KAAK,QAAQ,IAAI,KAAK,KAAK,SAAS,KAAK,IAAI;AACvE,QAAM,MAAM,KAAK,KAAK,QAAQ;AAC9B,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,QAAM,SAAS,OAAO,KAAK,WAAW,WAAW,OAAO,KAAK,MAAM,IAAI;AACvE,SAAO;AAAA,IACL,KAAK;AAAA,IACL,OAAO,KAAK,KAAK,KAAK,KAAK;AAAA,IAC3B,GAAI,gBAAgB,SAAY,CAAC,IAAI,EAAE,YAAY;AAAA,IACnD,QAAQ,EAAE,UAAU,MAAM,SAAS,SAAS,OAAO,KAAK,iBAAiB,WAAW,KAAK,KAAK,YAAY,MAAM,EAAE,KAAK,aAAa,gBAAgB,gBAAgB,OAAO;AAAA,IAC3K,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS;AAAA,IAC7C,QAAQ,MAAM,OAAO,CAAC,SAAS,SAAS,4BAA4B,CAAC,OAAO,OAAO,wBAAwB,IAAI,CAAC;AAAA,IAChH,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS;AAAA,IAC7C,OAAO,QAAQ,SAAY,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,SAAS,CAAC;AAAA,IACzD,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,EACjD;AACF;AAEA,SAASC,WAAU,KAA4B;AAC7C,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,SAAS,SAAS,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,KAAK,IAAI;AAC7D,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,SAAO,EAAE,IAAI,OAAO,KAAK,OAAO,WAAW,OAAO,KAAK,EAAE,IAAI,KAAK,GAAI,WAAW,SAAY,CAAC,IAAI,EAAE,OAAO,GAAI,MAAM,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,IAAI,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU,EAAG;AACzN;;;AC/OA,IAAME,eAAc;AACpB,IAAMC,UAAS;AACf,IAAM,MAAM;AACZ,IAAMC,OAAM;AAGZ,IAAMC,qBAA6C;AAAA,EACjD,MAAM,EAAE,SAAS,wBAAwB,SAAS,YAAY,CAAC,QAAQ,GAAG,OAAO,CAAC,WAAW,WAAW,OAAO,EAAE;AAAA,EACjH,UAAU,EAAE,SAAS,iBAAiB,YAAY,iBAAiB,OAAO,CAAC,OAAO,MAAM,EAAE;AAAA,EAC1F,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,QAAQ,CAAC,SAAS,eAAe,QAAQ;AAAA,EACzC,UAAU,CAAC,SAAS,QAAQ,QAAQ;AAAA,EACpC,SAAS;AAAA,EACT,OAAO,CAAC,SAAS,QAAQ;AAAA,EACzB,qBAAqB;AACvB;AAGA,IAAM,WAA6C,EAAE,SAAS,cAAc,SAAS,cAAc,OAAO,QAAQ;AAE3G,SAAS,cAAqC;AACnD,SAAO;AAAA,IACL,cAAcA;AAAA,IACd,QAAQ,CAAC,YAAY,wBAAwB,OAAO;AAAA,EACtD;AACF;AAEA,SAAS,wBAAwB,EAAE,YAAY,MAAM,GAAuC;AAC1F,QAAM,SAAS,cAAc,WAAW,QAAQ,qIAAgD;AAChG,MAAI,CAACF,QAAO,KAAK,MAAM,EAAG,OAAM,IAAI,aAAa,mBAAmB,4GAAgD;AACpH,QAAM,OAAO,QAAQ,WAAW,KAAKD,YAAW;AAChD,QAAM,SAAS,IAAI,IAAI,IAAI,EAAE;AAC7B,QAAM,OAAO,GAAG,IAAI,oBAAoB,mBAAmB,MAAM,CAAC;AAClE,QAAM,UAAkC,WAAW,UAAU,UAAa,WAAW,UAAU,KAAK,CAAC,IAAI,EAAE,iBAAiB,WAAW,MAAM;AAC7I,QAAM,MAAM,CAAC,QAAwB;AACnC,QAAI,CAAC,IAAI,KAAK,GAAG,EAAG,OAAM,IAAI,aAAa,aAAa,uCAAmB,GAAG,GAAG;AACjF,WAAO;AAAA,EACT;AACA,QAAM,YAAY,OAAO,QAAsCI,SAAQ,MAAM,YAAY,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,EAAE,SAAS,aAAa,SAAS,uCAAmB,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI;AACxN,SAAO;AAAA,IACL,MAAM,OAAO,UAAU;AACrB,sBAAgB,aAAaD,mBAAkB,MAAM,OAAO,wBAAwB,OAAO;AAC3F,YAAM,SAASE,cAAa,MAAM,MAAM;AACxC,YAAM,OAAOC,QAAO,MAAM,MAAM;AAChC,YAAM,SAAS,IAAI,gBAAgB;AAAA,QACjC,OAAOC,aAAY,MAAM;AAAA,QACzB,UAAU,OAAO,MAAM,KAAK;AAAA,QAC5B,MAAM,OAAO,IAAI;AAAA,QACjB,UAAU,MAAM,SAAS,SAAY,eAAgB,SAAS,MAAM,KAAK,KAAK,KAAK;AAAA,QACnF,MAAM,MAAM,MAAM,aAAa;AAAA,MACjC,CAAC;AACD,UAAI,MAAM,WAAW,UAAa,MAAM,OAAO,SAAS,GAAG;AACzD,YAAI,MAAM,OAAO,KAAK,CAAC,UAAU,MAAM,SAAS,GAAG,CAAC,EAAG,OAAM,IAAI,aAAa,mBAAmB,gMAA+C;AAChJ,eAAO,IAAI,UAAU,MAAM,OAAO,KAAK,GAAG,CAAC;AAAA,MAC7C;AACA,UAAI,MAAM,WAAW,OAAW,QAAO,IAAI,mBAAmB,MAAM,MAAM;AAC1E,UAAI,MAAM,WAAW,OAAW,QAAO,IAAI,iBAAiB,MAAM,MAAM;AACxE,UAAI,MAAM,WAAW,OAAW,QAAO,IAAI,iBAAiB,MAAM,MAAM;AACxE,UAAI,MAAM,WAAW,OAAW,QAAO,IAAI,UAAU,MAAM,MAAM;AACjE,UAAI,MAAM,iBAAiB,OAAW,QAAO,IAAI,iBAAiB,QAAQ,MAAM,YAAY,CAAC;AAC7F,UAAI,MAAM,kBAAkB,OAAW,QAAO,IAAI,kBAAkB,QAAQ,MAAM,aAAa,CAAC;AAChG,UAAI,MAAM,iBAAiB,OAAW,QAAO,IAAI,iBAAiB,QAAQ,MAAM,YAAY,CAAC;AAC7F,UAAI,MAAM,kBAAkB,OAAW,QAAO,IAAI,kBAAkB,QAAQ,MAAM,aAAa,CAAC;AAChG,YAAM,EAAE,MAAM,SAAS,gBAAgB,IAAI,MAAM,YAAY,GAAG,IAAI,IAAI,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,QAAQ,CAAC;AACvH,YAAM,OAAO,gBAAgB,IAAI,aAAa;AAC9C,YAAM,SAAS,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,GAAG,IAAIH,OAAM;AAE1D,aAAO;AAAA,QACL,OAAO,WAAW,SAAY,QAAQ,MAAM,OAAO,CAAC,OAAO,OAAO,SAAS,GAAG,OAAO,QAAQ,MAAM,IAAI;AAAA,QACvG,GAAI,SAAS,QAAQ,SAAS,KAAK,CAAC,IAAI,EAAE,YAAY,KAAK;AAAA,MAC7D;AAAA,IACF;AAAA,IACA,KAAK;AAAA,IACL,QAAQ,OAAO,UAAU;AACvB,YAAM,OAAO;AAAA,QACX,eAAe,MAAM;AAAA,QACrB,eAAe,MAAM;AAAA,QACrB,QAAQ,MAAM,UAAU,OAAO,sBAAsB,MAAM,MAAM;AAAA,QACjE,GAAI,MAAM,gBAAgB,SAAY,CAAC,IAAI,EAAE,aAAa,MAAM,YAAY;AAAA,MAC9E;AACA,aAAOA,SAAQ,MAAM,YAAY,MAAM,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,MAAM,YAAY,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI;AAAA,IACnH;AAAA,IACA,QAAQ,OAAO,KAAK,UAAU;AAC5B,YAAM,UAAU,MAAM,WAAW,SAAY,SAAY,MAAM,UAAU,GAAG;AAC5E,UAAI,MAAM,WAAW,WAAW,SAAS,OAAO,aAAa,UAAU;AACrE,cAAM,IAAI,aAAa,eAAe,uOAAwD;AAAA,MAChG;AACA,YAAM,OAAOI,WAAU,OAAO,OAAO;AAErC,UAAI,OAAO,KAAK,IAAI,EAAE,WAAW,EAAG,QAAO,WAAWJ,SAAQ,MAAM,YAAY,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,EAAE,SAAS,aAAa,SAAS,uCAAmB,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI;AAC/M,aAAOA,SAAQ,MAAM,YAAY,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,QAAQ,OAAO,MAAM,SAAS,EAAE,SAAS,aAAa,SAAS,uCAAmB,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI;AAAA,IACvL;AAAA,IACA,OAAO,OAAO,KAAK,UAAU;AAC3B,UAAI,MAAM,WAAW,UAAa,CAACD,mBAAkB,MAAM,SAAS,MAAM,MAAM,GAAG;AACjF,cAAM,IAAI,aAAa,eAAe,0GAA+B,MAAM,MAAM,qGAAqB;AAAA,MACxG;AACA,YAAM,OAAO;AAAA;AAAA,QAEX,GAAI,MAAM,WAAW,WAAW,EAAE,QAAQ,KAAK,IAAI,CAAC;AAAA,QACpD,GAAI,MAAM,YAAY,SAAY,CAAC,IAAI,MAAM,WAAW,WAAW,EAAE,uBAAuB,MAAM,QAAQ,IAAI,EAAE,sBAAsB,MAAM,QAAQ;AAAA,QACpJ,GAAI,MAAM,iBAAiB,SAAY,CAAC,IAAI,EAAE,6BAA6B,MAAM,aAAa;AAAA,QAC9F,GAAI,MAAM,YAAY,SAAY,CAAC,IAAI,EAAE,KAAK,MAAM,QAAQ;AAAA,MAC9D;AACA,aAAOC,SAAQ,MAAM,YAAY,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,UAAU,EAAE,OAAO,QAAQ,SAAS,QAAQ,OAAO,MAAM,YAAY,CAAC,KAAK,KAAK,GAAG,GAAG,SAAS,EAAE,SAAS,aAAa,SAAS,uCAAmB,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI;AAAA,IAC1N;AAAA,IACA,UAAU,OAAO,KAAK,UAAU;AAC9B,yBAAmB,6EAAsBD,mBAAkB,UAAU,KAAK;AAC1E,YAAM,OAAOG,QAAO,MAAM,MAAM;AAChC,YAAM,SAAS,IAAI,gBAAgB,EAAE,MAAM,MAAM,SAAS,OAAO,UAAU,cAAc,UAAU,OAAO,MAAM,KAAK,GAAG,MAAM,OAAO,IAAI,EAAE,CAAC;AAC5I,YAAM,EAAE,MAAM,SAAS,gBAAgB,IAAI,MAAM,YAAY,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,UAAU,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,EAAE,SAAS,aAAa,SAAS,uCAAmB,GAAG,IAAI,EAAE,CAAC;AAChN,YAAM,OAAO,gBAAgB,IAAI,aAAa;AAE9C,YAAM,SAAS,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,GAC1C,OAAO,CAAC,SAAS,SAAS,IAAI,KAAK,KAAK,WAAW,QAAQ,YAAY,YAAY,KAAK,UAAU,GAAG,MAAM,cAAc,MAAS,CAAC,EACnI,IAAIG,UAAS;AAChB,aAAO,EAAE,OAAO,GAAI,SAAS,QAAQ,SAAS,KAAK,CAAC,IAAI,EAAE,YAAY,KAAK,EAAG;AAAA,IAChF;AAAA,IACA,SAAS,OAAO,KAAK,SAASA,YAAW,MAAM,YAAY,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,UAAU,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,MAAM,EAAE,KAAK,GAAG,SAAS,EAAE,SAAS,aAAa,SAAS,uCAAmB,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI;AAAA,EAClO;AACF;AAEA,SAASH,QAAO,QAAoC;AAClD,QAAM,OAAO,WAAW,SAAY,IAAI,OAAO,MAAM;AACrD,SAAO,OAAO,UAAU,IAAI,KAAK,QAAQ,IAAI,OAAO;AACtD;AAGA,SAASC,aAAY,QAAkE;AACrF,MAAI,WAAW,OAAW,QAAO;AACjC,MAAI,OAAO,MAAM,CAAC,SAAS,SAAS,WAAW,SAAS,MAAM,EAAG,QAAO;AACxE,MAAI,OAAO,MAAM,CAAC,SAAS,SAAS,QAAQ,EAAG,QAAO;AACtD,MAAI,OAAO,MAAM,CAAC,SAAS,SAAS,QAAQ,EAAG,QAAO;AACtD,SAAO;AACT;AAIA,SAASC,WAAU,OAA8B,SAA2D;AAC1G,QAAM,OAAgC,CAAC;AACvC,MAAI,MAAM,gBAAgB,OAAW,MAAK,cAAc,MAAM;AAC9D,MAAI,MAAM,WAAW,OAAW,MAAK,gBAAgB,MAAM;AAC3D,MAAI,MAAM,WAAW,YAAY,SAAS,OAAO,aAAa,SAAU,MAAK,cAAc;AAC3F,MAAI,MAAM,WAAW,UAAU,SAAS,OAAO,aAAa,SAAU,MAAK,cAAc;AACzF,MAAI,MAAM,WAAW,WAAW,MAAM,WAAW,QAAQ;AAGvD,UAAM,QAAQ,MAAM,SAAS,SAAS,SAAS;AAC/C,UAAM,OAAO,MAAM,QAAQ,sBAAsB,EAAE;AAEnD,UAAM,OAAO,MAAM,WAAW,UAAU,sBAAsB,OAAO,SAAS,OAAO,aAAa,WAAW,UAAU,OAAO,OAAO,MAAM;AAC3I,QAAI,SAAS,UAAa,SAAS,SAAS,MAAO,MAAK,QAAQ;AAAA,EAClE,WAAW,MAAM,UAAU,UAAa,MAAM,UAAU,SAAS,OAAO;AACtE,SAAK,QAAQ,MAAM;AAAA,EACrB;AACA,SAAO;AACT;AAGA,SAASH,cAAa,QAA4G;AAChI,MAAI,WAAW,UAAa,OAAO,WAAW,EAAG,QAAO;AACxD,aAAW,QAAQ,QAAQ;AACzB,QAAI,CAAC,gCAAgC,QAAQ,SAAS,IAAI,GAAG;AAC3D,YAAM,IAAI,aAAa,mBAAmB,mLAA4C,OAAO,IAAI,CAAC,GAAG;AAAA,IACvG;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,WAAW,OAA0B;AAC5C,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACnC,QAAM,QAAQ,MAAM,IAAI,CAAC,SAAU,OAAO,SAAS,WAAW,OAAO,SAAS,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,MAAU;AAClH,SAAO,CAAC,GAAG,IAAI,IAAI,MAAM,OAAO,CAAC,SAAyB,SAAS,UAAa,SAAS,EAAE,CAAC,CAAC;AAC/F;AAEA,SAAS,UAAU,OAA0B;AAC3C,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACnC,QAAM,QAAQ,MAAM,IAAI,CAAC,SAAU,SAAS,IAAI,IAAI,KAAK,KAAK,QAAQ,IAAI,MAAU;AACpF,SAAO,CAAC,GAAG,IAAI,IAAI,MAAM,OAAO,CAAC,SAAyB,SAAS,UAAa,SAAS,EAAE,CAAC,CAAC;AAC/F;AAEA,SAASD,QAAO,KAA2B;AACzC,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,QAAQ,KAAK,KAAK,KAAK,KAAK;AAClC,QAAM,QAAQ,KAAK,UAAU;AAC7B,QAAM,WAAW,OAAkC,6BAA6B,OAAO,MAAM;AAC7F,QAAM,MAAM,OAAO,KAAK,QAAQ,WAAW,OAAO,KAAK,GAAG,IAAI;AAC9D,QAAM,cAAc,KAAK,KAAK,WAAW;AACzC,QAAM,SAAS,SAAS,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,QAAQ,IAAI;AACpE,QAAM,MAAM,KAAK,KAAK,GAAG;AACzB,QAAM,MAAM,KAAK,KAAK,OAAO;AAC7B,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,QAAM,WAAW,YAAY,KAAK,SAAS;AAC3C,QAAM,WAAW,YAAY,KAAK,SAAS;AAC3C,SAAO;AAAA,IACL;AAAA,IACA,OAAO,KAAK,KAAK,KAAK,KAAK;AAAA,IAC3B,GAAI,gBAAgB,SAAY,CAAC,IAAI,EAAE,YAAY;AAAA,IACnD,QAAQ,EAAE,UAAU,SAAS,aAAa,SAAS,UAAU,UAAU,MAAM,SAAS,aAAa,SAAS,UAAU,MAAM;AAAA,IAC5H,GAAI,WAAW,SAAY,CAAC,IAAI,EAAE,OAAO;AAAA,IACzC,QAAQ,KAAK,KAAK,aAAa,KAAK;AAAA,IACpC,QAAQ,KAAK,KAAK,aAAa,KAAK;AAAA,IACpC,GAAI,QAAQ,UAAaF,KAAI,KAAK,GAAG,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC;AAAA,IAC7D,QAAQ,WAAW,KAAK,MAAM;AAAA,IAC9B,WAAW,UAAU,KAAK,SAAS;AAAA,IACnC,OAAO,QAAQ,SAAY,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,SAAS,CAAC;AAAA,IACzD,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS;AAAA,IAC7C,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS;AAAA,EAC/C;AACF;AAEA,SAASO,WAAU,KAA4B;AAC7C,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,SAAS,SAAS,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,QAAQ,IAAI;AACpE,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,SAAO,EAAE,IAAI,OAAO,KAAK,OAAO,WAAW,OAAO,KAAK,EAAE,IAAI,KAAK,GAAI,WAAW,SAAY,CAAC,IAAI,EAAE,OAAO,GAAI,MAAM,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,IAAI,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU,EAAG;AACzN;;;AC/NA,IAAMC,eAAc;AACpB,IAAMC,UAAS;AACf,IAAMC,OAAM;AACZ,IAAMC,oBAAmB;AACzB,IAAMC,kBAAiB,mBAAmB;AAG1C,IAAMC,gBAAiC;AAAA,EACrC,UAAU,EAAE,SAASD,iBAAgB,YAAY,CAAC,GAAG,OAAO,CAAC,EAAE;AACjE;AAEO,SAAS,aAA6B;AAC3C,SAAO,EAAE,cAAcC,eAAc,QAAQ,CAAC,YAAY,wBAAwB,OAAO,EAAE;AAC7F;AAEA,SAAS,wBAAwB,EAAE,YAAY,MAAM,GAAgC;AACnF,QAAM,SAAS,cAAc,WAAW,QAAQ,qIAAgD;AAChG,MAAI,CAACJ,QAAO,KAAK,MAAM,EAAG,OAAM,IAAI,aAAa,mBAAmB,4GAAgD;AACpH,QAAM,OAAO,QAAQ,WAAW,KAAKD,YAAW;AAChD,QAAM,SAAS,IAAI,IAAI,IAAI,EAAE;AAC7B,QAAM,UAAU,GAAG,IAAI,oBAAoB,mBAAmB,MAAM,CAAC;AACrE,QAAM,UAAkC,WAAW,UAAU,UAAa,WAAW,UAAU,KAAK,CAAC,IAAI,EAAE,iBAAiB,WAAW,MAAM;AAC7I,QAAM,UAAU,EAAE,SAAS,aAAa,SAAS,+EAAwB,MAAM,IAAI;AACnF,SAAO;AAAA,IACL,KAAK,YAAYM,SAAQ,MAAM,YAAY,SAAS,EAAE,OAAO,QAAQ,SAAS,QAAQ,CAAC,GAAG,MAAM,MAAM;AAAA,IACtG,UAAU,OAAO,UAAU;AACzB,sBAAgBH,mBAAkBE,cAAa,UAAU,OAAOD,eAAc;AAC9E,YAAM,SAAS,IAAI,gBAAgB,EAAE,UAAU,OAAO,MAAM,KAAK,GAAG,MAAM,OAAOG,QAAO,MAAM,MAAM,CAAC,EAAE,CAAC;AACxG,UAAI,MAAM,WAAW,OAAW,QAAO,IAAI,UAAU,SAAS,MAAM,MAAM,CAAC;AAC3E,YAAM,EAAE,MAAM,SAAS,gBAAgB,IAAI,MAAM,YAAY,GAAG,OAAO,wBAAwB,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,QAAQ,CAAC;AACvJ,YAAM,OAAO,gBAAgB,IAAI,aAAa;AAC9C,aAAO,EAAE,QAAQ,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,GAAG,IAAIC,SAAQ,GAAG,GAAI,SAAS,QAAQ,SAAS,KAAK,CAAC,IAAI,EAAE,YAAY,KAAK,EAAG;AAAA,IACjI;AAAA,EACF;AACF;AAGA,SAASD,QAAO,QAAoC;AAClD,QAAM,OAAO,WAAW,SAAY,IAAI,OAAO,MAAM;AACrD,SAAO,OAAO,UAAU,IAAI,KAAK,QAAQ,IAAI,OAAO;AACtD;AASA,SAAS,SAAS,OAAuB;AACvC,QAAM,WAAW,MAAM,QAAQ,OAAO,EAAE,EAAE,QAAQ,OAAO,EAAE;AAC3D,SAAO,aAAa,KAAK,QAAQ;AACnC;AAGA,SAASD,QAAO,KAAc,QAAsB;AAClD,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,gBAAgB,KAAK,KAAK,cAAc;AAC9C,QAAM,cAAc,KAAK,KAAK,WAAW;AACzC,QAAM,aAAaG,cAAa,KAAK,UAAU;AAC/C,QAAM,MAAM,KAAK,KAAK,OAAO;AAC7B,SAAO;AAAA,IACL,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,KAAK,mBAAmB,KAAK;AAAA,IAC3D,GAAI,kBAAkB,SAAY,CAAC,IAAI,EAAE,cAAc;AAAA,IACvD,GAAI,gBAAgB,SAAY,CAAC,IAAI,EAAE,YAAY;AAAA,IACnD,GAAI,eAAe,SAAY,CAAC,IAAI,EAAE,WAAW;AAAA,IACjD,OAAO,QAAQ,SAAY,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,SAAS,CAAC;AAAA,EAC3D;AACF;AAGA,SAASD,UAAS,KAAsB;AACtC,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,MAAM,SAAS,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,EAAE,IAAI;AAC3D,SAAO;AAAA,IACL,MAAM,KAAK,KAAK,IAAI,KAAK;AAAA,IACzB,GAAI,QAAQ,UAAa,CAACN,KAAI,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI;AAAA,IACrD,GAAI,OAAO,KAAK,cAAc,YAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,IAC3E,GAAI,OAAO,KAAK,YAAY,YAAY,EAAE,WAAW,KAAK,QAAQ,IAAI,CAAC;AAAA,EACzE;AACF;AAGA,SAASO,cAAa,OAA4C;AAChE,QAAM,SAAS,qBAAqB,UAAU,KAAK;AACnD,SAAO,OAAO,UAAU,OAAO,OAAO;AACxC;;;AChFA,IAAMC,eAAc;AACpB,IAAMC,UAAS;AACf,IAAMC,OAAM;AAGZ,IAAM,qBAAwC;AAAA,EAC5C,MAAM,EAAE,SAAS,eAAe,YAAY,CAAC,QAAQ,GAAG,OAAO,CAAC,WAAW,WAAW,YAAY,OAAO,EAAE;AAAA,EAC3G,UAAU,EAAE,SAAS,iBAAiB,YAAY,iBAAiB,OAAO,CAAC,OAAO,MAAM,EAAE;AAC5F;AAGA,IAAMC,YAA8D;AAAA,EAClE,SAAS;AAAA,EACT,SAAS;AAAA,EACT,UAAU;AAAA,EACV,OAAO;AACT;AAEO,SAAS,gBAAmC;AACjD,SAAO;AAAA,IACL,YAAY;AAAA,MACV,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,QACN,EAAE,MAAM,UAAU,UAAU,MAAM,QAAQ,MAAM;AAAA,QAChD,EAAE,MAAM,SAAS,UAAU,MAAM,QAAQ,KAAK;AAAA,QAC9C,EAAE,MAAM,OAAO,UAAU,OAAO,QAAQ,MAAM;AAAA,MAChD;AAAA,MACA,UAAU,EAAE,QAAQ,MAAM,QAAQ,MAAM,SAAS,MAAM,UAAU,MAAM,QAAQ,MAAM,UAAU,OAAO,UAAU,CAAC,QAAQ,eAAe,MAAM,EAAE;AAAA,IAClJ;AAAA,IACA,QAAQ,CAAC,YAAY,oBAAoB,OAAO;AAAA,IAChD,QAAQ,CAAC,eAAe,IAAI,IAAI,QAAQ,WAAW,KAAKH,YAAW,CAAC,EAAE;AAAA,IACtE,QAAQ;AAAA,IACR,OAAO,YAAY;AAAA,IACnB,IAAI,SAAS;AAAA,IACb,MAAM,WAAW;AAAA,EACnB;AACF;AAEA,SAAS,oBAAoB,EAAE,YAAY,MAAM,GAAmC;AAClF,QAAM,SAAS,cAAc,WAAW,QAAQ,qIAAgD;AAChG,MAAI,CAACC,QAAO,KAAK,MAAM,EAAG,OAAM,IAAI,aAAa,mBAAmB,4GAAgD;AACpH,QAAM,OAAO,QAAQ,WAAW,KAAKD,YAAW;AAChD,QAAM,SAAS,IAAI,IAAI,IAAI,EAAE;AAC7B,QAAM,OAAO,GAAG,IAAI,oBAAoB,mBAAmB,MAAM,CAAC;AAClE,QAAM,UAAkC,WAAW,UAAU,UAAa,WAAW,UAAU,KAAK,CAAC,IAAI,EAAE,iBAAiB,WAAW,MAAM;AAC7I,QAAM,MAAM,CAAC,QAAwB;AACnC,QAAI,CAACE,KAAI,KAAK,GAAG,EAAG,OAAM,IAAI,aAAa,iBAAiB,yEAAuB,GAAG,GAAG;AACzF,WAAO;AAAA,EACT;AACA,QAAM,YAAY,OAAO,QAAgCE,UAAS,MAAM,YAAY,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,gBAAgB,KAAK,CAAC,GAAG,IAAI;AAClK,SAAO;AAAA,IACL,MAAM,OAAO,UAAU;AACrB,sBAAgB,+CAAiB,mBAAmB,MAAM,OAAO,aAAa;AAC9E,YAAM,OAAOC,QAAO,MAAM,MAAM;AAChC,YAAM,SAAS,IAAI,gBAAgB;AAAA,QACjC,OAAOC,aAAY,MAAM,MAAM;AAAA,QAC/B,UAAU,OAAO,MAAM,KAAK;AAAA,QAC5B,MAAM,OAAO,IAAI;AAAA,QACjB,UAAU,MAAM,SAAS,SAAY,eAAgBH,UAAS,MAAM,KAAK,KAAK,KAAK;AAAA,QACnF,MAAM,MAAM,MAAM,aAAa;AAAA,MACjC,CAAC;AACD,UAAI,MAAM,WAAW,UAAa,MAAM,OAAO,SAAS,GAAG;AACzD,YAAI,MAAM,OAAO,KAAK,CAAC,UAAU,MAAM,SAAS,GAAG,CAAC,EAAG,OAAM,IAAI,aAAa,mBAAmB,kOAAmD;AACpJ,eAAO,IAAI,UAAU,MAAM,OAAO,KAAK,GAAG,CAAC;AAAA,MAC7C;AACA,UAAI,MAAM,aAAa,OAAW,QAAO,IAAI,MAAM,aAAa,OAAO,gBAAgB,qBAAqB,MAAM,aAAa,OAAO,SAAS,MAAM,QAAQ;AAC7J,UAAI,MAAM,WAAW,OAAW,QAAO,IAAI,mBAAmB,MAAM,MAAM;AAC1E,UAAI,MAAM,WAAW,OAAW,QAAO,IAAI,UAAU,MAAM,MAAM;AACjE,UAAI,MAAM,iBAAiB,OAAW,QAAO,IAAI,iBAAiB,QAAQ,MAAM,YAAY,CAAC;AAC7F,UAAI,MAAM,kBAAkB,OAAW,QAAO,IAAI,kBAAkB,QAAQ,MAAM,aAAa,CAAC;AAChG,UAAI,MAAM,iBAAiB,OAAW,QAAO,IAAI,iBAAiB,QAAQ,MAAM,YAAY,CAAC;AAC7F,UAAI,MAAM,kBAAkB,OAAW,QAAO,IAAI,kBAAkB,QAAQ,MAAM,aAAa,CAAC;AAChG,YAAM,EAAE,MAAM,SAAS,gBAAgB,IAAI,MAAM,YAAY,GAAG,IAAI,IAAI,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,QAAQ,CAAC;AACvH,YAAM,SAAS,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,GAAG,IAAIC,QAAO;AAC3D,YAAM,OAAO,gBAAgB,IAAI,aAAa;AAC9C,aAAO;AAAA,QACL,OAAO,MAAM,WAAW,SAAY,QAAQ,MAAM,OAAO,CAAC,UAAU,MAAM,QAAQ,SAAS,MAAM,OAAO,QAAQ,MAAM,IAAI;AAAA,QAC1H,GAAI,SAAS,QAAQ,SAAS,KAAK,CAAC,IAAI,EAAE,YAAY,KAAK;AAAA,MAC7D;AAAA,IACF;AAAA,IACA,KAAK;AAAA,IACL,QAAQ,OAAO,UAAU;AACvB,YAAM,SAASG,eAAc,MAAM,UAAU,CAAC,GAAG,MAAM,UAAU,MAAS;AAC1E,YAAM,OAAO,EAAE,OAAO,MAAM,OAAO,GAAI,MAAM,gBAAgB,SAAY,CAAC,IAAI,EAAE,aAAa,MAAM,YAAY,GAAI,GAAI,OAAO,WAAW,IAAI,CAAC,IAAI,EAAE,QAAQ,OAAO,KAAK,GAAG,EAAE,EAAG;AAChL,aAAOH,UAAS,MAAM,YAAY,MAAM,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,KAAK,CAAC,GAAG,IAAI;AAAA,IACjG;AAAA,IACA,QAAQ,OAAO,KAAK,UAAU;AAC5B,YAAM,UAAU,MAAM,WAAW,UAAa,MAAM,aAAa,UAAa,MAAM,WAAW,SAAY,SAAY,MAAM,UAAU,GAAG;AAC1I,aAAOA,UAAS,MAAM,YAAY,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,QAAQ,OAAO,MAAMI,WAAU,OAAO,OAAO,GAAG,gBAAgB,KAAK,CAAC,GAAG,IAAI;AAAA,IAClK;AAAA,IACA,UAAU,OAAO,KAAK,UAAU;AAC9B,yBAAmB,6EAAsB,mBAAmB,UAAU,KAAK;AAC3E,YAAM,OAAOH,QAAO,MAAM,MAAM;AAChC,YAAM,SAAS,IAAI,gBAAgB,EAAE,MAAM,MAAM,SAAS,OAAO,UAAU,cAAc,UAAU,OAAO,MAAM,KAAK,GAAG,MAAM,OAAO,IAAI,EAAE,CAAC;AAC5I,YAAM,EAAE,MAAM,SAAS,gBAAgB,IAAI,MAAM,YAAY,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,UAAU,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,gBAAgB,KAAK,CAAC;AAC/J,YAAM,OAAO,gBAAgB,IAAI,aAAa;AAE9C,YAAM,SAAS,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,GAC1C,OAAO,CAAC,SAAS,SAAS,IAAI,KAAK,KAAK,WAAW,QAAQ,YAAY,YAAY,KAAK,UAAU,GAAG,MAAM,cAAc,MAAS,CAAC,EACnI,IAAII,UAAS;AAChB,aAAO,EAAE,OAAO,GAAI,SAAS,QAAQ,SAAS,KAAK,CAAC,IAAI,EAAE,YAAY,KAAK,EAAG;AAAA,IAChF;AAAA,IACA,SAAS,OAAO,KAAK,SAASA,YAAW,MAAM,YAAY,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,UAAU,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,MAAM,EAAE,KAAK,GAAG,gBAAgB,KAAK,CAAC,GAAG,IAAI;AAAA,EACjL;AACF;AAEA,SAASJ,QAAO,QAAoC;AAClD,QAAM,OAAO,WAAW,SAAY,IAAI,OAAO,MAAM;AACrD,SAAO,OAAO,UAAU,IAAI,KAAK,QAAQ,IAAI,OAAO;AACtD;AAEA,SAASC,aAAY,QAA4D;AAC/E,MAAI,WAAW,OAAW,QAAO;AACjC,MAAI,OAAO,MAAM,CAAC,SAAS,SAAS,UAAU,SAAS,aAAa,EAAG,QAAO;AAC9E,MAAI,OAAO,MAAM,CAAC,SAAS,SAAS,UAAU,SAAS,UAAU,EAAG,QAAO;AAC3E,SAAO;AACT;AAEA,SAASC,eAAc,OAA0B,UAAqC,QAAmD;AACvI,QAAM,gBAAgB,aAAa,SAAY,SAAY,aAAa,wBAAwB,QAAQ;AACxG,SAAO,CAAC,GAAG,OAAO,GAAI,kBAAkB,SAAY,CAAC,IAAI,CAAC,aAAa,GAAI,GAAI,WAAW,gBAAgB,CAAC,wBAAwB,IAAI,CAAC,CAAE;AAC5I;AAEA,SAASC,WAAU,OAAwB,SAAqD;AAC9F,QAAM,SAAS,MAAM,UAAU,SAAS,OAAO;AAC/C,QAAM,gBAAgB,MAAM,WAAW,UAAa,MAAM,aAAa,UAAa,MAAM,WAAW;AACrG,MAAI,MAAM,WAAW,WAAY,OAAM,IAAI,aAAa,mBAAmB,6IAAmC;AAC9G,SAAO;AAAA,IACL,GAAI,MAAM,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;AAAA,IAC1D,GAAI,MAAM,gBAAgB,SAAY,CAAC,IAAI,EAAE,aAAa,MAAM,YAAY;AAAA,IAC5E,GAAI,MAAM,WAAW,SAAY,CAAC,IAAI,EAAE,aAAa,MAAM,WAAW,SAAS,UAAU,SAAS;AAAA,IAClG,GAAI,gBAAgB,EAAE,QAAQD,eAAc,MAAM,UAAU,SAAS,UAAU,CAAC,GAAG,MAAM,YAAY,SAAS,UAAU,MAAM,EAAE,KAAK,GAAG,EAAE,IAAI,CAAC;AAAA,EACjJ;AACF;AAEA,SAASH,SAAQ,KAAqB;AACpC,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,QAAQ,WAAW,KAAK,MAAM;AACpC,QAAM,SAAS,KAAK,UAAU;AAC9B,QAAM,WAAgC,SAAS,SAAS,MAAM,SAAS,wBAAwB,IAAI,gBAAgB;AACnH,QAAM,WAAW,MAAM,IAAI,CAAC,SAAS,OAAkC,wBAAwB,MAAM,MAAS,CAAC,EAAE,KAAK,CAAC,UAAU,UAAU,MAAS;AACpJ,QAAM,cAAc,KAAK,KAAK,WAAW;AACzC,QAAM,YAAY,MAAM,QAAQ,KAAK,SAAS,IAAI,KAAK,YAAY,CAAC;AACpE,QAAM,QAAQ,UAAU,CAAC;AACzB,QAAM,WAAW,SAAS,KAAK,IAAI,KAAK,MAAM,QAAQ,IAAI;AAC1D,QAAM,MAAM,KAAK,KAAK,OAAO;AAC7B,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,QAAM,MAAM,OAAO,KAAK,QAAQ,WAAW,OAAO,KAAK,GAAG,IAAI;AAC9D,SAAO;AAAA,IACL;AAAA,IACA,OAAO,KAAK,KAAK,KAAK,KAAK;AAAA,IAC3B,GAAI,gBAAgB,SAAY,CAAC,IAAI,EAAE,YAAY;AAAA,IACnD,QAAQ,EAAE,UAAU,MAAM,SAAS,WAAW,aAAa,gBAAgB,gBAAgB,SAAS;AAAA,IACpG,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS;AAAA,IAC7C,QAAQ,MAAM,OAAO,CAAC,SAAS,SAAS,4BAA4B,CAAC,OAAO,OAAO,wBAAwB,IAAI,CAAC;AAAA,IAChH,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS;AAAA,IAC7C,OAAO,QAAQ,SAAY,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,SAAS,CAAC;AAAA,IACzD,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,EACjD;AACF;AAEA,SAASK,WAAU,KAA4B;AAC7C,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,SAAS,SAAS,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,QAAQ,IAAI;AACpE,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,SAAO,EAAE,IAAI,OAAO,KAAK,OAAO,WAAW,OAAO,KAAK,EAAE,IAAI,KAAK,GAAI,WAAW,SAAY,CAAC,IAAI,EAAE,OAAO,GAAI,MAAM,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,IAAI,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU,EAAG;AACzN;;;AC1KA,IAAM,cAAc;AACpB,IAAM,YAAY;AAClB,IAAM,SAAS;AACf,IAAM,eAAuE,EAAE,MAAM,WAAW,aAAa,iBAAiB,MAAM,OAAO;AAG3I,IAAMC,sBAAwC;AAAA,EAC5C,MAAM,EAAE,SAAS,eAAe,YAAY,CAAC,GAAG,OAAO,CAAC,WAAW,WAAW,YAAY,OAAO,EAAE;AAAA,EACnG,UAAU,EAAE,SAAS,iBAAiB,YAAY,iBAAiB,OAAO,CAAC,OAAO,MAAM,EAAE;AAC5F;AAGA,IAAM,mBAAkF,EAAE,SAAS,WAAW,SAAS,WAAW,UAAU,YAAY,OAAO,UAAU;AAElK,SAAS,cAAiC;AAC/C,SAAO;AAAA,IACL,YAAY;AAAA,MACV,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,QACN,EAAE,MAAM,OAAO,UAAU,MAAM,QAAQ,MAAM;AAAA,QAC7C,EAAE,MAAM,UAAU,UAAU,MAAM,QAAQ,MAAM;AAAA,QAChD,EAAE,MAAM,QAAQ,UAAU,OAAO,QAAQ,MAAM;AAAA,QAC/C,EAAE,MAAM,SAAS,UAAU,MAAM,QAAQ,KAAK;AAAA,MAChD;AAAA,MACA,UAAU,EAAE,QAAQ,MAAM,QAAQ,MAAM,SAAS,MAAM,UAAU,MAAM,QAAQ,MAAM,UAAU,OAAO,UAAU,CAAC,QAAQ,eAAe,MAAM,EAAE;AAAA,IAClJ;AAAA,IACA,QAAQ,CAAC,YAAY,kBAAkB,OAAO;AAAA,IAC9C,QAAQ,CAAC,eAAe,IAAI,IAAI,OAAO,UAAU,CAAC,EAAE;AAAA,IACpD,QAAQA;AAAA,EACV;AACF;AAGA,SAAS,OAAO,YAAkD;AAChE,MAAI,WAAW,QAAQ,OAAW,OAAM,IAAI,aAAa,mBAAmB,kFAAsB;AAClG,SAAO,QAAQ,WAAW,KAAK,WAAW,GAAG;AAC/C;AAEA,SAAS,kBAAkB,EAAE,YAAY,MAAM,GAAmC;AAChF,QAAM,OAAO,OAAO,UAAU;AAC9B,QAAM,UAAU,cAAc,WAAW,QAAQ,iIAAkC;AACnF,MAAI,CAAC,YAAY,KAAK,OAAO,EAAG,OAAM,IAAI,aAAa,mBAAmB,sNAAsD;AAChI,QAAM,SAAS,IAAI,IAAI,IAAI,EAAE;AAC7B,QAAM,MAAM,GAAG,IAAI;AACnB,QAAM,QAAQ,WAAW,SAAS;AAClC,QAAM,UAAU,EAAE,eAAe,WAAW,SAAS,SAAY,UAAU,KAAK,KAAK,SAAS,OAAO,KAAK,GAAG,WAAW,IAAI,IAAI,KAAK,EAAE,EAAE,SAAS,QAAQ,CAAC,GAAG;AAC9J,QAAM,MAAM,CAAC,UAA0B;AACrC,QAAI,CAAC,UAAU,KAAK,KAAK,EAAG,OAAM,IAAI,aAAa,iBAAiB,uEAAqB,KAAK,GAAG;AACjG,WAAO;AAAA,EACT;AACA,QAAMC,WAAU,CAAC,QAAwBC,SAAQ,KAAK,IAAI;AAC1D,QAAM,OAAO,OAAO,UAAkCD,UAAS,MAAM,YAAY,GAAG,GAAG,UAAU,IAAI,KAAK,CAAC,WAAW,MAAM,IAAI,EAAE,OAAO,QAAQ,SAAS,gBAAgB,KAAK,CAAC,GAAG,IAAI;AACvL,SAAO;AAAA,IACL,MAAM,OAAO,UAAU;AACrB,sBAAgB,6CAAeD,oBAAmB,MAAM,OAAO,aAAa;AAC5E,YAAM,MAAM,QAAQ,SAAS,KAAK;AAClC,UAAI,QAAQ,OAAW,QAAO,EAAE,OAAO,CAAC,EAAE;AAC1C,UAAI,MAAM,QAAQ,WAAW,IAAI,MAAM,MAAM;AAC3C,cAAMG,UAAS,IAAI,gBAAgB,EAAE,KAAK,QAAQ,QAAQ,YAAY,OAAO,MAAM,KAAK,EAAE,CAAC;AAC3F,YAAI,MAAM,WAAW,OAAW,CAAAA,QAAO,IAAI,iBAAiB,MAAM,MAAM;AACxE,YAAI;AACF,gBAAM,EAAE,MAAAC,MAAK,IAAI,MAAM,YAAY,GAAG,GAAG,eAAeD,QAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,QAAQ,CAAC;AACvG,gBAAME,UAAS,SAASD,KAAI,IAAIA,QAAO,CAAC;AACxC,gBAAM,OAAO,KAAKC,QAAO,aAAa;AACtC,iBAAO,EAAE,QAAQ,MAAM,QAAQA,QAAO,MAAM,IAAIA,QAAO,SAAS,CAAC,GAAG,IAAIJ,QAAO,GAAG,GAAI,SAAS,UAAaI,QAAO,WAAW,OAAO,CAAC,IAAI,EAAE,YAAY,KAAK,EAAG;AAAA,QAClK,SAAS,OAAO;AACd,cAAI,EAAE,iBAAiB,iBAAiB,CAAC,MAAM,QAAQ,SAAS,MAAM,EAAG,OAAM;AAAA,QACjF;AAAA,MACF;AACA,YAAM,UAAU,MAAM,QAAQ,WAAW,IAAI,MAAM,OAAO,OAAO,MAAM,OAAO,MAAM,CAAC,CAAC,IAAI;AAC1F,YAAM,SAAS,IAAI,gBAAgB,EAAE,KAAK,QAAQ,QAAQ,YAAY,OAAO,MAAM,KAAK,GAAG,SAAS,OAAO,OAAO,UAAU,OAAO,KAAK,WAAW,IAAI,UAAU,CAAC,EAAE,CAAC;AACrK,YAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,GAAG,WAAW,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,QAAQ,CAAC;AACnG,YAAM,SAAS,SAAS,IAAI,IAAI,OAAO,CAAC;AACxC,YAAM,SAAS,MAAM,QAAQ,OAAO,MAAM,IAAI,OAAO,SAAS,CAAC;AAC/D,YAAM,QAAQ,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AAChE,YAAM,KAAK,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;AACjE,aAAO,EAAE,OAAO,OAAO,IAAIJ,QAAO,GAAG,GAAI,KAAK,OAAO,SAAS,SAAS,OAAO,SAAS,IAAI,EAAE,YAAY,KAAK,OAAO,KAAK,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC,EAAG;AAAA,IACrJ;AAAA,IACA,KAAK;AAAA,IACL,QAAQ,OAAO,UAAU;AACvB,YAAM,SAAS;AAAA,QACb,SAAS,EAAE,KAAK,QAAQ;AAAA,QACxB,SAAS,MAAM;AAAA,QACf,WAAW,EAAE,MAAM,gBAAgB;AAAA,QACnC,GAAI,MAAM,gBAAgB,SAAY,CAAC,IAAI,EAAE,aAAa,MAAM,YAAY;AAAA,QAC5E,GAAI,MAAM,aAAa,SAAY,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,oBAAoB,MAAM,QAAQ,EAAE,EAAE;AAAA,QAClG,GAAI,MAAM,WAAW,SAAY,CAAC,IAAI,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC,UAAU,MAAM,QAAQ,QAAQ,GAAG,CAAC,EAAE;AAAA,MAC1G;AACA,YAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,GAAG,UAAU,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,MAAM,EAAE,OAAO,EAAE,CAAC;AAC/G,YAAM,UAAU,SAAS,IAAI,IAAI,KAAK,KAAK,GAAG,IAAI;AAClD,UAAI,YAAY,OAAW,OAAM,IAAI,aAAa,UAAU,mMAA6C;AACzG,aAAO,KAAK,OAAO;AAAA,IACrB;AAAA,IACA,QAAQ,OAAO,OAAO,UAAU;AAC9B,YAAM,SAAS,SAAS,KAAK;AAC7B,UAAI,OAAO,KAAK,MAAM,EAAE,SAAS,EAAG,OAAM,YAAY,GAAG,GAAG,UAAU,IAAI,KAAK,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,QAAQ,OAAO,MAAM,EAAE,OAAO,GAAG,gBAAgB,KAAK,CAAC;AACrK,UAAI,MAAM,WAAW,OAAW,OAAM,WAAW,KAAK,IAAI,KAAK,GAAG,MAAM,QAAQ,EAAE,OAAO,QAAQ,QAAQ,CAAC;AAC1G,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,IACA,UAAU,OAAO,OAAO,UAAU;AAChC,yBAAmB,2EAAoBD,oBAAmB,UAAU,KAAK;AACzE,YAAM,UAAU,MAAM,WAAW,SAAY,IAAI,OAAO,MAAM,MAAM;AACpE,YAAM,SAAS,IAAI,gBAAgB,EAAE,SAAS,OAAO,OAAO,UAAU,OAAO,KAAK,WAAW,IAAI,UAAU,CAAC,GAAG,YAAY,OAAO,MAAM,KAAK,GAAG,SAAS,MAAM,UAAU,SAAS,aAAa,UAAU,CAAC;AAC1M,YAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,GAAG,UAAU,IAAI,KAAK,CAAC,YAAY,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,gBAAgB,KAAK,CAAC;AAC9I,YAAM,SAAS,SAAS,IAAI,IAAI,OAAO,CAAC;AACxC,YAAM,MAAM,MAAM,QAAQ,OAAO,QAAQ,IAAI,OAAO,WAAW,CAAC;AAEhE,YAAM,QAAQ,IAAI,OAAO,CAAC,SAAS,YAAY,YAAY,SAAS,IAAI,IAAI,KAAK,UAAU,MAAS,GAAG,MAAM,cAAc,MAAS,CAAC;AACrI,YAAM,QAAQ,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AAChE,YAAM,KAAK,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;AACjE,aAAO,EAAE,OAAO,MAAM,IAAIM,UAAS,GAAG,GAAI,KAAK,IAAI,SAAS,SAAS,IAAI,SAAS,IAAI,EAAE,YAAY,OAAO,KAAK,IAAI,MAAM,EAAE,IAAI,CAAC,EAAG;AAAA,IACtI;AAAA,IACA,SAAS,OAAO,OAAO,SAASA,YAAW,MAAM,YAAY,GAAG,GAAG,UAAU,IAAI,KAAK,CAAC,YAAY,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,MAAM,EAAE,KAAK,GAAG,gBAAgB,KAAK,CAAC,GAAG,IAAI;AAAA,EAC5L;AACF;AAIA,SAAS,QAAQ,SAAiB,OAAuC;AACvE,QAAM,UAAoB,CAAC;AAC3B,MAAI,MAAM,WAAW,QAAW;AAC9B,UAAM,QAAQ,MAAM,OAAO,QAAQ,CAAC,SAAS,aAAa,IAAI,KAAK,CAAC,CAAC;AACrE,QAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,YAAQ,KAAK,sBAAsB,MAAM,KAAK,IAAI,CAAC,GAAG;AAAA,EACxD;AACA,aAAW,SAAS,MAAM,UAAU,CAAC,EAAG,SAAQ,KAAK,YAAY,OAAO,MAAM,QAAQ,QAAQ,GAAG,CAAC,CAAC,EAAE;AACrG,MAAI,MAAM,aAAa,OAAW,SAAQ,KAAK,MAAM,aAAa,OAAO,sBAAsB,cAAc,OAAO,MAAM,QAAQ,CAAC,EAAE;AACrI,MAAI,MAAM,WAAW,OAAW,SAAQ,KAAK,cAAc,OAAO,MAAM,MAAM,CAAC,EAAE;AACjF,MAAI,MAAM,WAAW,OAAW,SAAQ,KAAK,UAAU,OAAO,MAAM,MAAM,CAAC,EAAE;AAC7E,MAAI,MAAM,iBAAiB,OAAW,SAAQ,KAAK,cAAc,OAAO,SAAS,MAAM,cAAc,MAAM,CAAC,CAAC,EAAE;AAC/G,MAAI,MAAM,kBAAkB,OAAW,SAAQ,KAAK,cAAc,OAAO,SAAS,MAAM,eAAe,IAAI,CAAC,CAAC,EAAE;AAC/G,MAAI,MAAM,iBAAiB,OAAW,SAAQ,KAAK,cAAc,OAAO,SAAS,MAAM,cAAc,MAAM,CAAC,CAAC,EAAE;AAC/G,MAAI,MAAM,kBAAkB,OAAW,SAAQ,KAAK,cAAc,OAAO,SAAS,MAAM,eAAe,IAAI,CAAC,CAAC,EAAE;AAC/G,QAAM,OAAO,MAAM;AAEnB,QAAM,QAAS,SAAS,SAAY,YAAY,KAAK;AACrD,QAAM,YAAY,MAAM,aAAa;AACrC,SAAO,GAAG,CAAC,aAAa,OAAO,OAAO,CAAC,IAAI,GAAG,OAAO,EAAE,KAAK,OAAO,CAAC,aAAa,iBAAiB,KAAK,CAAC,IAAI,UAAU,YAAY,CAAC;AACrI;AAGA,SAAS,SAAS,IAAY,SAAgC;AAC5D,QAAM,KAAK,IAAI,KAAK,YAAY,SAAS,KAAK,MAAM,KAAK,GAAK,IAAI,MAAQ,KAAK,KAAK,KAAK,GAAK,IAAI,GAAK;AACvG,QAAM,MAAM,CAAC,UAA0B,OAAO,KAAK,EAAE,SAAS,GAAG,GAAG;AACpE,SAAO,GAAG,OAAO,GAAG,eAAe,CAAC,CAAC,IAAI,IAAI,GAAG,YAAY,IAAI,CAAC,CAAC,IAAI,IAAI,GAAG,WAAW,CAAC,CAAC,IAAI,IAAI,GAAG,YAAY,CAAC,CAAC,IAAI,IAAI,GAAG,cAAc,CAAC,CAAC;AAChJ;AAEA,SAAS,SAAS,OAAiD;AACjE,SAAO;AAAA,IACL,GAAI,MAAM,UAAU,SAAY,CAAC,IAAI,EAAE,SAAS,MAAM,MAAM;AAAA,IAC5D,GAAI,MAAM,gBAAgB,SAAY,CAAC,IAAI,EAAE,aAAa,MAAM,YAAY;AAAA,IAC5E,GAAI,MAAM,aAAa,SAAY,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,oBAAoB,MAAM,QAAQ,EAAE,EAAE;AAAA,IAClG,GAAI,MAAM,WAAW,SAAY,CAAC,IAAI,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC,UAAU,MAAM,QAAQ,QAAQ,GAAG,CAAC,EAAE;AAAA,EAC1G;AACF;AAGA,eAAe,WAAW,KAAa,KAAa,UAA+B,SAA6G;AAC9L,QAAM,EAAE,OAAO,QAAQ,QAAQ,IAAI;AACnC,QAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,GAAG,UAAU,GAAG,gBAAgB,EAAE,OAAO,QAAQ,SAAS,gBAAgB,KAAK,CAAC;AACtH,QAAM,OAAO,SAAS,IAAI,KAAK,MAAM,QAAQ,KAAK,WAAW,IAAI,KAAK,cAAc,CAAC;AACrF,QAAM,QAAQ,KAAK,KAAK,CAAC,SAAS;AAChC,QAAI,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,KAAK,EAAE,KAAK,CAAC,SAAS,KAAK,GAAG,cAAc,EAAG,QAAO;AACvF,WAAO,OAAwC,wBAAwB,KAAK,GAAG,eAAe,KAAK,MAAS,MAAM;AAAA,EACpH,CAAC;AACD,QAAM,KAAK,SAAS,KAAK,IAAI,KAAK,MAAM,EAAE,IAAI;AAC9C,MAAI,OAAO,OAAW,OAAM,IAAI,aAAa,mBAAmB,mPAAqD,QAAQ,GAAG;AAChI,QAAM,YAAY,GAAG,GAAG,UAAU,GAAG,gBAAgB,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,gBAAgB,KAAK,CAAC;AACrJ;AAEA,SAASJ,SAAQ,KAAc,MAAqB;AAClD,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,SAAS,SAAS,KAAK,MAAM,IAAI,KAAK,SAAS,CAAC;AACtD,QAAM,SAAS,SAAS,OAAO,MAAM,IAAI,OAAO,SAAS,CAAC;AAC1D,QAAM,WAAW,SAAS,OAAO,cAAc,IAAI,OAAO,eAAe,MAAM;AAC/E,QAAMK,gBAAe,SAAS,OAAO,QAAQ,KAAK,OAAO,OAAO,SAAS,SAAS,WAAW,OAAO,SAAS,KAAK,YAAY,IAAI;AAClI,QAAM,WAAW,OAAkC,iBAAiBA,eAAc,MAAS;AAC3F,QAAM,WAAW,SAAS,OAAO,QAAQ,IAAK,KAAK,OAAO,SAAS,WAAW,KAAK,KAAK,OAAO,SAAS,IAAI,IAAK;AACjH,QAAM,cAAc,KAAK,OAAO,WAAW;AAC3C,QAAM,YAAY,YAAY,OAAO,OAAO;AAC5C,QAAM,YAAY,YAAY,OAAO,OAAO;AAC5C,QAAM,MAAM,KAAK,KAAK,GAAG,KAAK;AAC9B,SAAO;AAAA,IACL;AAAA,IACA,OAAO,KAAK,OAAO,OAAO,KAAK;AAAA,IAC/B,GAAI,gBAAgB,SAAY,CAAC,IAAI,EAAE,YAAY;AAAA,IACnD,QAAQ,EAAE,UAAU,OAAO,wBAAwB,UAAU,MAAM,GAAG,MAAM,KAAK,OAAO,IAAI,KAAK,QAAQ;AAAA,IACzG,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS;AAAA,IAC7C,QAAQ,WAAW,OAAO,MAAM;AAAA,IAChC,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS;AAAA,IAC7C,OAAO,CAAC,EAAE,KAAK,GAAG,IAAI,WAAW,GAAG,IAAI,OAAO,OAAO,CAAC;AAAA,IACvD,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,EACjD;AACF;AAEA,SAASD,WAAU,KAA4B;AAC7C,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,SAAS,SAAS,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,WAAW,IAAI;AACvE,QAAM,YAAY,YAAY,KAAK,OAAO;AAC1C,SAAO,EAAE,IAAI,KAAK,KAAK,EAAE,KAAK,KAAK,GAAI,WAAW,SAAY,CAAC,IAAI,EAAE,OAAO,GAAI,MAAM,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,IAAI,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU,EAAG;AAC1L;;;AC5MA,IAAM,eAAe,EAAE,MAAM,QAAQ,aAAa,eAAe,MAAM,QAAQ,UAAU,WAAW;AAKpG,IAAME,sBAAwC;AAAA,EAC5C,MAAM;AAAA,IACJ,SAAS,CAAC,UAAU,UAAU,YAAY,UAAU,gBAAgB,iBAAiB,gBAAgB,eAAe;AAAA,IACpH,YAAY,CAAC,UAAU,YAAY,UAAU,gBAAgB,iBAAiB,gBAAgB,eAAe;AAAA,IAC7G,OAAO,CAAC;AAAA,EACV;AAAA,EACA,UAAU,EAAE,SAAS,iBAAiB,YAAY,iBAAiB,OAAO,CAAC,KAAK,EAAE;AACpF;AAEO,SAAS,eAAkC;AAChD,SAAO;AAAA,IACL,YAAY;AAAA,MACV,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ,CAAC;AAAA,MACT,UAAU,EAAE,QAAQ,MAAM,QAAQ,MAAM,SAAS,MAAM,UAAU,MAAM,QAAQ,MAAM,UAAU,MAAM,UAAU,CAAC,GAAG,YAAY,EAAE;AAAA,IACnI;AAAA,IACA,QAAQA;AAAA,IACR,QAAQ,CAAC,YAAY,mBAAmB,OAAO;AAAA,EACjD;AACF;AAEA,SAAS,mBAAmB,EAAE,OAAO,WAAW,OAAO,GAAmC;AACxF,QAAM,SAAS,CAAC,QAAwB;AACtC,QAAI,CAAC,kBAAkB,KAAK,GAAG,EAAG,OAAM,IAAI,aAAa,iBAAiB,oKAAkC,GAAG,GAAG;AAClH,WAAO,OAAO,GAAG;AAAA,EACnB;AACA,QAAM,UAAU,CAAC,QAA+B;AAC9C,UAAM,MAAM,MAAM,cAAc,WAAW,OAAO,GAAG,CAAC;AACtD,QAAI,QAAQ,OAAW,OAAM,IAAI,aAAa,iBAAiB,oKAAkC,GAAG,GAAG;AACvG,WAAO;AAAA,EACT;AACA,SAAO;AAAA;AAAA,IAEL,MAAM,OAAO,UAAU;AACrB,sBAAgB,8CAAgBA,oBAAmB,MAAM,OAAO,aAAa;AAC7E,YAAM,OAAO,MAAM,gBAAgB,WAAW,EAAE,OAAO,MAAM,OAAO,GAAI,MAAM,WAAW,SAAY,CAAC,IAAI,EAAE,QAAQ,MAAM,OAAO,GAAI,GAAI,MAAM,WAAW,SAAY,CAAC,IAAI,EAAE,QAAQ,MAAM,OAAO,EAAG,CAAC;AACtM,aAAO,EAAE,OAAO,KAAK,MAAM,OAAO,CAAC,QAAQ,kBAAkB,KAAK,KAAK,CAAC,EAAE,IAAI,OAAO,GAAG,GAAI,KAAK,eAAe,SAAY,CAAC,IAAI,EAAE,YAAY,KAAK,WAAW,EAAG;AAAA,IACpK;AAAA,IACA,KAAK,CAAC,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,GAAG,CAAC,CAAC;AAAA,IACnD,QAAQ,CAAC,UAAU,QAAQ,QAAQ,QAAQ,MAAM,iBAAiB,WAAW,KAAK,CAAC,CAAC;AAAA,IACpF,QAAQ,CAAC,KAAK,UAAU;AACtB,YAAM,MAAM,MAAM,iBAAiB,WAAW,QAAQ,GAAG,EAAE,QAAQ,KAAK;AACxE,UAAI,QAAQ,OAAW,OAAM,IAAI,aAAa,iBAAiB,oKAAkC,GAAG,GAAG;AACvG,aAAO,QAAQ,QAAQ,QAAQ,GAAG,CAAC;AAAA,IACrC;AAAA,IACA,UAAU,OAAO,KAAK,UAAU;AAC9B,yBAAmB,4EAAqBA,oBAAmB,UAAU,KAAK;AAC1E,YAAM,OAAO,MAAM,kBAAkB,WAAW,QAAQ,GAAG,EAAE,QAAQ,EAAE,OAAO,MAAM,OAAO,GAAI,MAAM,WAAW,SAAY,CAAC,IAAI,EAAE,QAAQ,MAAM,OAAO,EAAG,CAAC;AAE5J,YAAM,QAAQ,MAAM,iBAAiB,SAAY,KAAK,QAAQ,KAAK,MAAM,OAAO,CAAC,QAAQ,YAAY,IAAI,WAAW,MAAM,cAAc,MAAS,CAAC;AAClJ,aAAO,EAAE,OAAO,MAAM,IAAI,SAAS,GAAG,GAAI,KAAK,eAAe,SAAY,CAAC,IAAI,EAAE,YAAY,KAAK,WAAW,EAAG;AAAA,IAClH;AAAA,IACA,SAAS,CAAC,KAAK,SAAS,QAAQ,QAAQ,UAAU,MAAM,gBAAgB,WAAW,QAAQ,GAAG,EAAE,QAAQ,MAAM,MAAM,CAAC,CAAC;AAAA,EACxH;AACF;AAKA,SAAS,kBAAkB,KAAoB,OAA4B;AACzE,MAAI,MAAM,WAAW,UAAa,CAAC,MAAM,OAAO,MAAM,CAAC,UAAU,IAAI,OAAO,SAAS,KAAK,CAAC,EAAG,QAAO;AACrG,QAAM,WAAW,MAAM;AACvB,MAAI,aAAa,WAAc,aAAa,OAAO,IAAI,aAAa,SAAY,IAAI,aAAa,UAAW,QAAO;AACnH,MAAI,MAAM,WAAW,UAAa,CAAC,aAAa,CAAC,IAAI,OAAO,IAAI,WAAW,GAAG,MAAM,MAAM,EAAG,QAAO;AACpG,SAAO,YAAY,IAAI,WAAW,MAAM,cAAc,MAAM,aAAa,KAAK,YAAY,IAAI,WAAW,MAAM,cAAc,MAAM,aAAa;AAClJ;AAEA,SAAS,QAAQ,KAA2B;AAC1C,SAAO;AAAA,IACL,KAAK,OAAO,IAAI,MAAM;AAAA,IACtB,OAAO,IAAI;AAAA,IACX,GAAI,IAAI,gBAAgB,SAAY,CAAC,IAAI,EAAE,aAAa,IAAI,YAAY;AAAA,IACxE,QAAQ,EAAE,UAAU,IAAI,QAAQ,MAAM,aAAa,IAAI,MAAM,EAAE;AAAA,IAC/D,GAAI,IAAI,aAAa,SAAY,CAAC,IAAI,EAAE,UAAU,IAAI,SAAS;AAAA,IAC/D,QAAQ,IAAI;AAAA,IACZ,GAAI,IAAI,aAAa,SAAY,CAAC,IAAI,EAAE,UAAU,IAAI,SAAS;AAAA,IAC/D,OAAO,CAAC;AAAA,IACR,WAAW,IAAI;AAAA,IACf,WAAW,IAAI;AAAA,EACjB;AACF;AAEA,SAAS,UAAU,KAAwF;AACzG,SAAO,EAAE,IAAI,OAAO,IAAI,EAAE,GAAG,GAAI,IAAI,WAAW,SAAY,CAAC,IAAI,EAAE,QAAQ,IAAI,OAAO,GAAI,MAAM,IAAI,MAAM,WAAW,IAAI,UAAU;AACrI;;;AC5FA,IAAMC,eAAc;AACpB,IAAMC,WAAS;AACf,IAAM,OAAO;AACb,IAAMC,OAAM;AAGZ,IAAM,4BAA4E;AAAA,EAChF,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AACT;AAGA,IAAMC,qBAA6C;AAAA,EACjD,MAAM;AAAA,IACJ,SAAS,wBAAwB;AAAA,IACjC,YAAY,CAAC,UAAU,UAAU,gBAAgB,iBAAiB,gBAAgB,eAAe;AAAA,IACjG,OAAO,CAAC,WAAW,WAAW,OAAO;AAAA,EACvC;AAAA,EACA,UAAU,EAAE,SAAS,iBAAiB,YAAY,iBAAiB,OAAO,CAAC,OAAO,MAAM,EAAE;AAAA,EAC1F,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,QAAQ,CAAC,SAAS,eAAe,QAAQ;AAAA,EACzC,UAAU,CAAC,SAAS,QAAQ,QAAQ;AAAA,EACpC,SAAS;AAAA,EACT,OAAO,CAAC,SAAS,UAAU,QAAQ;AAAA,EACnC,qBAAqB;AACvB;AAEO,SAAS,mBAA0C;AACxD,SAAO,EAAE,cAAcA,oBAAmB,QAAQ,CAAC,YAAY,kBAAkB,OAAO,EAAE;AAC5F;AAEA,SAAS,kBAAkB,EAAE,YAAY,MAAM,GAAuC;AACpF,QAAM,SAAS,cAAc,WAAW,QAAQ,yFAAkC;AAClF,MAAI,CAACF,SAAO,KAAK,MAAM,EAAG,OAAM,IAAI,aAAa,mBAAmB,qCAAgC;AACpG,QAAM,MAAM,QAAQ,WAAW,KAAKD,YAAW;AAC/C,QAAM,SAAS,IAAI,IAAI,GAAG,EAAE;AAC5B,QAAM,OAAO,GAAG,GAAG,UAAU,MAAM;AACnC,QAAM,UAAU,EAAE,eAAe,UAAU,WAAW,SAAS,EAAE,GAAG;AACpE,QAAM,UAAU,CAAC,SAA4D,EAAE,SAAS,aAAa,SAAS,4CAAwB,GAAG,IAAI;AAC7I,QAAM,OAAO,CAAC,QAAwB;AACpC,QAAI,CAAC,KAAK,KAAK,GAAG,EAAG,OAAM,IAAI,aAAa,aAAa,4CAAwB,GAAG,GAAG;AACvF,WAAO;AAAA,EACT;AACA,QAAM,UAAU,OAAO,QACrBI,SAAQ,MAAM,YAAY,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,QAAQ,GAAG,EAAE,CAAC,GAAG,IAAI;AAC5G,SAAO;AAAA,IACL,MAAM,OAAO,UAAU;AACrB,sBAAgB,kBAAkBD,mBAAkB,MAAM,OAAO,wBAAwB,OAAO;AAChG,YAAM,SAASE,cAAa,MAAM,MAAM;AACxC,YAAM,SAAS,IAAI,gBAAgB,EAAE,WAAW,OAAO,MAAM,KAAK,EAAE,CAAC;AACrE,UAAI,MAAM,WAAW,OAAW,QAAO,IAAI,cAAc,MAAM,MAAM;AACrE,YAAM,SAAS,aAAa,OAAO,MAAM;AACzC,UAAI,WAAW,OAAW,QAAO,IAAI,UAAU,MAAM;AACrD,UAAI,MAAM,SAAS,OAAW,QAAO,IAAI,WAAW,GAAG,MAAM,KAAK,cAAc,QAAQ,KAAK,GAAG,GAAG,0BAA0B,MAAM,KAAK,KAAK,CAAC,EAAE;AAChJ,YAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,IAAI,IAAI,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,QAAQ,CAAC;AAC7F,YAAM,SAAS,SAAS,IAAI,IAAI,OAAO,CAAC;AACxC,YAAM,SAAS,MAAM,QAAQ,OAAO,aAAa,IAAI,OAAO,gBAAgB,CAAC,GAAG,IAAID,OAAM,EAAE,OAAO,CAAC,SAASE,aAAY,MAAM,KAAK,CAAC;AACrI,aAAO,EAAE,OAAO,OAAO,GAAGC,QAAO,OAAO,eAAe,EAAE;AAAA,IAC3D;AAAA,IACA,KAAK,CAAC,QAAQ,QAAQ,GAAG;AAAA,IACzB,QAAQ,OAAO,UAAUH,SAAQ,MAAM,YAAY,MAAM,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,MAAMI,YAAW,KAAK,EAAE,CAAC,GAAG,IAAI;AAAA,IACnI,QAAQ,OAAO,KAAK,UAAU;AAC5B,YAAM,KAAK,KAAK,GAAG;AACnB,UAAI;AACJ,UAAI,MAAM,UAAU,UAAa,MAAM,gBAAgB,UAAa,MAAM,WAAW,QAAW;AAC9F,cAAM,OAAO;AAAA,UACX,GAAI,MAAM,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;AAAA,UAC1D,GAAI,MAAM,gBAAgB,SAAY,CAAC,IAAI,EAAE,aAAa,MAAM,YAAY;AAAA,UAC5E,GAAI,MAAM,WAAW,SAAY,CAAC,IAAI,EAAE,eAAe,MAAM,OAAO;AAAA,QACtE;AACA,mBAAW,MAAM,YAAY,GAAG,IAAI,IAAI,EAAE,IAAI,EAAE,OAAO,QAAQ,SAAS,QAAQ,SAAS,MAAM,SAAS,QAAQ,GAAG,EAAE,CAAC,GAAG;AAAA,MAC3H;AACA,UAAI,MAAM,WAAW,QAAW;AAC9B,cAAM,SAAS,eAAe,MAAM,SAAS,MAAM,QAAQ,GAAG,GAAG,OAAO,QAAQ;AAChF,YAAI,WAAW,OAAW,OAAM,YAAY,GAAG,IAAI,IAAI,EAAE,IAAI,MAAM,IAAI,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,SAAS,QAAQ,GAAG,EAAE,CAAC;AACxI,eAAO,QAAQ,GAAG;AAAA,MACpB;AACA,aAAOJ,QAAO,YAAY,MAAM,YAAY,GAAG,IAAI,IAAI,EAAE,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,QAAQ,GAAG,EAAE,CAAC,GAAG,IAAI;AAAA,IACvH;AAAA,IACA,OAAO,OAAO,KAAK,UAAsB;AACvC,YAAM,KAAK,KAAK,GAAG;AACnB,UAAI,MAAM,YAAY,OAAW,OAAM,IAAI,aAAa,eAAe,iQAA8D;AACrI,UAAI,MAAM,WAAW,UAAa,CAACD,mBAAkB,MAAM,SAAS,MAAM,MAAM,GAAG;AACjF,cAAM,IAAI,aAAa,eAAe,+GAAoC,MAAM,MAAM,qGAAqB;AAAA,MAC7G;AACA,UAAI,MAAM,YAAY,QAAW;AAC/B,cAAM,UAAU,MAAM,QAAQ,GAAG;AAEjC,aAAK,QAAQ,WAAW,IAAI,YAAY,MAAM,MAAM,QAAQ,YAAY,GAAG;AACzE,gBAAM,IAAI,aAAa,YAAY,2CAAa,GAAG,mHAAyB,MAAM,OAAO,0CAAY,QAAQ,WAAW,8DAAY,GAAG;AAAA,QACzI;AAAA,MACF;AACA,YAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,IAAI,IAAI,EAAE,UAAU;AAAA,QACxD;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA;AAAA,QAER,MAAM;AAAA,UACJ,GAAI,MAAM,WAAW,SAAY,CAAC,IAAI,EAAE,QAAQ,MAAM,WAAW,UAAU,QAAQ,MAAM,WAAW,SAAS;AAAA,UAC7G,GAAI,MAAM,iBAAiB,SAAY,CAAC,IAAI,EAAE,eAAe,MAAM,aAAa;AAAA,QAClF;AAAA,QACA,SAAS,QAAQ,GAAG;AAAA,MACtB,CAAC;AACD,YAAM,YAAY,SAAS,IAAI,IAAI,OAAO,CAAC;AAC3C,UAAI,UAAU,WAAW,YAAY,UAAU,WAAW,UAAU;AAClE,cAAM,eAAe,SAAS,UAAU,KAAK,IAAI,KAAK,UAAU,MAAM,OAAO,IAAI;AACjF,cAAM,IAAI,aAAa,YAAY,iDAAc,GAAG,mEAAiB,iBAAiB,gBAAgB,OAAO,UAAU,MAAM,CAAC,CAAC,GAAG;AAAA,MACpI;AACA,aAAO,QAAQ,GAAG;AAAA,IACpB;AAAA,IACA,UAAU,OAAO,KAAK,UAAwB;AAC5C,YAAM,KAAK,KAAK,GAAG;AACnB,yBAAmB,qFAA8BA,mBAAkB,UAAU,KAAK;AAClF,YAAM,SAAS,IAAI,gBAAgB,EAAE,WAAW,OAAO,MAAM,KAAK,EAAE,CAAC;AACrE,UAAI,MAAM,WAAW,OAAW,QAAO,IAAI,cAAc,MAAM,MAAM;AACrE,UAAI,MAAM,UAAU,OAAW,QAAO,IAAI,WAAW,MAAM,UAAU,QAAQ,eAAe,aAAa;AACzG,YAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,IAAI,IAAI,EAAE,aAAa,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,SAAS,QAAQ,GAAG,EAAE,CAAC;AACnI,YAAM,SAAS,SAAS,IAAI,IAAI,OAAO,CAAC;AACxC,YAAM,cAAc,MAAM,QAAQ,OAAO,qBAAqB,IAAI,OAAO,wBAAwB,CAAC;AAClG,YAAM,UAAU,YAAY,OAAO,CAAC,QAAQ,EAAE,SAAS,GAAG,KAAK,IAAI,eAAe,KAAK;AACvF,YAAM,WAAW,MAAM,iBAAiB,SAAY,UAAU,QAAQ,OAAO,CAAC,QAAQ,YAAY,YAAY,SAAS,GAAG,IAAI,IAAI,aAAa,MAAS,GAAG,MAAM,cAAc,MAAS,CAAC;AACzL,aAAO,EAAE,OAAO,SAAS,IAAIM,UAAS,GAAG,GAAGF,QAAO,OAAO,eAAe,EAAE;AAAA,IAC7E;AAAA,IACA,SAAS,OAAO,KAAK,SAASE,YAAW,MAAM,YAAY,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,aAAa,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,MAAM,EAAE,KAAK,GAAG,SAAS,QAAQ,GAAG,EAAE,CAAC,GAAG,IAAI;AAAA,EACtL;AACF;AAGA,SAASD,YAAW,OAAqD;AACvE,SAAO;AAAA,IACL,OAAO,MAAM;AAAA,IACb,eAAe,MAAM;AAAA,IACrB,eAAe,MAAM;AAAA,IACrB,GAAI,MAAM,gBAAgB,SAAY,CAAC,IAAI,EAAE,aAAa,MAAM,YAAY;AAAA,IAC5E,SAAS,MAAM,UAAU;AAAA,EAC3B;AACF;AAGA,SAAS,eAAe,WAAyD,SAAwD;AACvI,MAAI,YAAY,UAAW,QAAO;AAClC,MAAI,cAAc,QAAS,QAAO;AAClC,MAAI,cAAc,OAAQ,QAAO,YAAY,UAAU,YAAY;AACnE,SAAO;AACT;AAGA,SAASH,cAAa,QAA4G;AAChI,MAAI,WAAW,UAAa,OAAO,WAAW,EAAG,QAAO;AACxD,aAAW,QAAQ,QAAQ;AACzB,QAAI,CAAC,gCAAgC,QAAQ,SAAS,IAAI,GAAG;AAC3D,YAAM,IAAI,aAAa,mBAAmB,wLAAiD,OAAO,IAAI,CAAC,GAAG;AAAA,IAC5G;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAASC,aAAY,MAAmB,OAAkC;AACxE,MAAI,MAAM,WAAW,UAAa,CAAC,MAAM,OAAO,MAAM,CAAC,UAAU,KAAK,OAAO,SAAS,KAAK,CAAC,EAAG,QAAO;AACtG,MAAI,MAAM,WAAW,UAAa,CAAC,aAAa,CAAC,KAAK,OAAO,KAAK,WAAW,GAAG,MAAM,MAAM,EAAG,QAAO;AACtG,SAAO,YAAY,KAAK,WAAW,MAAM,cAAc,MAAM,aAAa,KAAK,YAAY,KAAK,WAAW,MAAM,cAAc,MAAM,aAAa;AACpJ;AAGA,SAAS,aAAa,OAAyB,QAA8E;AAC3H,QAAM,UAAoB,CAAC;AAC3B,MAAI,WAAW,QAAW;AACxB,UAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,QAAQ,2BAA2B,MAAM,CAAC,CAAC;AACrE,YAAQ,KAAK,cAAc,MAAM,KAAK,IAAI,CAAC,GAAG;AAAA,EAChD;AACA,MAAI,MAAM,WAAW,OAAW,SAAQ,KAAK,eAAe,OAAO,MAAM,MAAM,CAAC,EAAE;AAClF,MAAI,MAAM,WAAW,OAAW,SAAQ,KAAK,iBAAiB,OAAO,MAAM,MAAM,CAAC,EAAE;AACpF,MAAI,MAAM,WAAW,OAAW,SAAQ,KAAK,iBAAiB,OAAO,MAAM,MAAM,CAAC,EAAE;AACpF,SAAO,QAAQ,WAAW,IAAI,SAAY,QAAQ,KAAK,OAAO;AAChE;AAGA,SAASC,QAAO,OAAyC;AACvD,QAAM,QAAQ,KAAK,KAAK;AACxB,SAAO,UAAU,SAAY,CAAC,IAAI,EAAE,YAAY,MAAM;AACxD;AAGA,SAASH,QAAO,KAA2B;AACzC,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,SAAS,SAAS,KAAK,MAAM,IAAI,KAAK,SAAS,CAAC;AACtD,QAAM,SAAS,SAAS,KAAK,MAAM,IAAI,KAAK,SAAS,CAAC;AACtD,QAAM,UAAU,KAAK,OAAO,GAAG;AAC/B,QAAM,cAAc,KAAK,KAAK,WAAW;AACzC,QAAM,SAAS,SAAS,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,IAAI,IAAI;AAChE,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,QAAM,WAAW,YAAY,KAAK,SAAS;AAC3C,QAAM,WAAW,YAAY,KAAK,SAAS;AAC3C,QAAM,MAAM,KAAK,KAAK,IAAI,KAAK;AAC/B,QAAM,aAAa,KAAK,KAAK,MAAM,KAAK;AACxC,SAAO;AAAA,IACL;AAAA,IACA,OAAO,KAAK,KAAK,KAAK,KAAK;AAAA,IAC3B,GAAI,gBAAgB,SAAY,CAAC,IAAI,EAAE,YAAY;AAAA,IACnD,QAAQ,EAAE,UAAU,OAAO,2BAA2B,YAAY,MAAM,GAAG,MAAM,WAAW;AAAA,IAC5F,GAAI,WAAW,SAAY,CAAC,IAAI,EAAE,OAAO;AAAA,IACzC,QAAQ,KAAK,OAAO,GAAG,KAAK,KAAK,KAAK,aAAa,KAAK;AAAA,IACxD,QAAQ,KAAK,OAAO,GAAG,KAAK,KAAK,KAAK,aAAa,KAAK;AAAA,IACxD,GAAI,YAAY,UAAaF,KAAI,KAAK,OAAO,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,IAChE,QAAQ,MAAM,QAAQ,KAAK,MAAM,IAAI,WAAW,KAAK,OAAO,IAAI,CAAC,UAAW,SAAS,KAAK,IAAI,MAAM,OAAO,MAAU,CAAC,IAAI,CAAC;AAAA,IAC3H,OAAO,CAAC;AAAA,IACR,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS;AAAA,IAC7C,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS;AAAA,EAC/C;AACF;AAEA,SAASO,WAAU,KAA4B;AAC7C,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,SAAS,SAAS,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,IAAI,IAAI;AAChE,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,SAAO,EAAE,IAAI,KAAK,KAAK,EAAE,KAAK,KAAK,GAAI,WAAW,SAAY,CAAC,IAAI,EAAE,OAAO,GAAI,MAAM,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,IAAI,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU,EAAG;AAC1L;;;AChOA,IAAMC,eAAc;AACpB,IAAMC,WAAS;AACf,IAAMC,OAAM;AACZ,IAAMC,oBAAmB;AACzB,IAAMC,kBAAiB,mBAAmB;AAE1C,IAAM,gBAAgB;AAGtB,IAAMC,gBAAiC;AAAA,EACrC,UAAU,EAAE,SAASD,iBAAgB,YAAY,CAAC,GAAG,OAAO,CAAC,EAAE;AACjE;AAEO,SAAS,kBAAkC;AAChD,SAAO,EAAE,cAAcC,eAAc,QAAQ,CAAC,YAAY,6BAA6B,OAAO,EAAE;AAClG;AAEA,SAAS,6BAA6B,EAAE,YAAY,MAAM,GAAgC;AACxF,QAAM,SAAS,cAAc,WAAW,QAAQ,yFAAkC;AAClF,MAAI,CAACJ,SAAO,KAAK,MAAM,EAAG,OAAM,IAAI,aAAa,mBAAmB,qCAAgC;AACpG,QAAM,MAAM,QAAQ,WAAW,KAAKD,YAAW;AAC/C,QAAM,SAAS,IAAI,IAAI,GAAG,EAAE;AAC5B,QAAM,OAAO,GAAG,GAAG,UAAU,MAAM;AACnC,QAAM,UAAU,EAAE,eAAe,UAAU,WAAW,SAAS,EAAE,GAAG;AACpE,QAAM,UAAU,EAAE,SAAS,aAAa,SAAS,4GAAiC,MAAM,IAAI;AAC5F,SAAO;AAAA,IACL,KAAK,YAAYM,SAAQ,MAAM,YAAY,MAAM,EAAE,OAAO,QAAQ,SAAS,QAAQ,CAAC,GAAG,MAAM,MAAM;AAAA,IACnG,UAAU,OAAO,UAAU;AACzB,sBAAgBH,mBAAkBE,cAAa,UAAU,OAAOD,eAAc;AAC9E,YAAM,SAAS,IAAI,gBAAgB,EAAE,WAAW,OAAO,KAAK,IAAI,MAAM,OAAO,aAAa,CAAC,EAAE,CAAC;AAC9F,UAAI,MAAM,WAAW,OAAW,QAAO,IAAI,cAAc,MAAM,MAAM;AACrE,UAAI,MAAM,WAAW,OAAW,QAAO,IAAI,UAAU,MAAM,MAAM;AACjE,YAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,IAAI,aAAa,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,QAAQ,CAAC;AAC/G,YAAM,SAAS,SAAS,IAAI,IAAI,OAAO,CAAC;AACxC,YAAM,WAAW,MAAM,QAAQ,OAAO,QAAQ,IAAI,OAAO,WAAW,CAAC;AACrE,YAAM,OAAO,KAAK,OAAO,eAAe;AACxC,aAAO,EAAE,OAAO,SAAS,IAAIG,SAAQ,GAAG,GAAI,SAAS,SAAY,CAAC,IAAI,EAAE,YAAY,KAAK,EAAG;AAAA,IAC9F;AAAA,EACF;AACF;AAGA,SAASD,QAAO,KAAc,QAAsB;AAClD,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,gBAAgB,KAAK,KAAK,cAAc;AAC9C,QAAM,cAAc,KAAK,KAAK,WAAW;AACzC,QAAM,aAAaE,cAAa,KAAK,UAAU;AAC/C,QAAM,MAAM,KAAK,KAAK,OAAO;AAC7B,SAAO;AAAA,IACL,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK;AAAA,IAC5C,GAAI,kBAAkB,SAAY,CAAC,IAAI,EAAE,cAAc;AAAA,IACvD,GAAI,gBAAgB,SAAY,CAAC,IAAI,EAAE,YAAY;AAAA,IACnD,GAAI,eAAe,SAAY,CAAC,IAAI,EAAE,WAAW;AAAA,IACjD,OAAO,QAAQ,SAAY,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,cAAc,CAAC;AAAA,EAChE;AACF;AAGA,SAASD,UAAS,KAAsB;AACtC,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,MAAM,SAAS,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,IAAI,IAAI;AAC7D,SAAO;AAAA,IACL,MAAM,KAAK,KAAK,IAAI,KAAK;AAAA,IACzB,GAAI,QAAQ,UAAa,CAACL,KAAI,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI;AAAA,EACvD;AACF;AAGA,SAASM,cAAa,OAA4C;AAChE,QAAM,SAAS,qBAAqB,UAAU,KAAK;AACnD,SAAO,OAAO,UAAU,OAAO,OAAO;AACxC;;;AClEA,IAAMC,eAAc;AACpB,IAAM,cAAc;AACpB,IAAMC,WAAS;AACf,IAAMC,QAAO;AAGb,IAAM,6BAAgF;AAAA,EACpF,SAAS;AAAA,EACT,SAAS;AAAA,EACT,UAAU;AAAA,EACV,OAAO;AACT;AAIA,IAAMC,sBAAwC;AAAA,EAC5C,MAAM,EAAE,SAAS,eAAe,YAAY,CAAC,UAAU,GAAG,OAAO,CAAC,WAAW,WAAW,YAAY,OAAO,EAAE;AAAA,EAC7G,UAAU,EAAE,SAAS,iBAAiB,YAAY,iBAAiB,OAAO,CAAC,OAAO,MAAM,EAAE;AAC5F;AAEO,SAAS,qBAAwC;AACtD,SAAO;AAAA,IACL,YAAY;AAAA,MACV,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,QACN,EAAE,MAAM,UAAU,UAAU,MAAM,QAAQ,MAAM;AAAA,QAChD,EAAE,MAAM,SAAS,UAAU,MAAM,QAAQ,KAAK;AAAA,QAC9C,EAAE,MAAM,OAAO,UAAU,OAAO,QAAQ,MAAM;AAAA,MAChD;AAAA,MACA,UAAU,EAAE,QAAQ,MAAM,QAAQ,MAAM,SAAS,MAAM,UAAU,MAAM,QAAQ,OAAO,UAAU,OAAO,UAAU,CAAC,GAAG,YAAY,EAAE;AAAA,IACrI;AAAA,IACA,QAAQA;AAAA,IACR,QAAQ,CAAC,YAAY,yBAAyB,OAAO;AAAA,IACrD,QAAQ,CAAC,eAAe,IAAI,IAAI,QAAQ,WAAW,KAAKH,YAAW,CAAC,EAAE;AAAA,IACtE,OAAO,iBAAiB;AAAA,IACxB,IAAI,cAAc;AAAA,IAClB,MAAM,gBAAgB;AAAA,EACxB;AACF;AAEA,SAAS,yBAAyB,EAAE,YAAY,MAAM,GAAmC;AACvF,QAAM,SAAS,cAAc,WAAW,QAAQ,yFAAkC;AAClF,MAAI,CAACC,SAAO,KAAK,MAAM,EAAG,OAAM,IAAI,aAAa,mBAAmB,qCAAgC;AACpG,QAAM,MAAM,QAAQ,WAAW,KAAKD,YAAW;AAC/C,QAAM,SAAS,IAAI,IAAI,GAAG,EAAE;AAC5B,QAAM,OAAO,GAAG,GAAG,UAAU,MAAM;AACnC,QAAM,UAAU,EAAE,eAAe,UAAU,WAAW,SAAS,EAAE,GAAG;AACpE,QAAM,MAAM,WAAW,QAAQ,SAAY,GAAG,WAAW,IAAI,MAAM,YAAY;AAC/E,QAAM,OAAO,CAAC,QAAwB;AACpC,QAAI,CAACE,MAAK,KAAK,GAAG,EAAG,OAAM,IAAI,aAAa,iBAAiB,8EAA4B,GAAG,GAAG;AAC/F,WAAO;AAAA,EACT;AACA,QAAME,WAAU,CAAC,QAAwBC,SAAQ,KAAK,GAAG;AACzD,SAAO;AAAA,IACL,MAAM,OAAO,UAAU;AACrB,sBAAgB,oDAAsBF,oBAAmB,MAAM,OAAO,aAAa;AACnF,YAAM,SAAS,IAAI,gBAAgB,EAAE,WAAW,OAAO,MAAM,KAAK,EAAE,CAAC;AACrE,UAAI,MAAM,WAAW,OAAW,QAAO,IAAI,cAAc,MAAM,MAAM;AACrE,YAAM,SAAS,cAAc,KAAK;AAClC,UAAI,WAAW,OAAW,QAAO,IAAI,UAAU,MAAM;AACrD,UAAI,MAAM,SAAS,OAAW,QAAO,IAAI,WAAW,GAAG,MAAM,KAAK,cAAc,QAAQ,KAAK,GAAG,GAAG,iBAAiB,MAAM,KAAK,KAAK,CAAC,EAAE;AACvI,YAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,IAAI,IAAI,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,QAAQ,CAAC;AAC7F,YAAM,SAAS,SAAS,IAAI,IAAI,OAAO,CAAC;AACxC,UAAI,UAAU,MAAM,QAAQ,OAAO,MAAM,IAAI,OAAO,SAAS,CAAC,GAAG,IAAIC,QAAO;AAC5E,UAAI,MAAM,WAAW,OAAW,UAAS,OAAO,OAAO,CAAC,UAAU,MAAM,QAAQ,SAAS,MAAM,OAAO,QAAQ,MAAM,IAAI;AACxH,UAAI,MAAM,aAAa,KAAM,UAAS,OAAO,OAAO,CAAC,UAAU,MAAM,aAAa,MAAS;AAC3F,aAAO,EAAE,OAAO,QAAQ,GAAGE,QAAO,OAAO,eAAe,EAAE;AAAA,IAC5D;AAAA,IACA,KAAK,OAAO,QAAQF,UAAS,MAAM,YAAY,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,gBAAgB,KAAK,CAAC,GAAG,IAAI;AAAA,IAC9H,QAAQ,OAAO,UAAU;AACvB,YAAM,OAAO,EAAE,OAAO,MAAM,OAAO,GAAI,MAAM,gBAAgB,SAAY,CAAC,IAAI,EAAE,aAAa,MAAM,YAAY,GAAI,GAAI,MAAM,aAAa,SAAY,CAAC,IAAI,EAAE,UAAU,MAAM,SAAS,EAAG;AACzL,aAAOA,UAAS,MAAM,YAAY,MAAM,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,KAAK,CAAC,GAAG,IAAI;AAAA,IACjG;AAAA,IACA,QAAQ,OAAO,KAAK,UAAUA,UAAS,MAAM,YAAY,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,QAAQ,SAAS,MAAMG,WAAU,KAAK,GAAG,gBAAgB,KAAK,CAAC,GAAG,IAAI;AAAA,IACjL,UAAU,OAAO,KAAK,UAAU;AAC9B,yBAAmB,kFAA2BJ,oBAAmB,UAAU,KAAK;AAChF,YAAM,SAAS,IAAI,gBAAgB,EAAE,WAAW,OAAO,MAAM,KAAK,EAAE,CAAC;AACrE,UAAI,MAAM,WAAW,OAAW,QAAO,IAAI,cAAc,MAAM,MAAM;AACrE,UAAI,MAAM,UAAU,OAAW,QAAO,IAAI,WAAW,MAAM,UAAU,QAAQ,eAAe,aAAa;AACzG,YAAM,EAAE,KAAK,IAAI,MAAM,YAAY,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,aAAa,OAAO,SAAS,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,gBAAgB,KAAK,CAAC;AACzI,YAAM,SAAS,SAAS,IAAI,IAAI,OAAO,CAAC;AACxC,YAAM,cAAc,MAAM,QAAQ,OAAO,cAAc,IAAI,OAAO,iBAAiB,CAAC;AACpF,YAAM,WAAW,MAAM,iBAAiB,SAAY,cAAc,YAAY,OAAO,CAAC,QAAQ,YAAY,YAAY,SAAS,GAAG,IAAI,IAAI,aAAa,MAAS,GAAG,MAAM,cAAc,MAAS,CAAC;AACjM,aAAO,EAAE,OAAO,SAAS,IAAIK,UAAS,GAAG,GAAGF,QAAO,OAAO,eAAe,EAAE;AAAA,IAC7E;AAAA,IACA,SAAS,OAAO,KAAK,SAASE,YAAW,MAAM,YAAY,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,aAAa,EAAE,OAAO,QAAQ,SAAS,QAAQ,QAAQ,MAAM,EAAE,KAAK,GAAG,gBAAgB,KAAK,CAAC,GAAG,IAAI;AAAA,EACrL;AACF;AAEA,SAASD,WAAU,OAAiD;AAClE,SAAO;AAAA,IACL,GAAI,MAAM,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;AAAA,IAC1D,GAAI,MAAM,gBAAgB,SAAY,CAAC,IAAI,EAAE,aAAa,MAAM,YAAY;AAAA,IAC5E,GAAI,MAAM,WAAW,SAAY,CAAC,IAAI,EAAE,aAAa,yBAAyB,MAAM,MAAM,EAAE;AAAA,IAC5F,GAAI,MAAM,aAAa,SAAY,CAAC,IAAI,EAAE,UAAU,MAAM,SAAS;AAAA,EACrE;AACF;AAGA,SAASD,QAAO,OAAyC;AACvD,QAAM,QAAQ,KAAK,KAAK;AACxB,SAAO,UAAU,SAAY,CAAC,IAAI,EAAE,YAAY,MAAM;AACxD;AAGA,SAAS,iBAAiB,OAA+B;AACvD,QAAM,WAAW,2BAA2B,KAAK;AACjD,MAAI,aAAa,OAAW,OAAM,IAAI,aAAa,eAAe,+HAAqC,KAAK,qGAAqB;AACjI,SAAO;AACT;AAGA,SAAS,cAAc,OAAuC;AAC5D,QAAM,UAAoB,CAAC;AAC3B,MAAI,MAAM,WAAW,UAAa,MAAM,OAAO,SAAS,GAAG;AACzD,UAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,MAAM,OAAO,QAAQ,CAAC,aAAa,0BAA0B,QAAQ,CAAC,CAAC,CAAC;AAClG,YAAQ,KAAK,cAAc,MAAM,KAAK,IAAI,CAAC,GAAG;AAAA,EAChD;AACA,aAAW,SAAS,MAAM,UAAU,CAAC,EAAG,SAAQ,KAAK,cAAc,OAAO,KAAK,CAAC,EAAE;AAClF,MAAI,OAAO,MAAM,aAAa,SAAU,SAAQ,KAAK,iBAAiB,OAAO,MAAM,QAAQ,CAAC,EAAE;AAC9F,MAAI,MAAM,WAAW,OAAW,SAAQ,KAAK,eAAe,OAAO,MAAM,MAAM,CAAC,EAAE;AAClF,MAAI,MAAM,WAAW,OAAW,SAAQ,KAAK,SAAS,OAAO,MAAM,MAAM,CAAC,EAAE;AAC5E,MAAI,MAAM,iBAAiB,OAAW,SAAQ,KAAK,eAAe,OAAO,QAAQ,MAAM,YAAY,CAAC,CAAC,EAAE;AACvG,MAAI,MAAM,kBAAkB,OAAW,SAAQ,KAAK,eAAe,OAAO,QAAQ,MAAM,aAAa,CAAC,CAAC,EAAE;AACzG,MAAI,MAAM,iBAAiB,OAAW,SAAQ,KAAK,eAAe,OAAO,QAAQ,MAAM,YAAY,CAAC,CAAC,EAAE;AACvG,MAAI,MAAM,kBAAkB,OAAW,SAAQ,KAAK,eAAe,OAAO,QAAQ,MAAM,aAAa,CAAC,CAAC,EAAE;AACzG,SAAO,QAAQ,WAAW,IAAI,SAAY,QAAQ,KAAK,OAAO;AAChE;AAEA,SAASD,SAAQ,KAAc,KAAgC;AAC7D,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,SAAS,SAAS,KAAK,MAAM,IAAI,KAAK,SAAS,CAAC;AACtD,QAAM,OAAO,KAAK,KAAK,IAAI,KAAK;AAChC,QAAM,aAAa,KAAK,OAAO,IAAI,KAAK;AACxC,QAAM,WAAW,OAA0B,wBAAwB,KAAK,UAAU,MAAS;AAC3F,QAAM,WAAW,SAAS,KAAK,QAAQ,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI;AACtE,QAAM,SAAS,MAAM,QAAQ,KAAK,MAAM,IAAI,WAAW,KAAK,OAAO,IAAI,CAAC,UAAW,SAAS,KAAK,IAAI,MAAM,OAAO,MAAU,CAAC,IAAI,CAAC;AAClI,QAAM,cAAc,KAAK,KAAK,WAAW;AACzC,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,SAAO;AAAA,IACL,KAAK;AAAA,IACL,OAAO,KAAK,KAAK,KAAK,KAAK;AAAA,IAC3B,GAAI,gBAAgB,SAAY,CAAC,IAAI,EAAE,YAAY;AAAA,IACnD,QAAQ,EAAE,UAAU,OAAO,sBAAsB,YAAY,MAAM,GAAG,MAAM,KAAK,OAAO,IAAI,KAAK,WAAW;AAAA,IAC5G,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS;AAAA,IAC7C;AAAA,IACA,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS;AAAA,IAC7C,OAAO,QAAQ,SAAY,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,GAAG,IAAI,IAAI,IAAI,OAAO,cAAc,CAAC;AAAA,IAChF,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,EACjD;AACF;AAEA,SAASG,WAAU,KAA4B;AAC7C,QAAM,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC;AACpC,QAAM,SAAS,SAAS,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,IAAI,IAAI;AAChE,QAAM,YAAY,YAAY,KAAK,UAAU;AAC7C,SAAO,EAAE,IAAI,KAAK,KAAK,EAAE,KAAK,KAAK,GAAI,WAAW,SAAY,CAAC,IAAI,EAAE,OAAO,GAAI,MAAM,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,IAAI,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU,EAAG;AAC1L;;;ACpKA,IAAI,aAAa;AAEV,SAAS,0BAAgC;AAC9C,MAAI,WAAY;AAChB,eAAa;AACb,aAAW,cAAc,CAAC,aAAa,GAAG,mBAAmB,GAAG,cAAc,GAAG,cAAc,GAAG,YAAY,CAAC,EAAG,iBAAgB,UAAU;AAC9I;;;ACdA,SAAS,OAAO,UAAU,QAAQ,iBAAiB;AACnD,SAAS,YAAY;AAWrB,IAAI,QAA0B,QAAQ,QAAQ;AAE9C,SAAS,UAAa,MAAoC;AACxD,QAAM,MAAM,MAAM,KAAK,MAAM,IAAI;AACjC,UAAQ,IAAI,MAAM,MAAM,MAAS;AACjC,SAAO;AACT;AAEA,eAAe,QAAQ,SAAkD;AACvE,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,SAAS,KAAK,SAAS,oBAAoB,GAAG,MAAM;AAAA,EAClE,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,SAAU,QAAO,CAAC;AAChE,UAAM;AAAA,EACR;AACA,QAAM,SAAkB,KAAK,MAAM,GAAG;AACtC,MAAI,CAAC,SAAS,MAAM,EAAG,QAAO,CAAC;AAC/B,SAAO,OAAO,YAAY,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,UAAqC,OAAO,MAAM,CAAC,MAAM,QAAQ,CAAC;AAC7H;AAEA,eAAe,SAAS,SAAiB,SAAgD;AACvF,QAAM,MAAM,SAAS,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AACrD,QAAM,SAAS,KAAK,SAAS,oBAAoB;AACjD,QAAM,OAAO,GAAG,MAAM,IAAI,OAAO,QAAQ,GAAG,CAAC;AAC7C,QAAM,UAAU,MAAM,KAAK,UAAU,OAAO,GAAG,EAAE,MAAM,IAAM,CAAC;AAC9D,QAAM,OAAO,MAAM,MAAM;AAC3B;AAGA,eAAsB,iBAAiB,SAAiB,WAAmB,OAAmB,mBAAgD;AAC5I,QAAM,SAAS,MAAM,QAAQ,OAAO,GAAG,SAAS;AAChD,MAAI,UAAU,OAAW,MAAK,SAAS,KAAK;AAC5C,SAAO;AACT;AAEO,SAAS,gBAAgB,SAAiB,WAAqC;AACpF,SAAO,QAAQ,OAAO,EAAE,KAAK,CAAC,YAAY,QAAQ,SAAS,MAAM,MAAS;AAC5E;AAGO,SAAS,kBAAkB,SAAiB,WAAmB,OAAe,OAAmB,mBAAkC;AACxI,MAAI,UAAU,GAAI,MAAK,SAAS,KAAK;AACrC,SAAO,UAAU,YAAY;AAC3B,UAAM,UAAU,MAAM,QAAQ,OAAO;AACrC,QAAI,UAAU,GAAI,QAAO,QAAQ,SAAS;AAAA,QACrC,SAAQ,SAAS,IAAI;AAC1B,UAAM,SAAS,SAAS,OAAO;AAAA,EACjC,CAAC;AACH;AAEO,SAAS,mBAAmB,SAAiB,WAAmB,OAAmB,mBAAkC;AAC1H,SAAO,kBAAkB,SAAS,WAAW,IAAI,IAAI;AACvD;;;ACjEO,SAAS,qBAAqB,YAA+B,SAA6C;AAC/G,MAAI,WAAW,UAAU,OAAW,OAAM,IAAI,aAAa,eAAe,wCAAU,WAAW,WAAW,KAAK,mEAA2B;AAC1I,SAAO,WAAW,MAAM,OAAO,OAAO;AACxC;;;ACHO,SAAS,cAAc,YAA+B,SAAsC;AACjG,MAAI,WAAW,SAAS,OAAW,OAAM,IAAI,aAAa,eAAe,wCAAU,WAAW,WAAW,KAAK,kHAAwB;AACtI,SAAO,WAAW,KAAK,OAAO,OAAO;AACvC;","names":["text","TARGET","ID","RUN_FILTERS","JOB_FILTERS","CAPABILITIES","runOf","pageOf","jobOf","DEFAULT_API","TARGET","RUN_FILTERS","JOB_FILTERS","CAPABILITIES","runOf","jobOf","z","z","DEFAULT_API","TARGET","SHA","pageOf","z","z","DEFAULT_API","TARGET","SHA","CAPABILITIES","pageOf","nextOf","DEFAULT_API","TARGET","NUMBER","LIST_SUBJECT","COMMENTS_SUBJECT","pageOf","rowsOf","patchBody","commentOf","stateFilter","DEFAULT_URL","TARGET","SHA","PULL_CAPABILITIES","pullOf","usedStatuses","pageOf","stateFilter","patchBody","commentOf","DEFAULT_URL","TARGET","SHA","BRANCHES_SUBJECT","BRANCH_FILTERS","CAPABILITIES","repoOf","pageOf","branchOf","visibilityOf","DEFAULT_URL","TARGET","IID","ORDER_BY","issueOf","pageOf","stateFilter","composeLabels","patchBody","commentOf","ISSUE_CAPABILITIES","toIssue","issueOf","params","body","record","commentOf","priorityName","ISSUE_CAPABILITIES","DEFAULT_API","TARGET","SHA","PULL_CAPABILITIES","pullOf","usedStatuses","matchesPage","nextOf","createBody","commentOf","DEFAULT_API","TARGET","SHA","BRANCHES_SUBJECT","BRANCH_FILTERS","CAPABILITIES","repoOf","branchOf","visibilityOf","DEFAULT_API","TARGET","SLUG","ISSUE_CAPABILITIES","toIssue","issueOf","nextOf","patchBody","commentOf"]}