@segnavia/format 0.37.0 → 0.39.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 (66) hide show
  1. package/dist/board-edit.d.ts +2 -1
  2. package/dist/board-geometry.d.ts +2 -1
  3. package/dist/board-section-grid.d.ts +2 -1
  4. package/dist/board-sections.d.ts +2 -1
  5. package/dist/board.d.ts +8 -8
  6. package/dist/board.js +15 -11
  7. package/dist/book-exports.d.ts +4 -0
  8. package/dist/book-section.d.ts +225 -3
  9. package/dist/book-section.js +82 -17
  10. package/dist/book.d.ts +878 -416
  11. package/dist/book.js +236 -37
  12. package/dist/cover.d.ts +337 -0
  13. package/dist/cover.js +100 -0
  14. package/dist/deck-from-slides.d.ts +23 -4
  15. package/dist/deck.d.ts +144 -42
  16. package/dist/deck.js +22 -24
  17. package/dist/dependency-policy.d.ts +12 -0
  18. package/dist/dependency-policy.js +42 -0
  19. package/dist/direction.d.ts +1 -1
  20. package/dist/font-collection.d.ts +8 -0
  21. package/dist/font-collection.js +191 -0
  22. package/dist/font-face.d.ts +8 -0
  23. package/dist/font-face.js +24 -0
  24. package/dist/font-refusal.d.ts +5 -0
  25. package/dist/font-refusal.js +9 -0
  26. package/dist/font-signature.d.ts +5 -0
  27. package/dist/font-signature.js +13 -0
  28. package/dist/fonts.d.ts +6 -1
  29. package/dist/fonts.js +3 -1
  30. package/dist/geometry.d.ts +20 -0
  31. package/dist/geometry.js +18 -0
  32. package/dist/image-fit.d.ts +10 -0
  33. package/dist/image-fit.js +10 -0
  34. package/dist/imposition-marks.d.ts +1 -1
  35. package/dist/imposition-schema.d.ts +185 -0
  36. package/dist/imposition-schema.js +122 -0
  37. package/dist/imposition.d.ts +8 -6
  38. package/dist/index.d.ts +29 -1797
  39. package/dist/index.js +30 -210
  40. package/dist/json-schemas.d.ts +1860 -0
  41. package/dist/json-schemas.js +43 -0
  42. package/dist/local-font-limits.d.ts +15 -0
  43. package/dist/local-font-limits.js +24 -0
  44. package/dist/media.d.ts +152 -0
  45. package/dist/media.js +119 -0
  46. package/dist/note-series.d.ts +70 -0
  47. package/dist/note-series.js +153 -0
  48. package/dist/page.d.ts +174 -0
  49. package/dist/page.js +37 -0
  50. package/dist/paper.d.ts +2 -1
  51. package/dist/paper.js +2 -1
  52. package/dist/placement-cycle.d.ts +5 -0
  53. package/dist/placement-cycle.js +30 -0
  54. package/dist/placement-refusal.d.ts +5 -0
  55. package/dist/placement-refusal.js +6 -0
  56. package/dist/placement.d.ts +76 -0
  57. package/dist/placement.js +100 -0
  58. package/dist/print.d.ts +72 -0
  59. package/dist/print.js +38 -0
  60. package/dist/printed-page-imposition.d.ts +2 -1
  61. package/dist/printed-pages.d.ts +14 -0
  62. package/dist/printed-pages.js +14 -1
  63. package/dist/shots-used.d.ts +0 -1
  64. package/dist/shots-used.js +2 -2
  65. package/dist/slots.d.ts +13 -13
  66. package/package.json +1 -1
