/** `productionSpec.definition.recipes` 같은 경로를 문서에서 따라간다. */ export declare const at: (o: any, path: string) => any; /** * 문서 항목의 **식별자** — 축마다 이름이 다르다(자리는 `id`, 공정은 `key`, 레시피도 `key`). * * 도메인 모양을 코드가 아는 것이 아니라 **식별자 관례**를 아는 것이다. 후보를 순서대로 보고 첫 * 값을 쓴다. 하나도 없으면 그 항목은 가리킬 수 없으므로 `null` — 목록에서 빼지 않고 **id 없음**으로 * 낸다(오류 없이 빠지면 건수가 안 맞는다). */ export declare const idOf: (o: any, info?: { idField?: string | string[]; }) => string | null; /** * **id → 이름**, 모든 축을 한 표로. * * ── 왜 이 표가 필요한가 ────────────────────────────────────────────────────── * 행은 다른 것을 **id 로** 가리킨다(사람의 `personnelClassIds`, 설비의 `homeLocationId`, 공정의 * `locationType`). 그 id 의 이름은 **가리켜진 축의 행**에 있으므로, 화면이 그것을 알려면 축을 * 하나씩 더 읽어야 한다 — 그래서 지금까지 표면마다 그냥 id 를 찍었다(`cutter-op`, `cut-station`). * 표면을 하나씩 고치는 것은 끝이 없다: 새 화면은 처음부터 다시 id 를 찍는다. * * 그래서 **서버가 붙인다.** 서버는 이미 모델을 손에 들고 있고, 어느 축이 있는지는 커널 카탈로그가 * 선언한다(`TWIN_AXES`) — 도메인이 늘어도 이 함수는 그대로다. * * 값은 그 항목이 **자기 이름이라고 말한 것**이다(`name`·`label`·`description`). 그중 어떤 것은 * i18n 키이므로(등급의 `description`) 번역은 화면의 일로 남긴다. 이름이 없으면 표에 넣지 않는다 — * 없는 것을 지어내지 않고, 그 경우 화면은 id 를 그대로 보인다. */ export declare function nameIndex(model: any): Record; /** * 이 응답이 **실제로 가리킨 것만** 골라 낸다. * * 모델 전체 표를 그대로 실으면 자리가 10만인 현장에서 목록 한 페이지에 10만 줄짜리 이름표가 * 따라온다. 나온 값에 걸리는 것만 싣는다 — 규모에서 성립하는 유일한 방식이다. */ export declare function namesFor(rows: any[], index: Record): Record;