paperlab 0.5.2 → 0.7.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.
package/dist/index.d.cts CHANGED
@@ -1,8 +1,10 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import * as THREE from 'three';
4
- import { P as PaperConfig, a as PaperConfigInput, S as SheetConfig, b as StockName, C as ContentConfigInput, B as BehaviorConfigInput, D as DeformerInstanceConfigInput, c as SurfaceConfigInput, d as SceneConfigInput, e as PhysicsConfigInput, F as FieldPaperSlot, f as ContentConfig, g as PaperStatesInput, L as LightingName, h as FilmName, i as LightOverrides, j as BackdropConfig } from './slots-CIo7FnlY.cjs';
5
- export { k as BackContentConfig, l as BehaviorConfig, m as ClothConfig, n as CoreStateName, o as DeformerInstanceConfig, p as LightOverridesInput, q as PaperEdge, r as PaperStates, s as PhysicsConfig, t as SceneConfig, u as StateDef, v as StateName, w as StateTransitionConfig, x as SurfaceConfig, W as WashConfig, y as backdropSchema, z as behaviorConfigSchema, A as clothConfigSchema, E as contentNames, G as contentSchemaFor, H as coreStateNames, I as lightSchema, J as lightingNames, K as paperConfigSchema, M as paperEdges, N as paperStatesSchema, O as physicsNames, Q as sceneSchema, R as stateDefSchema, T as stockNames, U as washSchema } from './slots-CIo7FnlY.cjs';
4
+ import { P as PaperConfig, a as PaperConfigInput, S as SheetConfig, b as StockName, C as ContentConfigInput, B as BehaviorConfigInput, D as DeformerInstanceConfigInput, c as SurfaceConfigInput, M as MemoryConfigInput, d as SceneConfigInput, e as PhysicsConfigInput, f as CreaseConfig, F as FieldPaperSlot, g as ContentConfig, h as PaperStatesInput, L as LightingName, i as FilmName, j as LightOverrides, k as BackdropConfig } from './slots-C5PqY0Q5.cjs';
5
+ export { l as BackContentConfig, m as BehaviorConfig, n as ClothConfig, o as CoreStateName, p as CreaseConfigInput, q as DeformerInstanceConfig, r as LightOverridesInput, s as MemoryConfig, t as PaperEdge, u as PaperStates, v as PhysicsConfig, w as SceneConfig, x as StateDef, y as StateName, z as StateTransitionConfig, A as StripConfig, E as SurfaceConfig, W as WashConfig, G as backdropSchema, H as behaviorConfigSchema, I as clothConfigSchema, J as contentNames, K as contentSchemaFor, N as coreStateNames, O as creaseSchema, Q as lightSchema, R as lightingNames, T as memorySchema, U as paperConfigSchema, V as paperEdges, X as paperStatesSchema, Y as physicsNames, Z as sceneSchema, _ as stateDefSchema, $ as stockNames, a0 as stripConfigSchema, a1 as washSchema } from './slots-C5PqY0Q5.cjs';
6
+ import { D as DamageSource } from './damageContract-DPF1YFLZ.cjs';
7
+ export { a as DAMAGE_CHANNELS, b as DAMAGE_LOOK_DEFAULTS, c as DamageLook } from './damageContract-DPF1YFLZ.cjs';
6
8
  import { z } from 'zod';
7
9
 
8
10
  /**
@@ -133,6 +135,13 @@ interface PaperMeshProps {
133
135
  deformers?: DeformerInstanceConfigInput[];
134
136
  /** Fragment-side effects: grain, aging, deckle, creases, perforation. */
135
137
  surface?: SurfaceConfigInput;
138
+ /**
139
+ * What the sheet remembers being folded — how much of a fold this paper
140
+ * keeps, and the creases it already carries. A sheet can be handed its
141
+ * creases (a letter that arrives having been folded once) as readily as it
142
+ * can be folded into them.
143
+ */
144
+ memory?: MemoryConfigInput;
136
145
  /** Scene-level presentation that travels with the paper (lighting). */
137
146
  scene?: SceneConfigInput;
138
147
  physics?: PhysicsConfigInput | 'cloth';