@@ -0,0 +1,43 @@
1
+ import { Media } from "./media.js";
2
+ import { PlacementShape } from "./placement.js";
3
+ import { SlotDeclaration, SlotDeclarationInput } from "./slots.js";
4
+ import { DeckShape, Manifest, PublishedShot } from "./deck.js";
5
+ import { Board } from "./board.js";
6
+ import { FontReference, FontReferenceInput, LocalFaceTransport, LocalFacesTransport } from "./fonts.js";
7
+ import { Motif, MotifInput } from "./motif.js";
8
+ import { PrintSetting, PrintSettingInput } from "./paper.js";
9
+ import { BookShape, BookView } from "./book.js";
10
+ import { Page } from "./page.js";
11
+ import { Cover } from "./cover.js";
12
+ import { Imposition } from "./imposition-schema.js";
13
+ import { Lexicon } from "./lexicon.js";
14
+ import { z } from "zod";
15
+ //#region src/json-schemas.ts
16
+ function jsonSchemas() {
17
+ return {
18
+ book: z.toJSONSchema(BookShape, { io: "input" }),
19
+ bookView: z.toJSONSchema(BookView, { io: "input" }),
20
+ page: z.toJSONSchema(Page, { io: "input" }),
21
+ lexicon: z.toJSONSchema(Lexicon, { io: "input" }),
22
+ imposition: z.toJSONSchema(Imposition, { io: "input" }),
23
+ deck: z.toJSONSchema(DeckShape, { io: "input" }),
24
+ manifest: z.toJSONSchema(Manifest, { io: "input" }),
25
+ publishedShot: z.toJSONSchema(PublishedShot, { io: "input" }),
26
+ board: z.toJSONSchema(Board, { io: "input" }),
27
+ printSetting: z.toJSONSchema(PrintSetting, { io: "input" }),
28
+ printSettingInput: z.toJSONSchema(PrintSettingInput, { io: "input" }),
29
+ slotDeclaration: z.toJSONSchema(SlotDeclaration, { io: "input" }),
30
+ slotDeclarationInput: z.toJSONSchema(SlotDeclarationInput, { io: "input" }),
31
+ fontReference: z.toJSONSchema(FontReference, { io: "input" }),
32
+ fontReferenceInput: z.toJSONSchema(FontReferenceInput, { io: "input" }),
33
+ localFaceTransport: z.toJSONSchema(LocalFaceTransport, { io: "input" }),
34
+ localFacesTransport: z.toJSONSchema(LocalFacesTransport, { io: "input" }),
35
+ motif: z.toJSONSchema(Motif, { io: "input" }),
36
+ motifInput: z.toJSONSchema(MotifInput, { io: "input" }),
37
+ media: z.toJSONSchema(Media, { io: "input" }),
38
+ placement: z.toJSONSchema(PlacementShape, { io: "input" }),
39
+ cover: z.toJSONSchema(Cover, { io: "input" })
40
+ };
41
+ }
42
+ //#endregion
43
+ export { jsonSchemas };
@@ -0,0 +1,15 @@
1
+ //#region src/local-font-limits.d.ts
2
+ export interface LocalFontLimits {
3
+ count?: number;
4
+ bytes?: number;
5
+ }
6
+ export interface LocalFontLimitFace {
7
+ family: string;
8
+ bytes: number;
9
+ }
10
+ export declare const LOCAL_FONT_LIMITS: {
11
+ readonly count: 64;
12
+ readonly bytes: number;
13
+ };
14
+ export declare function localFontLimitRefusal(faces: readonly LocalFontLimitFace[], limits?: LocalFontLimits): string | undefined;
15
+ //#endregion
@@ -0,0 +1,24 @@
1
+ //#region src/local-font-limits.ts
2
+ const LOCAL_FONT_LIMITS = {
3
+ count: 64,
4
+ bytes: 33554432
5
+ };
6
+ function limit(value, fallback, label) {
7
+ const resolved = value ?? fallback;
8
+ if (!Number.isSafeInteger(resolved) || resolved < 0) return `The local font ${label} limit must be a non-negative safe integer; pass valid limits to clear this refusal.`;
9
+ return resolved;
10
+ }
11
+ function localFontLimitRefusal(faces, limits = {}) {
12
+ const countLimit = limit(limits.count, LOCAL_FONT_LIMITS.count, "count");
13
+ if (typeof countLimit === "string") return countLimit;
14
+ const byteLimit = limit(limits.bytes, LOCAL_FONT_LIMITS.bytes, "byte");
15
+ if (typeof byteLimit === "string") return byteLimit;
16
+ if (faces.length > countLimit) return `The local face ${JSON.stringify(faces[countLimit]?.family ?? "unknown family")} exceeds the count limit of ${countLimit}; pass higher limits or declare fewer local font families to clear this refusal.`;
17
+ let bytes = 0;
18
+ for (const face of faces) {
19
+ bytes += face.bytes;
20
+ if (bytes > byteLimit) return `The local face ${JSON.stringify(face.family)} exceeds the byte limit of ${byteLimit}; pass higher limits or declare fewer local font families to clear this refusal.`;
21
+ }
22
+ }
23
+ //#endregion
24
+ export { LOCAL_FONT_LIMITS, localFontLimitRefusal };
@@ -0,0 +1,152 @@
1
+ import { TextDirection } from "./direction.js";
2
+ import { z } from "zod";
3
+ //#region src/media.d.ts
4
+ export declare const MediaFormat: z.ZodEnum<{
5
+ png: "png";
6
+ jpeg: "jpeg";
7
+ gif: "gif";
8
+ webp: "webp";
9
+ svg: "svg";
10
+ pdf: "pdf";
11
+ ai: "ai";
12
+ }>;
13
+ export type MediaFormat = z.infer<typeof MediaFormat>;
14
+ export declare const MEDIA_FORMATS: Record<MediaFormat, {
15
+ pages: boolean;
16
+ raster: boolean;
17
+ }>;
18
+ export declare const MediaText: z.ZodObject<{
19
+ text: z.ZodString;
20
+ lang: z.ZodOptional<z.ZodString>;
21
+ dir: z.ZodOptional<z.ZodEnum<{
22
+ auto: "auto";
23
+ ltr: "ltr";
24
+ rtl: "rtl";
25
+ }>>;
26
+ }, z.core.$strip>;
27
+ export type MediaText = z.infer<typeof MediaText>;
28
+ export declare function mediaTextDirection(text: MediaText): TextDirection;
29
+ export declare const PageSelector: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
30
+ export type PageSelector = z.infer<typeof PageSelector>;
31
+ export declare const MediaPage: z.ZodObject<{
32
+ name: z.ZodOptional<z.ZodString>;
33
+ boxes: z.ZodObject<{
34
+ media: z.ZodObject<{
35
+ x: z.ZodNumber;
36
+ y: z.ZodNumber;
37
+ width: z.ZodNumber;
38
+ height: z.ZodNumber;
39
+ }, z.core.$strip>;
40
+ crop: z.ZodOptional<z.ZodObject<{
41
+ x: z.ZodNumber;
42
+ y: z.ZodNumber;
43
+ width: z.ZodNumber;
44
+ height: z.ZodNumber;
45
+ }, z.core.$strip>>;
46
+ trim: z.ZodOptional<z.ZodObject<{
47
+ x: z.ZodNumber;
48
+ y: z.ZodNumber;
49
+ width: z.ZodNumber;
50
+ height: z.ZodNumber;
51
+ }, z.core.$strip>>;
52
+ bleed: z.ZodOptional<z.ZodObject<{
53
+ x: z.ZodNumber;
54
+ y: z.ZodNumber;
55
+ width: z.ZodNumber;
56
+ height: z.ZodNumber;
57
+ }, z.core.$strip>>;
58
+ art: z.ZodOptional<z.ZodObject<{
59
+ x: z.ZodNumber;
60
+ y: z.ZodNumber;
61
+ width: z.ZodNumber;
62
+ height: z.ZodNumber;
63
+ }, z.core.$strip>>;
64
+ }, z.core.$strip>;
65
+ }, z.core.$strip>;
66
+ export type MediaPage = z.infer<typeof MediaPage>;
67
+ export declare const Media: z.ZodObject<{
68
+ format: z.ZodEnum<{
69
+ png: "png";
70
+ jpeg: "jpeg";
71
+ gif: "gif";
72
+ webp: "webp";
73
+ svg: "svg";
74
+ pdf: "pdf";
75
+ ai: "ai";
76
+ }>;
77
+ size: z.ZodObject<{
78
+ width: z.ZodNumber;
79
+ height: z.ZodNumber;
80
+ }, z.core.$strip>;
81
+ pages: z.ZodOptional<z.ZodArray<z.ZodObject<{
82
+ name: z.ZodOptional<z.ZodString>;
83
+ boxes: z.ZodObject<{
84
+ media: z.ZodObject<{
85
+ x: z.ZodNumber;
86
+ y: z.ZodNumber;
87
+ width: z.ZodNumber;
88
+ height: z.ZodNumber;
89
+ }, z.core.$strip>;
90
+ crop: z.ZodOptional<z.ZodObject<{
91
+ x: z.ZodNumber;
92
+ y: z.ZodNumber;
93
+ width: z.ZodNumber;
94
+ height: z.ZodNumber;
95
+ }, z.core.$strip>>;
96
+ trim: z.ZodOptional<z.ZodObject<{
97
+ x: z.ZodNumber;
98
+ y: z.ZodNumber;
99
+ width: z.ZodNumber;
100
+ height: z.ZodNumber;
101
+ }, z.core.$strip>>;
102
+ bleed: z.ZodOptional<z.ZodObject<{
103
+ x: z.ZodNumber;
104
+ y: z.ZodNumber;
105
+ width: z.ZodNumber;
106
+ height: z.ZodNumber;
107
+ }, z.core.$strip>>;
108
+ art: z.ZodOptional<z.ZodObject<{
109
+ x: z.ZodNumber;
110
+ y: z.ZodNumber;
111
+ width: z.ZodNumber;
112
+ height: z.ZodNumber;
113
+ }, z.core.$strip>>;
114
+ }, z.core.$strip>;
115
+ }, z.core.$strip>>>;
116
+ resolution: z.ZodOptional<z.ZodNumber>;
117
+ alt: z.ZodOptional<z.ZodObject<{
118
+ text: z.ZodString;
119
+ lang: z.ZodOptional<z.ZodString>;
120
+ dir: z.ZodOptional<z.ZodEnum<{
121
+ auto: "auto";
122
+ ltr: "ltr";
123
+ rtl: "rtl";
124
+ }>>;
125
+ }, z.core.$strip>>;
126
+ caption: z.ZodOptional<z.ZodObject<{
127
+ text: z.ZodString;
128
+ lang: z.ZodOptional<z.ZodString>;
129
+ dir: z.ZodOptional<z.ZodEnum<{
130
+ auto: "auto";
131
+ ltr: "ltr";
132
+ rtl: "rtl";
133
+ }>>;
134
+ }, z.core.$strip>>;
135
+ credit: z.ZodOptional<z.ZodObject<{
136
+ text: z.ZodString;
137
+ lang: z.ZodOptional<z.ZodString>;
138
+ dir: z.ZodOptional<z.ZodEnum<{
139
+ auto: "auto";
140
+ ltr: "ltr";
141
+ rtl: "rtl";
142
+ }>>;
143
+ }, z.core.$strip>>;
144
+ derivedFrom: z.ZodOptional<z.ZodObject<{
145
+ address: z.ZodString;
146
+ page: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
147
+ name: z.ZodOptional<z.ZodString>;
148
+ }, z.core.$strip>>;
149
+ }, z.core.$strip>;
150
+ export type Media = z.infer<typeof Media>;
151
+ export type MediaInput = z.input<typeof Media>;
152
+ //#endregion
package/dist/media.js ADDED
@@ -0,0 +1,119 @@
1
+ import { Direction, resolveDirection } from "./direction.js";
2
+ import { Box } from "./geometry.js";
3
+ import { z } from "zod";
4
+ //#region src/media.ts
5
+ const MediaFormat = z.enum([
6
+ "png",
7
+ "jpeg",
8
+ "gif",
9
+ "webp",
10
+ "svg",
11
+ "pdf",
12
+ "ai"
13
+ ]);
14
+ const MEDIA_FORMATS = {
15
+ png: {
16
+ pages: false,
17
+ raster: true
18
+ },
19
+ jpeg: {
20
+ pages: false,
21
+ raster: true
22
+ },
23
+ gif: {
24
+ pages: false,
25
+ raster: true
26
+ },
27
+ webp: {
28
+ pages: false,
29
+ raster: true
30
+ },
31
+ svg: {
32
+ pages: false,
33
+ raster: false
34
+ },
35
+ pdf: {
36
+ pages: true,
37
+ raster: false
38
+ },
39
+ ai: {
40
+ pages: true,
41
+ raster: false
42
+ }
43
+ };
44
+ const MediaText = z.object({
45
+ text: z.string().min(1),
46
+ lang: z.string().optional(),
47
+ dir: Direction.optional()
48
+ });
49
+ function mediaTextDirection(text) {
50
+ return resolveDirection(text.dir, text.lang, text.text);
51
+ }
52
+ const PageSelector = z.union([z.string().trim().min(1), z.number().int().positive()]);
53
+ const PageBox = Box.superRefine((box, ctx) => {
54
+ if (box.width <= 0) ctx.addIssue({
55
+ code: "custom",
56
+ path: ["width"],
57
+ message: "box width must be positive; pass a positive width to clear this refusal"
58
+ });
59
+ if (box.height <= 0) ctx.addIssue({
60
+ code: "custom",
61
+ path: ["height"],
62
+ message: "box height must be positive; pass a positive height to clear this refusal"
63
+ });
64
+ });
65
+ const PAGE_BOXES = [
66
+ "media",
67
+ "crop",
68
+ "trim",
69
+ "bleed",
70
+ "art"
71
+ ];
72
+ const PageBoxName = z.enum(PAGE_BOXES);
73
+ const MediaPageBoxesShape = {
74
+ media: PageBox,
75
+ crop: PageBox.optional(),
76
+ trim: PageBox.optional(),
77
+ bleed: PageBox.optional(),
78
+ art: PageBox.optional()
79
+ };
80
+ const MediaPage = z.object({
81
+ name: z.string().min(1).optional(),
82
+ boxes: z.object(MediaPageBoxesShape)
83
+ });
84
+ const Media = z.object({
85
+ format: MediaFormat,
86
+ size: z.object({
87
+ width: z.number().positive("size.width could not be accepted; pass a positive width to clear this refusal"),
88
+ height: z.number().positive("size.height could not be accepted; pass a positive height to clear this refusal")
89
+ }),
90
+ pages: z.array(MediaPage).optional(),
91
+ resolution: z.number().positive("resolution could not be accepted; pass a positive resolution to clear this refusal").optional(),
92
+ alt: MediaText.optional(),
93
+ caption: MediaText.optional(),
94
+ credit: MediaText.optional(),
95
+ derivedFrom: z.object({
96
+ address: z.string().min(1),
97
+ page: PageSelector,
98
+ name: z.string().min(1).optional()
99
+ }).optional()
100
+ }).superRefine((media, ctx) => {
101
+ const capabilities = MEDIA_FORMATS[media.format];
102
+ if (media.pages !== void 0 && !capabilities.pages) ctx.addIssue({
103
+ code: "custom",
104
+ path: ["pages"],
105
+ message: `pages could not be accepted for ${media.format}; remove pages or use a format with pages to clear this refusal`
106
+ });
107
+ if (media.resolution !== void 0 && !capabilities.raster) ctx.addIssue({
108
+ code: "custom",
109
+ path: ["resolution"],
110
+ message: `resolution could not be accepted for ${media.format}; remove resolution or use a raster format to clear this refusal`
111
+ });
112
+ if (media.derivedFrom !== void 0 && capabilities.pages) ctx.addIssue({
113
+ code: "custom",
114
+ path: ["derivedFrom"],
115
+ message: `derivedFrom could not be accepted for ${media.format}; remove derivedFrom or use a format without pages to clear this refusal`
116
+ });
117
+ });
118
+ //#endregion
119
+ export { MEDIA_FORMATS, Media, MediaFormat, MediaPage, MediaText, PAGE_BOXES, PageBoxName, PageSelector, mediaTextDirection };
@@ -0,0 +1,70 @@
1
+ import { NoteMarker } from "./numbering.js";
2
+ import { z } from "zod";
3
+ //#region src/note-series.d.ts
4
+ export declare const NotePlacement: z.ZodEnum<{
5
+ page: "page";
6
+ book: "book";
7
+ chapter: "chapter";
8
+ part: "part";
9
+ }>;
10
+ export type NotePlacement = z.infer<typeof NotePlacement>;
11
+ export declare const NoteNumbering: z.ZodEnum<{
12
+ book: "book";
13
+ chapter: "chapter";
14
+ part: "part";
15
+ }>;
16
+ export type NoteNumbering = z.infer<typeof NoteNumbering>;
17
+ export declare const NoteSeries: z.ZodObject<{
18
+ name: z.ZodString;
19
+ placement: z.ZodOptional<z.ZodEnum<{
20
+ page: "page";
21
+ book: "book";
22
+ chapter: "chapter";
23
+ part: "part";
24
+ }>>;
25
+ numbering: z.ZodOptional<z.ZodEnum<{
26
+ book: "book";
27
+ chapter: "chapter";
28
+ part: "part";
29
+ }>>;
30
+ marker: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
31
+ arabic: "arabic";
32
+ "roman-lower": "roman-lower";
33
+ "roman-upper": "roman-upper";
34
+ hebrew: "hebrew";
35
+ }>, z.ZodLiteral<"symbols">]>>;
36
+ title: z.ZodOptional<z.ZodString>;
37
+ }, z.core.$strip>;
38
+ export type NoteSeriesInput = z.input<typeof NoteSeries>;
39
+ export interface ResolvedNoteSeries {
40
+ name: string;
41
+ placement: NotePlacement;
42
+ numbering: NoteNumbering;
43
+ marker: NoteMarker;
44
+ title: string;
45
+ idStem: string;
46
+ idScope: 'chapter' | 'numbering';
47
+ blockClass: string;
48
+ bodyClass: string;
49
+ titleClass: string;
50
+ sectionIdPrefix: string;
51
+ markerLabel: string;
52
+ markerConflictSuffixes: Readonly<Record<string, string>>;
53
+ markBlockSeries: boolean;
54
+ }
55
+ interface NoteSeriesSettings {
56
+ lang?: string;
57
+ footnotes: {
58
+ marker?: NoteMarker;
59
+ restart: 'chapter' | 'book';
60
+ };
61
+ endnotes: {
62
+ marker?: NoteMarker;
63
+ placement: 'book' | 'chapter';
64
+ title?: string;
65
+ };
66
+ notes: NoteSeriesInput[];
67
+ }
68
+ export declare function resolveNoteSeries(settings: NoteSeriesSettings): ResolvedNoteSeries[];
69
+ export declare function noteMarkerIssues(series: ResolvedNoteSeries[], used: ReadonlySet<string>): string[];
70
+ //#endregion
@@ -0,0 +1,153 @@
1
+ import { NoteMarker, isHebrew } from "./numbering.js";
2
+ import { REGION_NAME } from "./book-section.js";
3
+ import { z } from "zod";
4
+ //#region src/note-series.ts
5
+ const NotePlacement = z.enum([
6
+ "page",
7
+ "chapter",
8
+ "part",
9
+ "book"
10
+ ]);
11
+ const NoteNumbering = z.enum([
12
+ "chapter",
13
+ "part",
14
+ "book"
15
+ ]);
16
+ const NoteSeries = z.object({
17
+ name: z.string().regex(REGION_NAME, "a note series name must be an HTML name token"),
18
+ placement: NotePlacement.optional(),
19
+ numbering: NoteNumbering.optional(),
20
+ marker: NoteMarker.optional(),
21
+ title: z.string().optional()
22
+ });
23
+ function markerOrder(lang) {
24
+ return isHebrew(lang) ? [
25
+ "hebrew",
26
+ "arabic",
27
+ "symbols",
28
+ "roman-lower"
29
+ ] : [
30
+ "symbols",
31
+ "arabic",
32
+ "roman-lower",
33
+ "hebrew"
34
+ ];
35
+ }
36
+ function unusedMarker(lang, used) {
37
+ return markerOrder(lang).find((marker) => !used.has(marker)) ?? "symbols";
38
+ }
39
+ function resolveCustomSeries(series) {
40
+ if (series.placement === void 0 || series.numbering === void 0) throw new Error(`note series ${series.name} needs placement and numbering`);
41
+ return {
42
+ ...series,
43
+ placement: series.placement,
44
+ numbering: series.numbering,
45
+ title: series.title ?? series.name,
46
+ idStem: `note-${series.name}`,
47
+ idScope: "numbering",
48
+ blockClass: `segnavia-notes-${series.name}`,
49
+ bodyClass: `segnavia-note-${series.name}`,
50
+ titleClass: "segnavia-notes-title",
51
+ sectionIdPrefix: `segnavia-notes-${series.name}`,
52
+ markerLabel: `note series ${series.name}`,
53
+ markerConflictSuffixes: {},
54
+ markBlockSeries: true
55
+ };
56
+ }
57
+ function resolveNoteSeries(settings) {
58
+ const hebrew = isHebrew(settings.lang);
59
+ const declared = new Map(settings.notes.map((series) => [series.name, series]));
60
+ const footnotePresentation = {
61
+ idStem: "fn",
62
+ idScope: "chapter",
63
+ blockClass: "segnavia-footnotes",
64
+ bodyClass: "segnavia-footnote",
65
+ titleClass: "segnavia-notes-title",
66
+ sectionIdPrefix: "segnavia-notes-footnote",
67
+ markerLabel: "footnote",
68
+ markerConflictSuffixes: { endnote: "the two must differ when both kinds are used" },
69
+ markBlockSeries: false
70
+ };
71
+ const endnotePresentation = {
72
+ idStem: "en",
73
+ idScope: "numbering",
74
+ blockClass: "segnavia-notes-endnote",
75
+ bodyClass: "segnavia-endnote",
76
+ titleClass: "segnavia-endnotes-title",
77
+ sectionIdPrefix: "segnavia-endnotes",
78
+ markerLabel: "endnote",
79
+ markerConflictSuffixes: {},
80
+ markBlockSeries: true
81
+ };
82
+ const inputs = [
83
+ {
84
+ name: "footnote",
85
+ placement: "page",
86
+ numbering: settings.footnotes.restart,
87
+ marker: settings.footnotes.marker ?? (hebrew ? "hebrew" : "symbols"),
88
+ title: hebrew ? "מקורות" : "Footnotes",
89
+ ...footnotePresentation,
90
+ ...declared.get("footnote")
91
+ },
92
+ {
93
+ name: "endnote",
94
+ placement: settings.endnotes.placement,
95
+ numbering: "book",
96
+ marker: settings.endnotes.marker ?? "arabic",
97
+ title: settings.endnotes.title ?? (hebrew ? "הערות" : "Notes"),
98
+ ...endnotePresentation,
99
+ ...declared.get("endnote")
100
+ },
101
+ ...settings.notes.filter(({ name }) => name !== "footnote" && name !== "endnote").map(resolveCustomSeries)
102
+ ];
103
+ const used = /* @__PURE__ */ new Set();
104
+ return inputs.map((series) => {
105
+ const marker = series.marker ?? unusedMarker(settings.lang, used);
106
+ used.add(marker);
107
+ return {
108
+ name: series.name,
109
+ placement: series.placement,
110
+ numbering: series.numbering,
111
+ marker,
112
+ title: series.title,
113
+ idStem: series.idStem,
114
+ idScope: series.idScope,
115
+ blockClass: series.blockClass,
116
+ bodyClass: series.bodyClass,
117
+ titleClass: series.titleClass,
118
+ sectionIdPrefix: series.sectionIdPrefix,
119
+ markerLabel: series.markerLabel,
120
+ markerConflictSuffixes: series.markerConflictSuffixes,
121
+ markBlockSeries: series.markBlockSeries
122
+ };
123
+ });
124
+ }
125
+ function noteSeriesIssues(series, mode) {
126
+ const issues = [];
127
+ series.forEach((item, index) => {
128
+ if (mode === "continuous" && (item.placement === "chapter" || item.placement === "part")) issues.push({
129
+ path: [
130
+ "notes",
131
+ index,
132
+ "placement"
133
+ ],
134
+ message: `note series ${item.name} uses ${item.placement} placement only available in paginated mode; use page or book placement, or paginated mode`
135
+ });
136
+ });
137
+ return issues;
138
+ }
139
+ function noteMarkerIssues(series, used) {
140
+ const active = series.filter(({ name }) => used.has(name));
141
+ const issues = [];
142
+ for (let left = 0; left < active.length; left += 1) for (let right = left + 1; right < active.length; right += 1) {
143
+ const a = active[left];
144
+ const b = active[right];
145
+ if (!a || !b) continue;
146
+ if (a.marker !== b.marker) continue;
147
+ const suffix = a.markerConflictSuffixes[b.name] ?? b.markerConflictSuffixes[a.name] ?? "used series must have different markers";
148
+ issues.push(`${a.markerLabel} and ${b.markerLabel} markers are both ${a.marker}; ${suffix}`);
149
+ }
150
+ return issues;
151
+ }
152
+ //#endregion
153
+ export { NoteNumbering, NotePlacement, NoteSeries, noteMarkerIssues, noteSeriesIssues, resolveNoteSeries };