@intellectif/lk-core 1.3.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +2 -0
  3. package/dist/{ai-B222dtHH.d.ts → ai-BYryFkF9.d.cts} +462 -5
  4. package/dist/ai-BYryFkF9.d.cts.map +1 -0
  5. package/dist/{ai-B222dtHH.d.cts → ai-BYryFkF9.d.ts} +462 -5
  6. package/dist/ai-BYryFkF9.d.ts.map +1 -0
  7. package/dist/ai-check.cjs +274 -23
  8. package/dist/ai-check.cjs.map +1 -1
  9. package/dist/ai-check.d.cts +13 -5
  10. package/dist/ai-check.d.cts.map +1 -1
  11. package/dist/ai-check.d.ts +13 -5
  12. package/dist/ai-check.d.ts.map +1 -1
  13. package/dist/ai-check.js +274 -23
  14. package/dist/ai-check.js.map +1 -1
  15. package/dist/{ai-writing-DCVkv4Zj.cjs → ai-writing-Cen7-3qs.cjs} +520 -58
  16. package/dist/ai-writing-Cen7-3qs.cjs.map +1 -0
  17. package/dist/{ai-writing-CCBjTOM3.js → ai-writing-D8PdhJJz.js} +513 -75
  18. package/dist/ai-writing-D8PdhJJz.js.map +1 -0
  19. package/dist/{index-Dyu66R4-.d.cts → index-Bg0aeWtM.d.cts} +327 -3
  20. package/dist/index-Bg0aeWtM.d.cts.map +1 -0
  21. package/dist/{index-BWPRPIXL.d.ts → index-CxpiWedW.d.ts} +7 -217
  22. package/dist/index-CxpiWedW.d.ts.map +1 -0
  23. package/dist/{index-CXyOV8sm.d.cts → index-D7R3Ll8R.d.cts} +2 -2
  24. package/dist/{index-CXyOV8sm.d.cts.map → index-D7R3Ll8R.d.cts.map} +1 -1
  25. package/dist/{index-UGxRSopE.d.ts → index-DUaW1Tj5.d.ts} +327 -3
  26. package/dist/index-DUaW1Tj5.d.ts.map +1 -0
  27. package/dist/{index-O4_ExlAD.d.cts → index-qMbxed1B.d.cts} +7 -217
  28. package/dist/index-qMbxed1B.d.cts.map +1 -0
  29. package/dist/{index-CegM8o15.d.ts → index-wMc1E_aM.d.ts} +2 -2
  30. package/dist/{index-CegM8o15.d.ts.map → index-wMc1E_aM.d.ts.map} +1 -1
  31. package/dist/index.cjs +32 -130
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +115 -97
  34. package/dist/index.d.cts.map +1 -1
  35. package/dist/index.d.ts +115 -97
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +9 -117
  38. package/dist/index.js.map +1 -1
  39. package/dist/{item-group-DroFXgLb.cjs → item-group-DEB7nLID.cjs} +2 -2
  40. package/dist/{item-group-DroFXgLb.cjs.map → item-group-DEB7nLID.cjs.map} +1 -1
  41. package/dist/{item-group-DXiR8nOr.js → item-group-DdSUCUjM.js} +2 -2
  42. package/dist/{item-group-DXiR8nOr.js.map → item-group-DdSUCUjM.js.map} +1 -1
  43. package/dist/{registry-DVi0LR_i.cjs → registry-Ce00A_OW.cjs} +184 -4
  44. package/dist/registry-Ce00A_OW.cjs.map +1 -0
  45. package/dist/{registry-Dsx9mNsS.js → registry-DaZRpqjW.js} +155 -5
  46. package/dist/registry-DaZRpqjW.js.map +1 -0
  47. package/dist/{schemas-Bdw0nGPo.js → schemas-BioKFf3F.js} +3 -3
  48. package/dist/{schemas-Bdw0nGPo.js.map → schemas-BioKFf3F.js.map} +1 -1
  49. package/dist/{schemas-DVbAOrtd.cjs → schemas-DksueYsu.cjs} +3 -3
  50. package/dist/{schemas-DVbAOrtd.cjs.map → schemas-DksueYsu.cjs.map} +1 -1
  51. package/dist/schemas.cjs +2 -2
  52. package/dist/schemas.d.cts +1 -1
  53. package/dist/schemas.d.ts +1 -1
  54. package/dist/schemas.js +2 -2
  55. package/dist/{scoring-BZqUkuDF.js → scoring-BKNNTz-s.js} +657 -3
  56. package/dist/scoring-BKNNTz-s.js.map +1 -0
  57. package/dist/{scoring-B2_HEhMT.cjs → scoring-lKQVYsxy.cjs} +722 -2
  58. package/dist/scoring-lKQVYsxy.cjs.map +1 -0
  59. package/dist/scoring.cjs +8 -2
  60. package/dist/scoring.d.cts +3 -3
  61. package/dist/scoring.d.ts +3 -3
  62. package/dist/scoring.js +3 -3
  63. package/dist/{xapi-DNzkSJ0S.cjs → xapi-NYrTlpID.cjs} +2 -2
  64. package/dist/{xapi-DNzkSJ0S.cjs.map → xapi-NYrTlpID.cjs.map} +1 -1
  65. package/dist/{xapi-CMTph7wG.js → xapi-wR6gu4qS.js} +2 -2
  66. package/dist/{xapi-CMTph7wG.js.map → xapi-wR6gu4qS.js.map} +1 -1
  67. package/dist/xapi.cjs +1 -1
  68. package/dist/xapi.d.cts +1 -1
  69. package/dist/xapi.d.ts +1 -1
  70. package/dist/xapi.js +1 -2
  71. package/package.json +2 -2
  72. package/vectors/README.md +24 -1
  73. package/vectors/scoring.json +18182 -1
  74. package/dist/ai-B222dtHH.d.cts.map +0 -1
  75. package/dist/ai-B222dtHH.d.ts.map +0 -1
  76. package/dist/ai-writing-CCBjTOM3.js.map +0 -1
  77. package/dist/ai-writing-DCVkv4Zj.cjs.map +0 -1
  78. package/dist/index-BWPRPIXL.d.ts.map +0 -1
  79. package/dist/index-Dyu66R4-.d.cts.map +0 -1
  80. package/dist/index-O4_ExlAD.d.cts.map +0 -1
  81. package/dist/index-UGxRSopE.d.ts.map +0 -1
  82. package/dist/registry-DVi0LR_i.cjs.map +0 -1
  83. package/dist/registry-Dsx9mNsS.js.map +0 -1
  84. package/dist/scoring-B2_HEhMT.cjs.map +0 -1
  85. package/dist/scoring-BZqUkuDF.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { At as ItemOutcome, Bt as ReadAloudData, Ut as ReadAloudLearnerResponse, Yt as ScoringResult, Zt as ValidationResult, ft as ActivityType, gt as DictationData, jt as LearnerResponse, mn as Grader, pn as GradeRecord, st as ActivityData } from "./ai-B222dtHH.cjs";