@@ -149,6 +158,17 @@ interface PaperMeshProps {
149
158
  onProgress?(value: number): void;
150
159
  /** Fires when a handle drag ends, with the params the drag changed. */
151
160
  onBehaviorChange?(patch: Record<string, unknown>): void;
161
+ /**
162
+ * Fires when folding the paper leaves a crease it did not have.
163
+ *
164
+ * The sheet applies its own creases immediately — this is how they get
165
+ * PERSISTED. Recording happens in the frame loop, where a fold's peak
166
+ * actually is, and routing that through React sixty times a second would
167
+ * cost more than the rest of the feature; so the mesh holds the live truth
168
+ * and reports it, and the host writes it into config whenever it likes.
169
+ * The same split `onBehaviorChange` uses for handle drags.
170
+ */
171
+ onCrease?(creases: CreaseConfig[]): void;
152
172
  /**
153
173
  * Interaction states: when the config carries `states`, pointer triggers
154
174
  * are live by default. Set false to sculpt a stateful paper without the
@@ -159,6 +179,18 @@ interface PaperMeshProps {
159
179
  onStateChange?(state: string): void;
160
180
  /** Fires for `onEnter` actions ('emit:<event>'). */
161
181
  onStateAction?(event: string, state: string): void;
182
+ /**
183
+ * What has happened to this sheet — char, wet, heat and missing paper — as
184
+ * a grid over its UV.
185
+ *
186
+ * The sheet draws whatever damage it is handed and does not know what
187
+ * caused it, the same way it draws `content` without knowing who painted
188
+ * it. `DamageField` from `paperlab/fx` is one source; a baked texture or a
189
+ * recorded burn played back would be others. A prop and not config,
190
+ * because it is live state that changes every frame and does not belong in
191
+ * a preset or a share link. See `DamageSource`.
192
+ */
193
+ damage?: DamageSource | null;
162
194
  }