1
+ import { At as ActivityType, Fn as Grader, I as AiGradingJudgement, In as GraderConfiguration, Jt as ItemOutcome, Mn as GradeRecord, Nn as GradeRouting, Pt as DictationData, Tt as ActivityData, Yt as LearnerResponse, gn as WrittenResponseData, hn as ValidationResult, in as ReadAloudData, jn as CriterionScore, pn as ScoringResult, sn as ReadAloudLearnerResponse, vn as WrittenResponseRubric } from "./ai-BYryFkF9.cjs";
2
2
  //#region src/scoring/rounding.d.ts
3
3
  /**
4
4
  * Rounding for assessment scores.
@@ -564,6 +564,330 @@ interface ItemTriesScore {
564
564
  tries: ItemTryScore[];
565
565
  }
566
566
  //#endregion
567
+ //#region src/grading.d.ts
568
+ /** Options for {@link gradeFromRubric}. */
569
+ interface GradeFromRubricOptions {
570
+ /**
571
+ * Scaled score [0,1] required to pass. Defaults to the activity's
572
+ * `passThreshold`, or {@link DEFAULT_PASS_THRESHOLD} when absent.
573
+ */
574
+ passThreshold?: number;
575
+ /** Narrative feedback for the learner, carried onto the record verbatim. */
576
+ feedback?: string | null;
577
+ /**
578
+ * Compare the pass line the way the score is displayed — both sides rounded,
579
+ * via `gte` — whichever threshold applies: `passThreshold` above, the
580
+ * activity's own, or the 0.7 default. The returned `score` stays unrounded.
581
+ * Opt-in, as on `score()` and `evaluate()`: switching it on moves pass/fail
582
+ * for totals in the rounding band.
583
+ *
584
+ * Checked before any criterion is read: `null` reads as no policy, and a
585
+ * policy that cannot be applied — an unknown `mode`, or a `dp` that is not a
586
+ * whole number from 0 to 15 — throws a `RangeError`, even for a rubric that
587
+ * turns out to be unscorable.
588
+ */
589
+ rounding?: RoundingPolicy;
590
+ }
591
+ /**
592
+ * Computes the weighted total from per-criterion scores — the arithmetic that
593
+ * must NOT be delegated to a language model.
594
+ *
595
+ * A grader is asked for judgement (how good is this criterion?), not for
596
+ * mental arithmetic. Asking a model to also produce the weighted total makes
597
+ * the final grade unverifiable and unreproducible: two runs can return
598
+ * different totals for identical criterion scores. This function makes the
599
+ * total a pure function of the judgements, so a grade can be recomputed and
600
+ * audited years later.
601
+ *
602
+ * Weights are normalised by their sum, so they need not add to 1; each must be
603
+ * zero or more, and their sum a positive, finite number, or the result is
604
+ * `unscorable`. Criteria marked `notApplicable`, and those carrying no numeric
605
+ * `score` (a purely banded judgement), are excluded from both numerator and
606
+ * denominator, weight included. When nothing scoreable remains the result is
607
+ * `unscorable`, never a zero.
608
+ *
609
+ * Scores need not be in [0,1]: set `maxScore` on a criterion to declare what
610
+ * its score is out of, and each is normalised before weighting. A grader
611
+ * working out of 100 says so and is done:
612
+ *
613
+ * ```ts
614
+ * gradeFromRubric([
615
+ * { name: 'Task achievement', score: 82, maxScore: 100, weight: 2 },
616
+ * { name: 'Range', score: 7, maxScore: 9, weight: 1 },
617
+ * ]);
618
+ * ```
619
+ *
620
+ * The returned `GradeRecord.score` is always scaled [0,1] against
621
+ * `maxScore: 1`, like every other score in the SDK.
622
+ */
623
+ declare function gradeFromRubric(criteria: readonly CriterionScore[], activityData?: ActivityData, options?: GradeFromRubricOptions): GradeRecord | {
624
+ unscorable: true;
625
+ reason: string;
626
+ };
627
+ /**
628
+ * Lifts a {@link GradeRecord} into the `graded` arm of {@link ItemOutcome}, so
629
+ * a grade that arrived asynchronously renders through the same path as a
630
+ * synchronously scored item. The score/passed/feedback fields are mirrored
631
+ * onto the outcome for uniform reads; `grade` carries the full record.
632
+ *
633
+ * A record whose numbers cannot be a grade is refused, as `evaluate` refuses a
634
+ * non-finite score and {@link gradeFromRubric} one outside [0,1]. `maxScore`
635
+ * must be a positive, finite number and `score` a finite number from 0 to it (a
636
+ * hair above, one part in a billion, is float noise and passes as it is).
637
+ * Anything else — NaN, 85 "out of 1", a score out of 0 — comes back as
638
+ * `{ status: 'deferred', reason: 'grade_rejected', maxScore: 1, rejectedGrade }`
639
+ * with the record kept verbatim. Not `graded`, or its `passed` would be read as
640
+ * a verdict; not `unscorable`, which `composeAssessmentScore` drops from the
641
+ * denominator while letting the attempt go final — so a failing grade on the
642
+ * wrong scale would vanish and the rest would be recorded as a pass. Deferred
643
+ * is what it is: the slot is still owed a real grade, so a composed attempt
644
+ * stays `provisional` and names the slot in `rejectedSlotIds`.
645
+ */
646
+ declare function outcomeFromGrade(grade: GradeRecord): ItemOutcome;
647
+ /**
648
+ * True when an outcome carries a real grade — either the SDK scored it
649
+ * synchronously or a grader returned one. Use this instead of testing
650
+ * `status === 'scored'`, which silently misses asynchronously graded work.
651
+ */
652
+ declare function hasGrade(outcome: ItemOutcome): outcome is Extract<ItemOutcome, {
653
+ status: 'scored' | 'graded';
654
+ }>;
655
+ //#endregion
656
+ //#region src/scoring/assisted/calibration.d.ts
657
+ /** One response marked twice: by the model, and by a person — and, optionally, a second person. */
658
+ interface CalibrationPair {
659
+ /** The model's grade, from `gradeFromJudgement`: its `grader` names the model and the prompt. */
660
+ model: GradeRecord;
661
+ /** A person's grade of the same response, criterion by criterion. */
662
+ person: GradeRecord;
663
+ /** A second person's grade, for the human–human agreement a model is compared with. */
664
+ secondPerson?: GradeRecord;
665
+ }
666
+ /** What the responses were graded against: the rubric, and the target language. */
667
+ interface CalibrationScope {
668
+ rubric?: WrittenResponseRubric;
669
+ languageTarget?: string;
670
+ }
671
+ /** How a model's judgements of one criterion agree with a person's. Rates are fractions from 0 to 1. */
672
+ interface CriterionCalibration {
673
+ name: string;
674
+ /** `levels` when the criterion is judged on levels; `score` when on a score from 0 to 1. */
675
+ scale: 'levels' | 'score';
676
+ /** How many levels, on a criterion with levels. */
677
+ levels?: number;
678
+ /** Pairs where both judged this criterion on its scale. */
679
+ pairs: number;
680
+ /** Levels: the share of pairs on the same level. */
681
+ exactAgreement?: number | null;
682
+ /** Levels: the share of pairs at most one level apart. */
683
+ adjacentAgreement?: number | null;
684
+ /** Levels: Cohen's kappa, quadratic weights. `null` when it is undefined (no variance). */
685
+ quadraticKappa?: number | null;
686
+ /** Levels: pair counts, `confusion[personLevel][modelLevel]`, lowest first. */
687
+ confusion?: number[][];
688
+ /** Pearson's r between the two scores. `null` when undefined (fewer than 2 pairs, or no variance). */
689
+ pearson: number | null;
690
+ /** The mean absolute difference between the two scores, from 0 to 1. `null` with no pairs. */
691
+ meanAbsoluteError: number | null;
692
+ /**
693
+ * The model's mean score minus the person's, over their pooled standard
694
+ * deviation (population): positive when the model is more lenient. `null`
695
+ * when undefined.
696
+ */
697
+ standardizedMeanDifference: number | null;
698
+ /** Levels: pairs whose model grade carried level probabilities. */
699
+ probabilityPairs?: number;
700
+ /**
701
+ * Levels: expected calibration error over ten equal bins of the model's
702
+ * confidence (its likeliest level's probability): how far stated confidence
703
+ * is from how often that level was the person's. `null` without
704
+ * probabilities.
705
+ */
706
+ calibrationError?: number | null;
707
+ /** Levels: the multi-class Brier score of the probabilities against the person's level. `null` without them. */
708
+ brierScore?: number | null;
709
+ /** Pairs with a second person's grade of this criterion. */
710
+ humanPairs?: number;
711
+ /** Levels: quadratic kappa between the two people. */
712
+ humanQuadraticKappa?: number | null;
713
+ /** Pearson's r between the two people. */
714
+ humanPearson?: number | null;
715
+ /**
716
+ * How much worse the model agrees with a person than two people agree: the
717
+ * human kappa minus the model's on levels, the human r minus the model's on
718
+ * scores. `null` without a second person.
719
+ */
720
+ degradation?: number | null;
721
+ }
722
+ /** How the model's totals agree with a person's. */
723
+ interface TotalCalibration {
724
+ pairs: number;
725
+ pearson: number | null;
726
+ meanAbsoluteError: number | null;
727
+ standardizedMeanDifference: number | null;
728
+ /** The share of pairs whose pass or fail is the same. */
729
+ passAgreement: number | null;
730
+ humanPairs?: number;
731
+ humanPearson?: number | null;
732
+ degradation?: number | null;
733
+ }
734
+ /**
735
+ * How one grader configuration agrees with people, on the host's own responses.
736
+ * It ships no thresholds: the host decides what agreement admits a model to a
737
+ * paper of record, and `routeGrade` applies that decision.
738
+ */
739
+ interface CalibrationReport {
740
+ /** What this report certifies: one model, one prompt revision, one rubric, one target. */
741
+ configuration: GraderConfiguration;
742
+ /** Pairs given. */
743
+ pairs: number;
744
+ /** One entry per rubric criterion, in the rubric's order. */
745
+ criteria: CriterionCalibration[];
746
+ total: TotalCalibration;
747
+ /** `contentHash` of everything above: what a routed grade records it relied on. */
748
+ reportHash: string;
749
+ }
750
+ /** The grader configuration a model grade comes from, on items with this rubric and target; `null` when the grade does not name its model and prompt. */
751
+ declare function graderConfiguration(grade: GradeRecord, scope: CalibrationScope): GraderConfiguration | null;
752
+ /**
753
+ * How one grader configuration — a model, a prompt revision, a rubric and a
754
+ * target language — agrees with people, measured on responses the host had
755
+ * marked twice. Pure: the same pairs give the same report and the same
756
+ * `reportHash`.
757
+ *
758
+ * Every model grade must come from one configuration (its `grader` names the
759
+ * model and the prompt), and no person's grade may be a model's. A criterion
760
+ * is measured over the pairs where both judged it on its scale — levels by
761
+ * their labels, scores as fractions of their maximum — and every metric that
762
+ * is undefined is `null`, never a number made up. It ships no threshold:
763
+ * `routeGrade` applies the host's.
764
+ */
765
+ declare function calibrationReport(pairs: readonly CalibrationPair[], scope: CalibrationScope): {
766
+ ok: true;
767
+ report: CalibrationReport;
768
+ } | {
769
+ ok: false;
770
+ reason: string;
771
+ };
772
+ //#endregion
773
+ //#region src/scoring/assisted/grade-from-judgement.d.ts
774
+ /** Options for {@link gradeFromJudgement}: those of `gradeFromRubric`, but the feedback is the model's. */
775
+ type GradeFromJudgementOptions = Omit<GradeFromRubricOptions, 'feedback'>;
776
+ /**
777
+ * The grade a checked model judgement gives a written response: the total
778
+ * computed as `gradeFromRubric` computes every grade — never by the model — with
779
+ * the item's own weights and pass line, and the record a host keeps.
780
+ *
781
+ * Each criterion scores what `checkAiGrading` read: a level's place on its
782
+ * scale, or the model's score from 0 to 1. The level chosen is kept as `band`,
783
+ * its probabilities as `levelProbabilities`, and the model's identity as
784
+ * `grader` (`kind: 'ai'`, with its `model` and `promptHash`), so a routing rule
785
+ * and a calibration can read them later.
786
+ *
787
+ * `data` must be the item the request was built from: a judgement that names a
788
+ * criterion this rubric does not have, or leaves one of its criteria out, is
789
+ * `unscorable` rather than a grade on another task's rubric.
790
+ */
791
+ declare function gradeFromJudgement(judgement: AiGradingJudgement, data: WrittenResponseData, options?: GradeFromJudgementOptions): GradeRecord | {
792
+ unscorable: true;
793
+ reason: string;
794
+ };
795
+ //#endregion
796
+ //#region src/scoring/assisted/routing.d.ts
797
+ /**
798
+ * The thresholds a calibration report must meet before a model's grade counts.
799
+ * The SDK has no default for any of them, as rounding has no default `dp`: a
800
+ * threshold you leave out is not checked. A metric a threshold needs that the
801
+ * report cannot give — a kappa with no variance, a degradation without a second
802
+ * person — fails it: what cannot be shown is not assumed.
803
+ */
804
+ interface CalibrationThresholds {
805
+ /** Fewest pairs a criterion, and the total, must be measured on. */
806
+ minPairs?: number;
807
+ /** Lowest quadratic kappa, on each criterion with levels. */
808
+ minQuadraticKappa?: number;
809
+ /** Lowest exact agreement, on each criterion with levels. */
810
+ minExactAgreement?: number;
811
+ /** Lowest Pearson's r, on each criterion without levels and on the total. */
812
+ minPearson?: number;
813
+ /** Highest mean absolute error, on every criterion and the total. */
814
+ maxMeanAbsoluteError?: number;
815
+ /** Highest |standardised mean difference|, on every criterion and the total. */
816
+ maxAbsStandardizedMeanDifference?: number;
817
+ /** Highest degradation from human–human agreement, on every criterion and the total. */
818
+ maxDegradation?: number;
819
+ /** Highest expected calibration error, on each criterion with levels whose grades carry probabilities. */
820
+ maxCalibrationError?: number;
821
+ }
822
+ /** How `routeGrade` decides. Every part is optional and has no default. */
823
+ interface GradeRoutingPolicy {
824
+ /** What a calibration must show. Read when a report is supplied. */
825
+ calibration?: CalibrationThresholds;
826
+ /**
827
+ * A criterion judged on levels whose chosen level the grader gave a lower
828
+ * probability than this goes to a person (`unsure`), and so does one whose
829
+ * grade carries no distribution to read: what cannot be shown is not assumed.
830
+ */
831
+ minLevelProbability?: number;
832
+ /** Send a grade whose grader's own `confidence` is `low` to a person (`low-confidence`). */
833
+ routeLowConfidence?: boolean;
834
+ /** Send this share of grades to a person too, chosen by `inAuditSample` (`audit-sample`). */
835
+ audit?: {
836
+ rate: number;
837
+ seed: string;
838
+ };
839
+ }
840
+ /** What `routeGrade` reads besides the grade. */
841
+ interface GradeRoutingContext {
842
+ /** `exam` for a paper of record: a grade needs a matching calibration there (`no-calibration`). */
843
+ mode: 'exam' | 'practice';
844
+ /** The item graded: its rubric and target name the configuration a report must certify. */
845
+ item: CalibrationScope;
846
+ /** The calibration of this grader's configuration, when the host has one. */
847
+ calibration?: CalibrationReport;
848
+ policy?: GradeRoutingPolicy;
849
+ /** The response's stable identity — an attempt and slot — for the audit sample. Required with `policy.audit`. */
850
+ sampleKey?: string;
851
+ }
852
+ /**
853
+ * Whether `key` is in the audit sample: a stable share `rate` of keys, chosen
854
+ * by a hash of the seed and the key, so the same response is always in or
855
+ * always out, two responses are drawn independently even when their keys
856
+ * differ by one character, and changing the seed draws a new sample.
857
+ */
858
+ declare function inAuditSample(key: string, rate: number, seed: string): boolean;
859
+ /**
860
+ * Where a model's grade goes: to count, or to a person first. Deterministic —
861
+ * the same grade, context and policy always route the same way — and the
862
+ * decision says every reason it rests on, in {@link GradeRoutingReason}'s
863
+ * order, so an appeal can see why a person did or did not mark a response.
864
+ *
865
+ * - **In `exam`, a grade needs a calibration of its exact configuration**
866
+ * (`no-calibration`): the model and prompt its `grader` names, and the
867
+ * item's rubric and target. Fail closed: without a matching report, every
868
+ * grade goes to a person.
869
+ * - A supplied report must meet the policy's thresholds (`calibration-below-policy`).
870
+ * - A criterion on levels the grader was less sure of than
871
+ * `minLevelProbability`, or showed no probabilities for (`unsure`), a
872
+ * grader that asked for review (`model-asked`), a `low` confidence where
873
+ * the policy routes on it (`low-confidence`), and the audit sample
874
+ * (`audit-sample`) send it to a person too.
875
+ *
876
+ * A mode other than `exam` or `practice`, a policy threshold that is not a
877
+ * finite number, a rate outside 0 to 1, or an audit without a `sampleKey`
878
+ * throws a `RangeError`: it is the caller's configuration, not the grade's,
879
+ * and a typo must not quietly make an exam a practice.
880
+ */
881
+ declare function routeGrade(grade: GradeRecord, context: GradeRoutingContext): GradeRouting;
882
+ /**
883
+ * The outcome a routed grade gives its slot. To the model: the grade, with the
884
+ * decision on its `routing`, lifted as `outcomeFromGrade` lifts any grade. To a
885
+ * person: `{ status: 'deferred', reason: 'awaiting_human_review', pendingGrade }`
886
+ * — not `graded`, so its `passed` is never read as a verdict, and a composed
887
+ * attempt stays `provisional` until a person's grade replaces it.
888
+ */
889
+ declare function outcomeFromRoutedGrade(grade: GradeRecord, routing: GradeRouting): ItemOutcome;
890
+ //#endregion
567
891
  //#region src/scoring/dictation/align.d.ts
568
892
  /** One transcript word, or one extra word the learner typed, after alignment. */
569
893
  interface DictationWordAlignment {
@@ -1067,5 +1391,5 @@ interface ItemTriesOutcome {
1067
1391
  */
1068
1392
  declare function evaluateTries(data: ActivityData, responses: readonly LearnerResponse[], options?: EvaluateOptions): ItemTriesOutcome;
1069
1393
  //#endregion
1070
- export { SpeechAssessment as $, diffDictationChars as A, ItemTry as B, validateItemScoringPolicy as C, DICTATION_MAX_TEXT_LENGTH as D, DICTATION_MAX_EQUIVALENCE_LENGTH as E, dictationReferenceWords as F, CompositionPolicy as G, ResolvedItemScoringPolicy as H, ItemScoringCount as I, SectionScore as J, PassFailureReason as K, ItemScoringPolicy as L, DictationReference as M, DictationWordAlignment as N, DICTATION_MAX_TRANSCRIPT_LENGTH as O, alignDictation as P, ReadAloudWordState as Q, ItemScoringPolicyIssue as R, scoreTries as S, DICTATION_MAX_EQUIVALENCES as T, AssessmentScore as U, ItemTryScore as V, AssessmentSectionInput as W, GradeReadAloudOptions as X, composeAssessmentScore as Y, ReadAloudWordAlignment as Z, DEFAULT_PASS_THRESHOLD as _, evaluateTries as a, SpeechUnscorable as at, ITEM_SCORING_MAX_RETRIES as b, inspectWav as c, SpeechWordError as ct, READ_ALOUD_MAX_SECONDS as d, Band as dt, SpeechMeasurement as et, READ_ALOUD_MAX_TAKES as f, RoundingMode as ft, alignReadAloud as g, roundGrade as gt, validateSpeechAssessment as h, gte as ht, evaluate as i, SpeechSyllable as it, DictationAlignment as j, DictationCharOp as k, READ_ALOUD_MAX_DIMENSION_WEIGHT as l, WavInspection as lt, gradeReadAloud as m, classifyBand as mt, ItemTriesOutcome as n, SpeechPhonemeCandidate as nt, score as o, SpeechUnscorableCode as ot, SPEECH_ASSESSMENT_MAX_WORDS as p, RoundingPolicy as pt, ScoredItem as q, ScoringOptions as r, SpeechPlausibilityPolicy as rt, outcomeFromUnscorable as s, SpeechWord as st, EvaluateOptions as t, SpeechPhoneme as tt, READ_ALOUD_MAX_REFERENCE_LENGTH as u, WavInspectionPolicy as ut, computePassThreshold as v, DICTATION_MAX_ACCEPTED_TRANSCRIPTS as w, resolveItemScoringPolicy as x, DEFAULT_ITEM_SCORING_POLICY as y, ItemTriesScore as z };
1071
- //# sourceMappingURL=index-Dyu66R4-.d.cts.map
1394
+ export { hasGrade as $, diffDictationChars as A, Band as At, outcomeFromRoutedGrade as B, validateItemScoringPolicy as C, SpeechSyllable as Ct, DICTATION_MAX_TEXT_LENGTH as D, SpeechWordError as Dt, DICTATION_MAX_EQUIVALENCE_LENGTH as E, SpeechWord as Et, dictationReferenceWords as F, roundGrade as Ft, CalibrationReport as G, GradeFromJudgementOptions as H, CalibrationThresholds as I, TotalCalibration as J, CalibrationScope as K, GradeRoutingContext as L, DictationReference as M, RoundingPolicy as Mt, DictationWordAlignment as N, classifyBand as Nt, DICTATION_MAX_TRANSCRIPT_LENGTH as O, WavInspection as Ot, alignDictation as P, gte as Pt, gradeFromRubric as Q, GradeRoutingPolicy as R, scoreTries as S, SpeechPlausibilityPolicy as St, DICTATION_MAX_EQUIVALENCES as T, SpeechUnscorableCode as Tt, gradeFromJudgement as U, routeGrade as V, CalibrationPair as W, graderConfiguration as X, calibrationReport as Y, GradeFromRubricOptions as Z, DEFAULT_PASS_THRESHOLD as _, ReadAloudWordState as _t, evaluateTries as a, ItemTry as at, ITEM_SCORING_MAX_RETRIES as b, SpeechPhoneme as bt, inspectWav as c, AssessmentScore as ct, READ_ALOUD_MAX_SECONDS as d, PassFailureReason as dt, outcomeFromGrade as et, READ_ALOUD_MAX_TAKES as f, ScoredItem as ft, alignReadAloud as g, ReadAloudWordAlignment as gt, validateSpeechAssessment as h, GradeReadAloudOptions as ht, evaluate as i, ItemTriesScore as it, DictationAlignment as j, RoundingMode as jt, DictationCharOp as k, WavInspectionPolicy as kt, READ_ALOUD_MAX_DIMENSION_WEIGHT as l, AssessmentSectionInput as lt, gradeReadAloud as m, composeAssessmentScore as mt, ItemTriesOutcome as n, ItemScoringPolicy as nt, score as o, ItemTryScore as ot, SPEECH_ASSESSMENT_MAX_WORDS as p, SectionScore as pt, CriterionCalibration as q, ScoringOptions as r, ItemScoringPolicyIssue as rt, outcomeFromUnscorable as s, ResolvedItemScoringPolicy as st, EvaluateOptions as t, ItemScoringCount as tt, READ_ALOUD_MAX_REFERENCE_LENGTH as u, CompositionPolicy as ut, computePassThreshold as v, SpeechAssessment as vt, DICTATION_MAX_ACCEPTED_TRANSCRIPTS as w, SpeechUnscorable as wt, resolveItemScoringPolicy as x, SpeechPhonemeCandidate as xt, DEFAULT_ITEM_SCORING_POLICY as y, SpeechMeasurement as yt, inAuditSample as z };
1395
+ //# sourceMappingURL=index-Bg0aeWtM.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-Bg0aeWtM.d.cts","names":[],"sources":["../src/scoring/rounding.ts","../src/types/speech.ts","../src/scoring/compose.ts","../src/types/item-scoring.ts","../src/grading.ts","../src/scoring/assisted/calibration.ts","../src/scoring/assisted/grade-from-judgement.ts","../src/scoring/assisted/routing.ts","../src/scoring/dictation/align.ts","../src/scoring/dictation/chars.ts","../src/scoring/dictation/normalize.ts","../src/scoring/item-scoring.ts","../src/scoring/pass-threshold.ts","../src/scoring/speech/align.ts","../src/scoring/speech/assessment.ts","../src/scoring/speech/grade.ts","../src/scoring/speech/limits.ts","../src/scoring/speech/wav.ts","../src/scoring/unscorable.ts","../src/scoring/index.ts"],"mappings":"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"}
@@ -1,218 +1,4 @@
1
- import { Rt as MultipleChoiceOptionMedia, Zt as ValidationResult, ct as ActivityDataMap, ft as ActivityType, st as ActivityData, ut as ActivityMedia } from "./ai-B222dtHH.js";
2
- //#region src/types/item-group.d.ts
3
- /** What a stimulus primarily is. Drives validation and layout, never scoring. */
4
- type StimulusKind = 'text' | 'audio' | 'video' | 'image' | 'mixed';
5
- /**
6
- * Shared material that several items refer to: a reading passage, a
7
- * recording, a chart. Modelled as CONTENT — it lives inside the item group
8
- * that carries it — so it works in a lesson quiz, a sequence and an exam
9
- * section alike, and needs no blueprint to exist.
10
- *
11
- * Learner-visible by definition: the point of a stimulus is that the learner
12
- * reads or hears it. The one exception is `transcript`, an author asset that
13
- * `redactItemGroup` removes.
14
- */
15
- interface Stimulus {
16
- id: string;
17
- kind: StimulusKind;
18
- /** Optional heading (a passage title). */
19
- title?: string;
20
- /**
21
- * Plain-text body: the passage itself, or short instructions above media.
22
- * Required for `text` and `mixed`.
23
- */
24
- body?: string;
25
- /**
26
- * Optional sanitised rich-HTML sidecar of `body`. Requires `body`, which is
27
- * the accessible fallback rendered when no sanitiser is supplied.
28
- */
29
- bodyHtml?: string;
30
- /** The recording, video or image. Required for `audio`, `video`, `image` and `mixed`. */
31
- media?: ActivityMedia;
32
- /**
33
- * Author-only transcript of `media` — for item generation and grading,
34
- * never shown to the learner. Removed by `redactItemGroup`.
35
- */
36
- transcript?: string;
37
- /** BCP 47 language tag of the material, when it differs from the items'. */
38
- locale?: string;
39
- /** Source credit, shown to the learner after the material. */
40
- attribution?: string;
41
- }
42
- /**
43
- * A quiz inside an interactive video: one moment of the video, and the
44
- * questions shown there. The video pauses when playback reaches `at`, and the
45
- * questions are shown one at a time, in `itemIds` order.
46
- */
47
- interface TimelineCue {
48
- /** Unique within the timeline. Names the quiz in events, the contents panel and drafts. */
49
- id: string;
50
- /**
51
- * Seconds from the start of the video: finite and 0 or more. The SDK never
52
- * reads the video, so it cannot check this against the duration: a quiz at
53
- * or past the end opens when the video ends.
54
- */
55
- at: number;
56
- /**
57
- * `id`s of items in this group, in the order the quiz shows them. Non-empty.
58
- * Every item of the group belongs to exactly one quiz.
59
- */
60
- itemIds: string[];
61
- /** Optional heading shown above the questions. At most 120 characters. */
62
- title?: string;
63
- /**
64
- * Every question must be answered (practice) or submitted (exam) before
65
- * playback may pass `at`. Default false.
66
- */
67
- required?: boolean;
68
- }
69
- /** A titled section of the video. */
70
- interface TimelineChapter {
71
- /** Seconds from the start: finite, 0 or more, strictly increasing across the list. */
72
- at: number;
73
- /** Non-empty after trimming; at most 120 characters. */
74
- title: string;
75
- }
76
- /**
77
- * The arrangement that turns an item group with a video stimulus into an
78
- * interactive video: when each quiz opens, the video's chapters, and how far
79
- * ahead a learner may seek.
80
- *
81
- * It lives on the container rather than inside `stimulus` because it describes
82
- * how THESE questions are arranged over the material, not the material itself.
83
- */
84
- interface MediaTimeline {
85
- cues: TimelineCue[];
86
- chapters?: TimelineChapter[];
87
- /**
88
- * `free` (default): seek anywhere. `no-skip-ahead`: rewind freely, never past
89
- * the furthest point reached. Either way, playback never passes a `required`
90
- * quiz that is not finished.
91
- */
92
- navigation?: 'free' | 'no-skip-ahead';
93
- }
94
- /**
95
- * Where a learner stands in an interactive video, stored by the host so the
96
- * video can resume. Kept apart from `AttemptState`, which holds answers by slot
97
- * and drops fields it does not know. Read it back through
98
- * `readMediaProgress`, never directly.
99
- */
100
- interface MediaProgress {
101
- progressVersion: '1.0';
102
- /** Seconds: where playback last stood. */
103
- at: number;
104
- /**
105
- * Seconds: the furthest point reached. Decides how far `no-skip-ahead` lets
106
- * the learner seek, and how much of the transcript it shows.
107
- */
108
- furthest: number;
109
- }
110
- /**
111
- * One stimulus serving several items. Two rules, both taken from observed
112
- * failures: a group is SHUFFLE-ATOMIC (shuffling a sequence moves the group
113
- * as one block — interleaving two passages' questions is the defect), and its
114
- * stimulus is presented persistently alongside every item, never behind a
115
- * toggle the learner must reopen per question.
116
- *
117
- * Generic over the item type so one shape describes a group of full activity
118
- * data (authoring, server) and a group of `redact()` projections (client)
119
- * without a cast at every boundary.
120
- */
121
- interface ItemGroup<TItem = ActivityData> {
122
- schemaVersion: '1.0';
123
- type: 'item-group';
124
- id: string;
125
- title?: string;
126
- /**
127
- * Stable identity for this entry's slots, independent of where it sits in
128
- * the array. See {@link SequenceSlot.slotId}: without one, inserting a
129
- * question above this group re-maps every slot id beneath it, and stored
130
- * grades quietly start naming different questions.
131
- */
132
- slotKey?: string;
133
- stimulus: Stimulus;
134
- /**
135
- * The items, in authored order. Non-empty; ids unique within the group; no
136
- * nested groups.
137
- *
138
- * An item may declare its own `slotKey`, for the same reason an entry can:
139
- * it pins the item's identity within the group (`"reading.q1"` rather than
140
- * `"reading.0"`), so inserting a question into a published group does not
141
- * re-map the ones after it.
142
- */
143
- items: (TItem & {
144
- slotKey?: string;
145
- })[];
146
- /**
147
- * `none` (default) keeps authored order; `within-group` shuffles the items
148
- * among themselves under the sequence seed. Either way the group stays one
149
- * contiguous block.
150
- */
151
- shuffle?: 'none' | 'within-group';
152
- /**
153
- * Makes the group an interactive video: the stimulus must be a video, every
154
- * item must be one of `INTERACTIVE_VIDEO_ITEM_TYPES`, and every item belongs
155
- * to exactly one quiz. Items are then presented in quiz order, never
156
- * shuffled. An older lk-core that does not know this field presents the same
157
- * items as an ordinary video testlet, with the same slots and grades.
158
- */
159
- timeline?: MediaTimeline;
160
- }
161
- /**
162
- * What a sequence is made of: loose activities and item groups, in authored
163
- * order.
164
- *
165
- * A plain activity may carry `slotKey` here even though no activity SCHEMA
166
- * declares one, because a slot key describes an item's PLACE in a paper, not
167
- * its content — the same question keeps its own id in every paper it appears
168
- * in. Putting it on the entry rather than on the activity is what lets it be
169
- * authored without every activity type having to know about assessment
170
- * assembly. See {@link SequenceSlot.slotId}.
171
- */
172
- type SequenceEntry<TItem = ActivityData> = (TItem & {
173
- slotKey?: string;
174
- }) | ItemGroup<TItem>;
175
- /** The group a presented slot belongs to. */
176
- interface SequenceSlotGroup {
177
- id: string;
178
- title?: string;
179
- stimulus: Stimulus;
180
- /** 0-based position of this slot within the group's PRESENTED order. */
181
- position: number;
182
- /** Number of slots in the group. */
183
- size: number;
184
- /** The group's timeline, when the group is an interactive video. */
185
- timeline?: MediaTimeline;
186
- /** The quiz this slot's item sits in, when the group is an interactive video. */
187
- cue?: TimelineCue;
188
- }
189
- /** One presented position in a flattened sequence. */
190
- interface SequenceSlot<TItem = ActivityData> {
191
- /**
192
- * Identity of the slot within the sequence definition — unique, and stable
193
- * under shuffling. Feed it to `composeAssessmentScore` as `slotId`.
194
- *
195
- * By default it is derived from the AUTHORED position (`"2"` for the third
196
- * top-level entry; `"2.1"` for the second item of that entry when it is a
197
- * group), so the same activity can appear in two entries and still be two
198
- * slots.
199
- *
200
- * **A positional id is only valid against one version of the entries
201
- * array.** Insert a question at the top of a published paper and every id
202
- * below it shifts: rows stored as `"3"` now name what used to be entry 2,
203
- * and a re-grade or a review render pairs each response with the wrong
204
- * question — silently, because the ids still look valid. For any content
205
- * whose slot ids you persist, give the entries an explicit `slotKey`; it is
206
- * used verbatim here and survives insertion, deletion and re-ordering.
207
- */
208
- slotId: string;
209
- /** 0-based PRESENTED position, after shuffling. */
210
- index: number;
211
- activity: TItem;
212
- /** Present when the slot comes from an item group. */
213
- group?: SequenceSlotGroup;
214
- }
215
- //#endregion
1
+ import { At as ActivityType, Et as ActivityDataMap, Ot as ActivityMedia, hn as ValidationResult, nn as MultipleChoiceOptionMedia, st as ItemGroup } from "./ai-BYryFkF9.js";
216
2
  //#region src/types/redacted.d.ts
217
3
  /**
218
4
  * The learner-safe SHAPE of each built-in type.
@@ -324,6 +110,10 @@ interface RedactedWrittenResponseData extends RedactedItem {
324
110
  name: string;
325
111
  weight: number;
326
112
  description?: string | undefined;
113
+ levels?: {
114
+ label: string;
115
+ description?: string | undefined;
116
+ }[] | undefined;
327
117
  }[];
328
118
  label?: string | undefined;
329
119
  } | undefined;
@@ -549,5 +339,5 @@ declare function validateOptionMedia(value: unknown): ValidationResult<MultipleC
549
339
  */
550
340
  declare function validateActivity<T extends ActivityType>(type: T, data: unknown): ValidationResult<ActivityDataMap[T]>;
551
341
  //#endregion
552
- export { MediaProgress as A, RedactedMultipleChoiceData as C, RedactedStimulus as D, RedactedReadAloudData as E, Stimulus as F, StimulusKind as I, TimelineChapter as L, SequenceEntry as M, SequenceSlot as N, RedactedWrittenResponseData as O, SequenceSlotGroup as P, TimelineCue as R, RedactedGapSelectGap as S, RedactedMultipleChoiceOptionMedia as T, RedactedDictationSlowMedia as _, fillInTheBlanksJsonSchema as a, RedactedGapSelectChoice as b, jsonSchemaFor as c, stimulusJsonSchema as d, writtenResponseJsonSchema as f, RedactedDictationData as g, RedactedBlankConfig as h, dictationJsonSchema as i, MediaTimeline as j, ItemGroup as k, multipleChoiceJsonSchema as l, RedactedActivity as m, validateMedia as n, gapSelectJsonSchema as o, validateItemGroup as p, validateOptionMedia as r, itemGroupJsonSchema as s, validateActivity as t, readAloudJsonSchema as u, RedactedFillInTheBlanksData as v, RedactedMultipleChoiceOption as w, RedactedGapSelectData as x, RedactedGapSelectBank as y };
553
- //# sourceMappingURL=index-BWPRPIXL.d.ts.map
342
+ export { RedactedMultipleChoiceData as C, RedactedStimulus as D, RedactedReadAloudData as E, RedactedWrittenResponseData as O, RedactedGapSelectGap as S, RedactedMultipleChoiceOptionMedia as T, RedactedDictationSlowMedia as _, fillInTheBlanksJsonSchema as a, RedactedGapSelectChoice as b, jsonSchemaFor as c, stimulusJsonSchema as d, writtenResponseJsonSchema as f, RedactedDictationData as g, RedactedBlankConfig as h, dictationJsonSchema as i, multipleChoiceJsonSchema as l, RedactedActivity as m, validateMedia as n, gapSelectJsonSchema as o, validateItemGroup as p, validateOptionMedia as r, itemGroupJsonSchema as s, validateActivity as t, readAloudJsonSchema as u, RedactedFillInTheBlanksData as v, RedactedMultipleChoiceOption as w, RedactedGapSelectData as x, RedactedGapSelectBank as y };
343
+ //# sourceMappingURL=index-CxpiWedW.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-CxpiWedW.d.ts","names":[],"sources":["../src/types/redacted.ts","../src/schemas/item-group.ts","../src/schemas/json-schema.ts","../src/schemas/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;UAoBU;EACR;EACA;EACA;EACA;EACA;;;UAIQ;EACR;EACA;EACA;EACA;EACA;;;UAIQ;EACR;EACA;EACA;EACA;EACA,SAAS;EACT;EACA,WAAW;;;UAIH;EACR;EACA;;;UAIQ;EACR;EACA;EACA;EACA;EACA;EACA,QAAQ;EACR;EACA;EACA;EACA,KAAK;;;UAIU;EACf;EACA;EACA;EACA;;;UAIe;EACf;EACA;EACA,QAAQ;;;UAIO,mCAAmC;EAClD;EACA;EACA;EACA;EACA,SAAS;EACT;EACA;;;UAIe;EACf;EACA;;;UAIe,oCAAoC;EACnD;EACA;EACA;EACA,QAAQ;EACR;;;UAIe,oCAAoC;EACnD;EACA;EACA;EACA;EACA;EACA;IAEM;MACE;MACA;MACA;MACA;QAAW;QAAe;;;IAE5B;;EAGN;EACA;;;UAIe;EACf;EACA;;;UAIe;EACf;EACA,SAAS;;;UAIM;EACf;EACA,UAAU;EACV;;;UAIe,8BAA8B;EAC7C;EACA;EACA;EACA,MAAM;EACN,QAAQ;EACR;EACA;EACA;;;UAIe;EACf;EACA;EACA;;;UAIe,8BAA8B;EAC7C;EACA,YAAY;EACZ;IAAU;;EACV;;;;;;;UAQe,8BAA8B;EAC7C;EACA;EACA;EACA;EACA,YAAY;EACZ;IACE;IACA;IACA;;EAEF;IACE;MACE;MACA;;;;;UAMW;EACf;EACA;EACA;EACA;EACA;EACA,QAAQ;EACR;EACA;;;;;;;;;;;;;;KAeU,mBACR,6BACA,8BACA,8BACA,wBACA,wBACA;;;;;;;;;;;;;iBC2MY,kBAAkB,gBAAgB,iBAAiB;;;;;;;cClatD,oBAAoB;;;;;;;;cAWpB,qBAAqB;;;;;;;;;;;;;;;;;;cAqBrB,qBAAqB;;;;;;;;;;;cAcrB,qBAAqB;;;;;;;;;;cAarB,qBAAqB;cAIrB,0BAA0B;;;;;;cAY1B,2BAA2B;;;;;cAW3B,2BAA2B;;;;;;;;;;;;;;;;iBAsBxB,cAAc,eAAe;;;;;;;;;;;;;iBCvE7B,cAAc,iBAAiB,iBAAiB;;;;;;;;iBAWhD,oBAAoB,iBAAiB,iBAAiB;;;;;;;;;;;;;iBA8BtD,iBAAiB,UAAU,cACzC,MAAM,GACN,gBACC,iBAAiB,gBAAgB"}
@@ -1,4 +1,4 @@
1
- import { Yt as ScoringResult, cn as XAPIResult, in as XAPIContext, nn as XAPIActor, un as XAPIStatement } from "./ai-B222dtHH.cjs";
1
+ import { Cn as XAPIContext, Dn as XAPIResult, kn as XAPIStatement, pn as ScoringResult, xn as XAPIActor } from "./ai-BYryFkF9.cjs";
2
2
  //#region src/xapi/verbs.d.ts
3
3
  /**
4
4
  * The set of xAPI verbs emitted by SDK activities, keyed by a stable
@@ -150,4 +150,4 @@ declare function xapiDefinitionFor(data: {
150
150
  declare function validateXAPIStatement(statement: XAPIStatement): void;
151
151
  //#endregion
152
152
  export { XAPIObjectParams as a, xapiDefinitionFor as c, XAPI_VERB_DISPLAY as d, SubmittedStatementParams as i, XAPIVerb as l, AnsweredStatementParams as n, XAPIStatementParams as o, CompletedStatementParams as r, xAPIBuilder as s, validateXAPIStatement as t, XAPIVerbKey as u };
153
- //# sourceMappingURL=index-CXyOV8sm.d.cts.map
153
+ //# sourceMappingURL=index-D7R3Ll8R.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-CXyOV8sm.d.cts","names":[],"sources":["../src/xapi/verbs.ts","../src/xapi/builder.ts","../src/xapi/validators.ts"],"mappings":";;;;;;cAIa;;;;;;;;;;;;;;;;;;;;;;;;;;KA2BD,2BAA2B;;;;;cAM1B,mBAAmB,OAAO,aAAa;;;;UCxBnC;;EAEf;EACA,OAAO;EACP,cAAc;;EAEd;;EAEA;;EAEA;;EAEA,UAAU;IAAQ;IAAY,cAAc;;;;UAI7B;EACf,OAAO;EACP,MAAM;EACN,QAAQ;EACR,SAAS;EACT,UAAU;;;UAIK;EACf,OAAO;EACP,QAAQ;EACR,eAAe;EACf;;EAEA;EACA,UAAU;EACV,mBAAmB;;;;;;;UAQJ;EACf,OAAO;EACP,QAAQ;EACR;;EAEA;EACA,UAAU;EACV,mBAAmB;;;UAIJ;EACf,OAAO;EACP,QAAQ;EACR,gBAAgB;EAChB;EACA,UAAU;EACV,mBAAmB;;;;;;;cAiGR;EACY,eAAA,QAAA,sBAAsB;EAoBd,uBAAA,QAAA,0BAA0B;;;;;;;EAqBzB,wBAAA,QAAA,2BAA2B;EAc3B,wBAAA,QAAA,2BAA2B;;;;;;;;;;;;;;;;iBA8B7C,kBAAkB;EAAQ;IAAiB,QAAQ;;;;;;;;;;;;;;;;iBClHnD,sBAAsB,WAAW"}
1
+ {"version":3,"file":"index-D7R3Ll8R.d.cts","names":[],"sources":["../src/xapi/verbs.ts","../src/xapi/builder.ts","../src/xapi/validators.ts"],"mappings":";;;;;;cAIa;;;;;;;;;;;;;;;;;;;;;;;;;;KA2BD,2BAA2B;;;;;cAM1B,mBAAmB,OAAO,aAAa;;;;UCxBnC;;EAEf;EACA,OAAO;EACP,cAAc;;EAEd;;EAEA;;EAEA;;EAEA,UAAU;IAAQ;IAAY,cAAc;;;;UAI7B;EACf,OAAO;EACP,MAAM;EACN,QAAQ;EACR,SAAS;EACT,UAAU;;;UAIK;EACf,OAAO;EACP,QAAQ;EACR,eAAe;EACf;;EAEA;EACA,UAAU;EACV,mBAAmB;;;;;;;UAQJ;EACf,OAAO;EACP,QAAQ;EACR;;EAEA;EACA,UAAU;EACV,mBAAmB;;;UAIJ;EACf,OAAO;EACP,QAAQ;EACR,gBAAgB;EAChB;EACA,UAAU;EACV,mBAAmB;;;;;;;cAiGR;EACY,eAAA,QAAA,sBAAsB;EAoBd,uBAAA,QAAA,0BAA0B;;;;;;;EAqBzB,wBAAA,QAAA,2BAA2B;EAc3B,wBAAA,QAAA,2BAA2B;;;;;;;;;;;;;;;;iBA8B7C,kBAAkB;EAAQ;IAAiB,QAAQ;;;;;;;;;;;;;;;;iBClHnD,sBAAsB,WAAW"}