163
195
  interface PaperHandle {
164
196
  play(): void;
@@ -185,6 +217,21 @@ interface PaperHandle {
185
217
  * allocate a vector sixty times a second.
186
218
  */
187
219
  handlePoint(id?: string, target?: THREE.Vector3): THREE.Vector3 | null;
220
+ /**
221
+ * Where a point of the sheet is right now, in world space: `(u, v)` over
222
+ * the sheet, `v = 0` its bottom edge — the same UV the damage grid is laid
223
+ * out on, so a cell of damage can be asked where it is. Null before the
224
+ * sheet has mounted.
225
+ *
226
+ * On the DRAWN surface, after this frame's simulation and deformer stack,
227
+ * which is the reason it is a method: an ember that leaves the burn front
228
+ * has to leave from where the paper is, and a draped or crumpled sheet is
229
+ * nowhere a UV alone could say. Interpolated across the triangle the GPU
230
+ * draws, so the point is on the paper and not a hair behind it.
231
+ *
232
+ * Written into `target` when one is passed, like {@link handlePoint}.
233
+ */
234
+ surfacePoint(u: number, v: number, target?: THREE.Vector3): THREE.Vector3 | null;
188
235
  /** Interaction-state machine access (null when the config has no states). */
189
236
  readonly state: string;
190
237
  sendState(event: StateEvent): string | null;
@@ -200,9 +247,10 @@ interface PaperHandle {
200
247
  returnProgrammatic(): boolean;
201
248
  }
202
249
  /**
203
- * The atom: one sheet of paper, hero-mode CPU path. The deformer stack (or
204
- * the cloth sim never both) writes geometry positions each frame. GSAP
205
- * owns animated values; useFrame owns geometry writes.
250
+ * The atom: one sheet of paper, hero-mode CPU path. The cloth sim solves the
251
+ * particles and the deformer stack runs over them both, not either; only a
252
+ * strip owns its vertices outright. GSAP owns animated values; useFrame owns
253
+ * geometry writes.
206
254
  */
207
255
  declare const PaperMesh: react.ForwardRefExoticComponent<PaperMeshProps & react.RefAttributes<PaperHandle>>;
208
256
 
@@ -280,7 +328,7 @@ interface Deformer<O = Record<string, unknown>> {
280
328
  id: string;
281
329
  label: string;
282
330
  defaults: O;
283
- optionsSchema: z.ZodType<O, z.ZodTypeDef, unknown>;
331
+ optionsSchema: z.ZodType<O, unknown>;
284
332
  /** Mutate `out` (sheet-local space; flat sheet is the XY plane facing +Z). */
285
333
  displace(out: THREE.Vector3, uv: THREE.Vector2, o: O, ctx: DeformerContext): void;
286
334
  /** GPU path — arrives with field mode. */
@@ -355,31 +403,12 @@ interface DeformerInstance<O = Record<string, unknown>> {
355
403
  declare const sheetLayoutSchema: z.ZodObject<{
356
404
  rows: z.ZodDefault<z.ZodNumber>;
357
405
  columns: z.ZodDefault<z.ZodNumber>;
358
- /** World-units gap between slots. Stamps are printed in register — no jitter. */
359
406
  gutter: z.ZodDefault<z.ZodNumber>;
360
- /** Slot footprint in world units (the paper preset should match). */
361
407
  cellWidth: z.ZodDefault<z.ZodNumber>;
362
408
  cellHeight: z.ZodDefault<z.ZodNumber>;
363
- /** Render the shared backing sheet behind the grid. */
364
409
  backing: z.ZodDefault<z.ZodBoolean>;
365
410
  backingMargin: z.ZodDefault<z.ZodNumber>;
366
- }, "strip", z.ZodTypeAny, {
367
- columns: number;
368
- rows: number;
369
- gutter: number;
370
- cellWidth: number;
371
- cellHeight: number;
372
- backing: boolean;
373
- backingMargin: number;
374
- }, {
375
- columns?: number | undefined;
376
- rows?: number | undefined;
377
- gutter?: number | undefined;
378
- cellWidth?: number | undefined;
379
- cellHeight?: number | undefined;
380
- backing?: boolean | undefined;
381
- backingMargin?: number | undefined;
382
- }>;
411
+ }, z.core.$strip>;
383
412
  type SheetLayoutOptions = z.infer<typeof sheetLayoutSchema>;
384
413
 
385
414
  /** Imperative field controls for the hidden a11y keyboard flow. */
@@ -605,7 +634,7 @@ interface Behavior<O = AnyOptions> {
605
634
  id: string;
606
635
  label: string;
607
636
  defaults: O;
608
- optionsSchema: z.ZodType<O, z.ZodTypeDef, unknown>;
637
+ optionsSchema: z.ZodType<O, unknown>;
609
638
  /** Expand human params to the underlying deformer stack. */
610
639
  stack(o: O, sheet: SheetDims): DeformerInstance[];
611
640
  /** Transient, time-varying option overrides (idle motion). Never persisted. */
@@ -613,10 +642,14 @@ interface Behavior<O = AnyOptions> {
613
642
  /**
614
643
  * Whole-sheet motion written into `pose` each frame (allocation-free),
615
644
  * composed after any idle preset's transform. Must be a pure function of
616
- * (options, t) — the field applies it per instance with a time offset, so
617
- * it has to be deterministic (flight's travel-across-the-scene).
645
+ * (options, t, sheet) — the field applies it per instance with a time
646
+ * offset, so it has to be deterministic (flight's travel-across-the-scene).
647
+ *
648
+ * `sheet` is passed because whole-sheet motion is often only meaningful
649
+ * relative to the sheet's own extent: `unroll` holds the roll still in
650
+ * space, and where "still" is depends on how long the paper is.
618
651
  */
619
- transform?(o: O, t: number, pose: AeroPose): void;
652
+ transform?(o: O, t: number, pose: AeroPose, sheet: SheetDims): void;
620
653
  handles?: HandleSpec<O>[];
621
654
  /**
622
655
  * The two or three options that ARE this behavior — the ones someone
@@ -670,7 +703,7 @@ interface Layout<O = Record<string, unknown>> {
670
703
  id: string;
671
704
  label: string;
672
705
  defaults: O;
673
- optionsSchema: z.ZodType<O, z.ZodTypeDef, unknown>;
706
+ optionsSchema: z.ZodType<O, unknown>;
674
707
  /**
675
708
  * `sheet` is the field's paper size. Layouts that arrange by CONTACT —
676
709
  * edges meeting, sheets resting on each other — cannot work without it,
@@ -724,6 +757,16 @@ interface Stock {
724
757
  showThrough: number;
725
758
  /** Glossy near-white glue underside (stickers) — forces showThrough 0. */
726
759
  adhesive: boolean;
760
+ /**
761
+ * How hard this paper holds a crease, 0..1 — the material half of
762
+ * {@link MemoryConfig}. Fibrous, thick stocks take a set and keep it;
763
+ * coated and translucent ones spring most of the way back.
764
+ *
765
+ * Not a fraction of anything on its own: `memory.ts` scales it by
766
+ * `MAX_SET`, so 1 here means "as much as paper ever remembers", not "stays
767
+ * exactly as folded".
768
+ */
769
+ takesSet: number;
727
770
  }
728
771
  declare const stocks: Record<StockName, Stock>;
729
772
  declare function getStock(name: StockName): Stock;
@@ -749,6 +792,139 @@ interface IdlePreset {
749
792
  stack?(): DeformerInstance[];
750
793
  }
751
794
 
795
+ /**
796
+ * The longest strip this chain can still draw properly, for a given
797
+ * perforation spacing.
798
+ *
799
+ * {@link stripNodeCount} is CAPPED, and the cap does not fail loudly: past it
800
+ * the node count stops growing, so `segment` (which is `length / (count - 1)`)
801
+ * grows instead, and every constant that was tuned per node quietly changes
802
+ * meaning. The first thing to break is the roll — a longer chord on the same
803
+ * radius dips further inside the wrap beneath it, so the spiral heads for the
804
+ * {@link safeSpiralRadius} threshold and comes apart into a starburst.
805
+ *
806
+ * Exported because it is a UI limit as much as a physics one: a length slider
807
+ * that runs past this hands the user a roll that visibly falls apart, and the
808
+ * editor has no other way to know where the ceiling is. The constants that set
809
+ * it live here, so the derivation does too.
810
+ */
811
+ declare function maxStripLength(perforation: number): number;
812
+
813
+ /**
814
+ * Paper memory: the sheet keeps what has been done to it.
815
+ *
816
+ * Every deformer is a pure function of its options — a sheet folded to 180°
817
+ * and back to 0° flows through the stack and comes out pristine. That is
818
+ * correct for cloth and wrong for paper, which is PLASTIC: the fibres break
819
+ * along the fold and the crease outlives it.
820
+ *
821
+ * The fix lives here rather than inside the deformers, and deliberately.
822
+ * Deformer purity is load-bearing — it is what gives the GLSL twins
823
+ * something to be identical to, what lets the field scale one instance's
824
+ * bend by a per-sheet bias, and what `test:parity` checks. So memory sits
825
+ * ABOVE the stack: it watches the stack the behavior built, and it rewrites
826
+ * that stack before it runs. Nothing below this file knows it exists.
827
+ *
828
+ * The whole layer is hero-path only. The field composes one GLSL program for
829
+ * every sheet in an instanced draw call, and a crease is per-sheet state —
830
+ * so a field of a hundred papers cannot carry a hundred crease sets without
831
+ * per-instance attributes that don't exist yet. `applyMemory` is called from
832
+ * `PaperMesh` and from nowhere in `field/`.
833
+ */
834
+ /**
835
+ * What a paper at `takesSet: 1` keeps of a fold, as a fraction of the angle
836
+ * it was folded to.
837
+ *
838
+ * Kraft folded flat (180°) comes to rest around 30° open, which is `180 ×
839
+ * 0.85 × 0.2`. Keeping this multiplier here rather than folding it into the
840
+ * stock values is what lets `memory.set` and `Stock.takesSet` both be honest
841
+ * 0..1 knobs that use their whole range, instead of designer-facing sliders
842
+ * that do everything interesting in their bottom fifth.
843
+ */
844
+ declare const MAX_SET = 0.2;
845
+ /** What the crease shader carries, and so what memory may record. */
846
+ declare const MAX_CREASES = 4;
847
+ /**
848
+ * Fold a sheet's remembered creases into the stack that is about to run.
849
+ *
850
+ * A crease is a FLOOR on the fold at its line, never an addition. Where the
851
+ * behavior is already folding that line further, the crease is invisible and
852
+ * contributes nothing; as the behavior lets go, the fold angle falls to the
853
+ * crease's depth and stops there. That is what makes the crease appear on
854
+ * the way back out of a fold without anything having to detect the release —
855
+ * and it is why the residual is written INTO the live instance rather than
856
+ * added beside it. Two folds on one line would not be a deeper crease, they
857
+ * would be two creases a hair apart, and `fold` does not commute.
858
+ *
859
+ * Creases with no live fold on their line are prepended: a sheet that is
860
+ * already creased is creased BEFORE the behavior gets hold of it, so the
861
+ * behavior bends a creased sheet rather than the crease bending a bent one.
862
+ */
863
+ declare function applyMemory(stack: DeformerInstance[], creases: CreaseConfig[]): DeformerInstance[];
864
+ /**
865
+ * Watches a running deformer stack and records the creases it leaves.
866
+ *
867
+ * One per sheet, driven from the frame loop. It is deliberately not a
868
+ * reducer over config: recording has to happen at frame rate to catch the
869
+ * peak of a fold, and routing sixty writes a second through React would cost
870
+ * more than the whole rest of the feature. Instead this holds the live truth
871
+ * and says when it has changed, and the host persists that at its own pace —
872
+ * the same split `onBehaviorChange` already uses for handle drags.
873
+ *
874
+ * Slots are keyed by POSITION in the stack, which is the only stable identity
875
+ * a fold has: a behavior's stack is a pure function of its options, so
876
+ * `stack[1]` is the same fold from frame to frame, while its angle and offset
877
+ * are exactly the things that may legitimately move.
878
+ */
879
+ declare class CreaseTracker {
880
+ private slots;
881
+ private recorded;
882
+ private authored;
883
+ /** What `observe` last handed out, so an echo can be told from an edit. */
884
+ private lastReported;
885
+ constructor(authored?: CreaseConfig[]);
886
+ /**
887
+ * Forget how the paper got here without forgetting the creases.
888
+ *
889
+ * Called when the stack is replaced wholesale (a new behavior, a new
890
+ * sheet): the slots describe folds that no longer exist, but a crease is a
891
+ * property of the paper and survives being put down and picked up.
892
+ */
893
+ reset(authored?: CreaseConfig[]): void;
894
+ /**
895
+ * Take on a crease set that came from outside, and work out which kind of
896
+ * outside it was — because the two kinds want opposite things.
897
+ *
898
+ * It is USUALLY this tracker's own recording coming back, a frame or two
899
+ * after `onCrease` handed it to the host. Then the slots must survive: the
900
+ * fold that made the crease is very likely still closing, and resetting
901
+ * its peak on the host's echo would stall the crease halfway into the
902
+ * fold that was making it.
903
+ *
904
+ * But it can also be somebody EDITING the paper — a depth dragged down in
905
+ * a panel, a shared link opened, a state's overrides settling. Then the
906
+ * slots are the wrong story to keep. `merge` takes the deeper of two
907
+ * creases on a line, so a recording of 20° would quietly outvote a human
908
+ * asking for 5° and the slider would appear not to work; and it would go
909
+ * on outvoting it, because the fold that recorded the 20 is still sitting
910
+ * in a slot. An edit means the paper is what it is now, and the next
911
+ * crease has to be earned by folding it again.
912
+ *
913
+ * The two are told apart by what we last reported. Anything else is an
914
+ * edit, which is the safe way round: mistaking an echo for an edit costs
915
+ * a crease that gets re-recorded on the next fold, while mistaking an edit
916
+ * for an echo costs a control that does not work.
917
+ */
918
+ adopt(creases: CreaseConfig[]): void;
919
+ /** Everything the sheet currently carries, authored and recorded merged. */
920
+ get creases(): CreaseConfig[];
921
+ /**
922
+ * Take one frame's reading. Returns true when the crease set changed by
923
+ * enough to be worth telling anyone about.
924
+ */
925
+ observe(stack: DeformerInstance[], set: number): boolean;
926
+ }
927
+
752
928
  /**
753
929
  * Lighting presets: each is a key light + ambient level + contact shadow +
754
930
  * optional gobo (a texture the key light projects — window blinds, foliage).
@@ -1101,4 +1277,4 @@ declare function segmentsForSine(span: number, amplitude: number, wavelength: nu
1101
1277
  */
1102
1278
  declare function wrapLines(ctx: CanvasRenderingContext2D, text: string, maxWidth: number, font: string): string[];
1103
1279
 
1104
- export { AUTO_CEILING, BackdropConfig, type Behavior, BehaviorConfigInput, ContentConfig, ContentConfigInput, type Deformer, type DeformerContext, type DeformerInstance, DeformerInstanceConfigInput, DropZone, type DropZoneConfig, type DropZoneProps, FLAT_SEGMENTS, type FieldExportInput, type FieldExportPaper, type FieldExportZone, FieldPaperSlot, FilmName, type HandleSpec, type IdleName, type IdlePreset, type Layout, type LightAngles, LightOverrides, LightRig, LightingName, type LightingPreset, PARITY_EPSILON, Paper, PaperBackdrop, PaperConfig, PaperConfigInput, PaperField, PaperFieldMesh, type PaperFieldMeshProps, type PaperFieldProps, type PaperHandle, PaperLighting, type PaperLightingProps, PaperMesh, type PaperMeshProps, type PaperPose, type PaperProps, PaperStatesInput, type ParityCase, type ParityResult, PhysicsConfigInput, type PlacedPaper, SAG_TOL, SceneConfigInput, SheetConfig, type SheetDims, type SheetLayoutOptions, type StateEvent, type Stock, StockName, SurfaceConfigInput, type UsePaperStatesResult, buildAgentPayload, buildFieldAgentPayload, buildFieldComponentSource, buildJsxSnippet, describeConfig, describeFieldConfig, diffConfig, diffFieldProps, getBehavior, getDeformer, getLayout, getPreset, getStock, idleNames, isBuiltinPreset, lightAngles, listBehaviors, listDeformers, listLayouts, listPresets, mergeConfig, mergeWithDeletes, parityCases, parsePreset, quantizeSegments, recordStateOverride, registerBehavior, registerDeformer, registerLayout, registerPreset, resolveLighting, resolveStateConfig, runParityHarness, segmentsForArc, segmentsForSine, serializePreset, sheetLayoutSchema, spanAlong, stocks, supportsWebGL, uniquePresetName, unregisterPreset, usePaperStates, usePrefersReducedMotion, wrapLines };
1280
+ export { AUTO_CEILING, BackdropConfig, type Behavior, BehaviorConfigInput, ContentConfig, ContentConfigInput, CreaseConfig, CreaseTracker, DamageSource, type Deformer, type DeformerContext, type DeformerInstance, DeformerInstanceConfigInput, DropZone, type DropZoneConfig, type DropZoneProps, FLAT_SEGMENTS, type FieldExportInput, type FieldExportPaper, type FieldExportZone, FieldPaperSlot, FilmName, type HandleSpec, type IdleName, type IdlePreset, type Layout, type LightAngles, LightOverrides, LightRig, LightingName, type LightingPreset, MAX_CREASES, MAX_SET, MemoryConfigInput, PARITY_EPSILON, Paper, PaperBackdrop, PaperConfig, PaperConfigInput, PaperField, PaperFieldMesh, type PaperFieldMeshProps, type PaperFieldProps, type PaperHandle, PaperLighting, type PaperLightingProps, PaperMesh, type PaperMeshProps, type PaperPose, type PaperProps, PaperStatesInput, type ParityCase, type ParityResult, PhysicsConfigInput, type PlacedPaper, SAG_TOL, SceneConfigInput, SheetConfig, type SheetDims, type SheetLayoutOptions, type StateEvent, type Stock, StockName, SurfaceConfigInput, type UsePaperStatesResult, applyMemory, buildAgentPayload, buildFieldAgentPayload, buildFieldComponentSource, buildJsxSnippet, describeConfig, describeFieldConfig, diffConfig, diffFieldProps, getBehavior, getDeformer, getLayout, getPreset, getStock, idleNames, isBuiltinPreset, lightAngles, listBehaviors, listDeformers, listLayouts, listPresets, maxStripLength, mergeConfig, mergeWithDeletes, parityCases, parsePreset, quantizeSegments, recordStateOverride, registerBehavior, registerDeformer, registerLayout, registerPreset, resolveLighting, resolveStateConfig, runParityHarness, segmentsForArc, segmentsForSine, serializePreset, sheetLayoutSchema, spanAlong, stocks, supportsWebGL, uniquePresetName, unregisterPreset, usePaperStates, usePrefersReducedMotion, wrapLines };