@kitschpatrol/tldraw-cli 3.1.0 → 3.2.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/bin/cli.js CHANGED
@@ -609,15 +609,722 @@ var require_boolbase = __commonJS({
609
609
  }
610
610
  });
611
611
 
612
+ // node_modules/.pnpm/irregular-plurals@3.5.0/node_modules/irregular-plurals/irregular-plurals.json
613
+ var require_irregular_plurals = __commonJS({
614
+ "node_modules/.pnpm/irregular-plurals@3.5.0/node_modules/irregular-plurals/irregular-plurals.json"(exports, module) {
615
+ module.exports = {
616
+ addendum: "addenda",
617
+ aircraft: "aircraft",
618
+ alga: "algae",
619
+ alumna: "alumnae",
620
+ alumnus: "alumni",
621
+ alveolus: "alveoli",
622
+ amoeba: "amoebae",
623
+ analysis: "analyses",
624
+ antenna: "antennae",
625
+ antithesis: "antitheses",
626
+ apex: "apices",
627
+ appendix: "appendices",
628
+ automaton: "automata",
629
+ axis: "axes",
630
+ bacillus: "bacilli",
631
+ bacterium: "bacteria",
632
+ baculum: "bacula",
633
+ barracks: "barracks",
634
+ basis: "bases",
635
+ beau: "beaux",
636
+ bison: "bison",
637
+ buffalo: "buffalo",
638
+ bureau: "bureaus",
639
+ cactus: "cacti",
640
+ calf: "calves",
641
+ carcinoma: "carcinomata",
642
+ carp: "carp",
643
+ census: "censuses",
644
+ chassis: "chassis",
645
+ cherub: "cherubim",
646
+ child: "children",
647
+ ch\u00E2teau: "ch\xE2teaus",
648
+ cloaca: "cloacae",
649
+ cod: "cod",
650
+ codex: "codices",
651
+ concerto: "concerti",
652
+ consortium: "consortia",
653
+ corpus: "corpora",
654
+ crisis: "crises",
655
+ criterion: "criteria",
656
+ curriculum: "curricula",
657
+ cystoma: "cystomata",
658
+ datum: "data",
659
+ deer: "deer",
660
+ diagnosis: "diagnoses",
661
+ die: "dice",
662
+ dwarf: "dwarfs",
663
+ echo: "echoes",
664
+ elf: "elves",
665
+ elk: "elk",
666
+ ellipsis: "ellipses",
667
+ embargo: "embargoes",
668
+ emphasis: "emphases",
669
+ erratum: "errata",
670
+ "faux pas": "faux pas",
671
+ fez: "fezes",
672
+ firmware: "firmware",
673
+ fish: "fish",
674
+ focus: "foci",
675
+ foot: "feet",
676
+ formula: "formulae",
677
+ fungus: "fungi",
678
+ gallows: "gallows",
679
+ genus: "genera",
680
+ glomerulus: "glomeruli",
681
+ goose: "geese",
682
+ graffito: "graffiti",
683
+ grouse: "grouse",
684
+ half: "halves",
685
+ hamulus: "hamuli",
686
+ hero: "heroes",
687
+ hippopotamus: "hippopotami",
688
+ hoof: "hooves",
689
+ hovercraft: "hovercraft",
690
+ hypothesis: "hypotheses",
691
+ iliac: "ilia",
692
+ incubus: "incubi",
693
+ index: "indices",
694
+ interstitium: "interstitia",
695
+ kakapo: "kakapo",
696
+ knife: "knives",
697
+ larva: "larvae",
698
+ leaf: "leaves",
699
+ libretto: "libretti",
700
+ life: "lives",
701
+ loaf: "loaves",
702
+ loculus: "loculi",
703
+ locus: "loci",
704
+ louse: "lice",
705
+ man: "men",
706
+ matrix: "matrices",
707
+ means: "means",
708
+ measles: "measles",
709
+ media: "media",
710
+ medium: "media",
711
+ memorandum: "memoranda",
712
+ millennium: "millennia",
713
+ minutia: "minutiae",
714
+ moose: "moose",
715
+ mouse: "mice",
716
+ nebula: "nebulae",
717
+ nemesis: "nemeses",
718
+ neurosis: "neuroses",
719
+ news: "news",
720
+ nucleolus: "nucleoli",
721
+ nucleus: "nuclei",
722
+ oasis: "oases",
723
+ occiput: "occipita",
724
+ offspring: "offspring",
725
+ omphalos: "omphaloi",
726
+ opus: "opera",
727
+ ovum: "ova",
728
+ ox: "oxen",
729
+ paralysis: "paralyses",
730
+ parenthesis: "parentheses",
731
+ person: "people",
732
+ phenomenon: "phenomena",
733
+ phylum: "phyla",
734
+ pike: "pike",
735
+ polyhedron: "polyhedra",
736
+ potato: "potatoes",
737
+ primus: "primi",
738
+ prognosis: "prognoses",
739
+ quiz: "quizzes",
740
+ radius: "radii",
741
+ referendum: "referenda",
742
+ salmon: "salmon",
743
+ scarf: "scarves",
744
+ scrotum: "scrota",
745
+ self: "selves",
746
+ seminoma: "seminomata",
747
+ series: "series",
748
+ sheep: "sheep",
749
+ shelf: "shelves",
750
+ shrimp: "shrimp",
751
+ simulacrum: "simulacra",
752
+ soliloquy: "soliloquies",
753
+ spacecraft: "spacecraft",
754
+ species: "species",
755
+ spectrum: "spectra",
756
+ squid: "squid",
757
+ stimulus: "stimuli",
758
+ stratum: "strata",
759
+ swine: "swine",
760
+ syconium: "syconia",
761
+ syllabus: "syllabi",
762
+ symposium: "symposia",
763
+ synopsis: "synopses",
764
+ synthesis: "syntheses",
765
+ tableau: "tableaus",
766
+ testis: "testes",
767
+ that: "those",
768
+ thesis: "theses",
769
+ thief: "thieves",
770
+ this: "these",
771
+ thrombus: "thrombi",
772
+ tomato: "tomatoes",
773
+ tooth: "teeth",
774
+ torus: "tori",
775
+ trout: "trout",
776
+ tuna: "tuna",
777
+ umbilicus: "umbilici",
778
+ uterus: "uteri",
779
+ vertebra: "vertebrae",
780
+ vertex: "vertices",
781
+ veto: "vetoes",
782
+ vita: "vitae",
783
+ vortex: "vortices",
784
+ watercraft: "watercraft",
785
+ wharf: "wharves",
786
+ wife: "wives",
787
+ wolf: "wolves",
788
+ woman: "women"
789
+ };
790
+ }
791
+ });
792
+
793
+ // node_modules/.pnpm/irregular-plurals@3.5.0/node_modules/irregular-plurals/index.js
794
+ var require_irregular_plurals2 = __commonJS({
795
+ "node_modules/.pnpm/irregular-plurals@3.5.0/node_modules/irregular-plurals/index.js"(exports, module) {
796
+ "use strict";
797
+ var irregularPlurals2 = require_irregular_plurals();
798
+ module.exports = new Map(Object.entries(irregularPlurals2));
799
+ }
800
+ });
801
+
612
802
  // package.json
613
- var version = "3.0.0";
803
+ var version = "3.1.0";
804
+
805
+ // node_modules/.pnpm/chalk@5.3.0/node_modules/chalk/source/vendor/ansi-styles/index.js
806
+ var ANSI_BACKGROUND_OFFSET = 10;
807
+ var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
808
+ var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
809
+ var wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
810
+ var styles = {
811
+ modifier: {
812
+ reset: [0, 0],
813
+ // 21 isn't widely supported and 22 does the same thing
814
+ bold: [1, 22],
815
+ dim: [2, 22],
816
+ italic: [3, 23],
817
+ underline: [4, 24],
818
+ overline: [53, 55],
819
+ inverse: [7, 27],
820
+ hidden: [8, 28],
821
+ strikethrough: [9, 29]
822
+ },
823
+ color: {
824
+ black: [30, 39],
825
+ red: [31, 39],
826
+ green: [32, 39],
827
+ yellow: [33, 39],
828
+ blue: [34, 39],
829
+ magenta: [35, 39],
830
+ cyan: [36, 39],
831
+ white: [37, 39],
832
+ // Bright color
833
+ blackBright: [90, 39],
834
+ gray: [90, 39],
835
+ // Alias of `blackBright`
836
+ grey: [90, 39],
837
+ // Alias of `blackBright`
838
+ redBright: [91, 39],
839
+ greenBright: [92, 39],
840
+ yellowBright: [93, 39],
841
+ blueBright: [94, 39],
842
+ magentaBright: [95, 39],
843
+ cyanBright: [96, 39],
844
+ whiteBright: [97, 39]
845
+ },
846
+ bgColor: {
847
+ bgBlack: [40, 49],
848
+ bgRed: [41, 49],
849
+ bgGreen: [42, 49],
850
+ bgYellow: [43, 49],
851
+ bgBlue: [44, 49],
852
+ bgMagenta: [45, 49],
853
+ bgCyan: [46, 49],
854
+ bgWhite: [47, 49],
855
+ // Bright color
856
+ bgBlackBright: [100, 49],
857
+ bgGray: [100, 49],
858
+ // Alias of `bgBlackBright`
859
+ bgGrey: [100, 49],
860
+ // Alias of `bgBlackBright`
861
+ bgRedBright: [101, 49],
862
+ bgGreenBright: [102, 49],
863
+ bgYellowBright: [103, 49],
864
+ bgBlueBright: [104, 49],
865
+ bgMagentaBright: [105, 49],
866
+ bgCyanBright: [106, 49],
867
+ bgWhiteBright: [107, 49]
868
+ }
869
+ };
870
+ var modifierNames = Object.keys(styles.modifier);
871
+ var foregroundColorNames = Object.keys(styles.color);
872
+ var backgroundColorNames = Object.keys(styles.bgColor);
873
+ var colorNames = [...foregroundColorNames, ...backgroundColorNames];
874
+ function assembleStyles() {
875
+ const codes = /* @__PURE__ */ new Map();
876
+ for (const [groupName, group] of Object.entries(styles)) {
877
+ for (const [styleName, style] of Object.entries(group)) {
878
+ styles[styleName] = {
879
+ open: `\x1B[${style[0]}m`,
880
+ close: `\x1B[${style[1]}m`
881
+ };
882
+ group[styleName] = styles[styleName];
883
+ codes.set(style[0], style[1]);
884
+ }
885
+ Object.defineProperty(styles, groupName, {
886
+ value: group,
887
+ enumerable: false
888
+ });
889
+ }
890
+ Object.defineProperty(styles, "codes", {
891
+ value: codes,
892
+ enumerable: false
893
+ });
894
+ styles.color.close = "\x1B[39m";
895
+ styles.bgColor.close = "\x1B[49m";
896
+ styles.color.ansi = wrapAnsi16();
897
+ styles.color.ansi256 = wrapAnsi256();
898
+ styles.color.ansi16m = wrapAnsi16m();
899
+ styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
900
+ styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
901
+ styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
902
+ Object.defineProperties(styles, {
903
+ rgbToAnsi256: {
904
+ value(red, green, blue) {
905
+ if (red === green && green === blue) {
906
+ if (red < 8) {
907
+ return 16;
908
+ }
909
+ if (red > 248) {
910
+ return 231;
911
+ }
912
+ return Math.round((red - 8) / 247 * 24) + 232;
913
+ }
914
+ return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
915
+ },
916
+ enumerable: false
917
+ },
918
+ hexToRgb: {
919
+ value(hex) {
920
+ const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
921
+ if (!matches) {
922
+ return [0, 0, 0];
923
+ }
924
+ let [colorString] = matches;
925
+ if (colorString.length === 3) {
926
+ colorString = [...colorString].map((character) => character + character).join("");
927
+ }
928
+ const integer = Number.parseInt(colorString, 16);
929
+ return [
930
+ /* eslint-disable no-bitwise */
931
+ integer >> 16 & 255,
932
+ integer >> 8 & 255,
933
+ integer & 255
934
+ /* eslint-enable no-bitwise */
935
+ ];
936
+ },
937
+ enumerable: false
938
+ },
939
+ hexToAnsi256: {
940
+ value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
941
+ enumerable: false
942
+ },
943
+ ansi256ToAnsi: {
944
+ value(code) {
945
+ if (code < 8) {
946
+ return 30 + code;
947
+ }
948
+ if (code < 16) {
949
+ return 90 + (code - 8);
950
+ }
951
+ let red;
952
+ let green;
953
+ let blue;
954
+ if (code >= 232) {
955
+ red = ((code - 232) * 10 + 8) / 255;
956
+ green = red;
957
+ blue = red;
958
+ } else {
959
+ code -= 16;
960
+ const remainder = code % 36;
961
+ red = Math.floor(code / 36) / 5;
962
+ green = Math.floor(remainder / 6) / 5;
963
+ blue = remainder % 6 / 5;
964
+ }
965
+ const value = Math.max(red, green, blue) * 2;
966
+ if (value === 0) {
967
+ return 30;
968
+ }
969
+ let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
970
+ if (value === 2) {
971
+ result += 60;
972
+ }
973
+ return result;
974
+ },
975
+ enumerable: false
976
+ },
977
+ rgbToAnsi: {
978
+ value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
979
+ enumerable: false
980
+ },
981
+ hexToAnsi: {
982
+ value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
983
+ enumerable: false
984
+ }
985
+ });
986
+ return styles;
987
+ }
988
+ var ansiStyles = assembleStyles();
989
+ var ansi_styles_default = ansiStyles;
990
+
991
+ // node_modules/.pnpm/chalk@5.3.0/node_modules/chalk/source/vendor/supports-color/index.js
992
+ import process2 from "node:process";
993
+ import os from "node:os";
994
+ import tty from "node:tty";
995
+ function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process2.argv) {
996
+ const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
997
+ const position = argv.indexOf(prefix + flag);
998
+ const terminatorPosition = argv.indexOf("--");
999
+ return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
1000
+ }
1001
+ var { env } = process2;
1002
+ var flagForceColor;
1003
+ if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
1004
+ flagForceColor = 0;
1005
+ } else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
1006
+ flagForceColor = 1;
1007
+ }
1008
+ function envForceColor() {
1009
+ if ("FORCE_COLOR" in env) {
1010
+ if (env.FORCE_COLOR === "true") {
1011
+ return 1;
1012
+ }
1013
+ if (env.FORCE_COLOR === "false") {
1014
+ return 0;
1015
+ }
1016
+ return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
1017
+ }
1018
+ }
1019
+ function translateLevel(level) {
1020
+ if (level === 0) {
1021
+ return false;
1022
+ }
1023
+ return {
1024
+ level,
1025
+ hasBasic: true,
1026
+ has256: level >= 2,
1027
+ has16m: level >= 3
1028
+ };
1029
+ }
1030
+ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
1031
+ const noFlagForceColor = envForceColor();
1032
+ if (noFlagForceColor !== void 0) {
1033
+ flagForceColor = noFlagForceColor;
1034
+ }
1035
+ const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
1036
+ if (forceColor === 0) {
1037
+ return 0;
1038
+ }
1039
+ if (sniffFlags) {
1040
+ if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
1041
+ return 3;
1042
+ }
1043
+ if (hasFlag("color=256")) {
1044
+ return 2;
1045
+ }
1046
+ }
1047
+ if ("TF_BUILD" in env && "AGENT_NAME" in env) {
1048
+ return 1;
1049
+ }
1050
+ if (haveStream && !streamIsTTY && forceColor === void 0) {
1051
+ return 0;
1052
+ }
1053
+ const min = forceColor || 0;
1054
+ if (env.TERM === "dumb") {
1055
+ return min;
1056
+ }
1057
+ if (process2.platform === "win32") {
1058
+ const osRelease = os.release().split(".");
1059
+ if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
1060
+ return Number(osRelease[2]) >= 14931 ? 3 : 2;
1061
+ }
1062
+ return 1;
1063
+ }
1064
+ if ("CI" in env) {
1065
+ if ("GITHUB_ACTIONS" in env || "GITEA_ACTIONS" in env) {
1066
+ return 3;
1067
+ }
1068
+ if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
1069
+ return 1;
1070
+ }
1071
+ return min;
1072
+ }
1073
+ if ("TEAMCITY_VERSION" in env) {
1074
+ return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
1075
+ }
1076
+ if (env.COLORTERM === "truecolor") {
1077
+ return 3;
1078
+ }
1079
+ if (env.TERM === "xterm-kitty") {
1080
+ return 3;
1081
+ }
1082
+ if ("TERM_PROGRAM" in env) {
1083
+ const version2 = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
1084
+ switch (env.TERM_PROGRAM) {
1085
+ case "iTerm.app": {
1086
+ return version2 >= 3 ? 3 : 2;
1087
+ }
1088
+ case "Apple_Terminal": {
1089
+ return 2;
1090
+ }
1091
+ }
1092
+ }
1093
+ if (/-256(color)?$/i.test(env.TERM)) {
1094
+ return 2;
1095
+ }
1096
+ if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
1097
+ return 1;
1098
+ }
1099
+ if ("COLORTERM" in env) {
1100
+ return 1;
1101
+ }
1102
+ return min;
1103
+ }
1104
+ function createSupportsColor(stream, options = {}) {
1105
+ const level = _supportsColor(stream, {
1106
+ streamIsTTY: stream && stream.isTTY,
1107
+ ...options
1108
+ });
1109
+ return translateLevel(level);
1110
+ }
1111
+ var supportsColor = {
1112
+ stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
1113
+ stderr: createSupportsColor({ isTTY: tty.isatty(2) })
1114
+ };
1115
+ var supports_color_default = supportsColor;
1116
+
1117
+ // node_modules/.pnpm/chalk@5.3.0/node_modules/chalk/source/utilities.js
1118
+ function stringReplaceAll(string, substring, replacer) {
1119
+ let index2 = string.indexOf(substring);
1120
+ if (index2 === -1) {
1121
+ return string;
1122
+ }
1123
+ const substringLength = substring.length;
1124
+ let endIndex = 0;
1125
+ let returnValue = "";
1126
+ do {
1127
+ returnValue += string.slice(endIndex, index2) + substring + replacer;
1128
+ endIndex = index2 + substringLength;
1129
+ index2 = string.indexOf(substring, endIndex);
1130
+ } while (index2 !== -1);
1131
+ returnValue += string.slice(endIndex);
1132
+ return returnValue;
1133
+ }
1134
+ function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index2) {
1135
+ let endIndex = 0;
1136
+ let returnValue = "";
1137
+ do {
1138
+ const gotCR = string[index2 - 1] === "\r";
1139
+ returnValue += string.slice(endIndex, gotCR ? index2 - 1 : index2) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
1140
+ endIndex = index2 + 1;
1141
+ index2 = string.indexOf("\n", endIndex);
1142
+ } while (index2 !== -1);
1143
+ returnValue += string.slice(endIndex);
1144
+ return returnValue;
1145
+ }
1146
+
1147
+ // node_modules/.pnpm/chalk@5.3.0/node_modules/chalk/source/index.js
1148
+ var { stdout: stdoutColor, stderr: stderrColor } = supports_color_default;
1149
+ var GENERATOR = Symbol("GENERATOR");
1150
+ var STYLER = Symbol("STYLER");
1151
+ var IS_EMPTY = Symbol("IS_EMPTY");
1152
+ var levelMapping = [
1153
+ "ansi",
1154
+ "ansi",
1155
+ "ansi256",
1156
+ "ansi16m"
1157
+ ];
1158
+ var styles2 = /* @__PURE__ */ Object.create(null);
1159
+ var applyOptions = (object, options = {}) => {
1160
+ if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
1161
+ throw new Error("The `level` option should be an integer from 0 to 3");
1162
+ }
1163
+ const colorLevel = stdoutColor ? stdoutColor.level : 0;
1164
+ object.level = options.level === void 0 ? colorLevel : options.level;
1165
+ };
1166
+ var chalkFactory = (options) => {
1167
+ const chalk2 = (...strings) => strings.join(" ");
1168
+ applyOptions(chalk2, options);
1169
+ Object.setPrototypeOf(chalk2, createChalk.prototype);
1170
+ return chalk2;
1171
+ };
1172
+ function createChalk(options) {
1173
+ return chalkFactory(options);
1174
+ }
1175
+ Object.setPrototypeOf(createChalk.prototype, Function.prototype);
1176
+ for (const [styleName, style] of Object.entries(ansi_styles_default)) {
1177
+ styles2[styleName] = {
1178
+ get() {
1179
+ const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
1180
+ Object.defineProperty(this, styleName, { value: builder });
1181
+ return builder;
1182
+ }
1183
+ };
1184
+ }
1185
+ styles2.visible = {
1186
+ get() {
1187
+ const builder = createBuilder(this, this[STYLER], true);
1188
+ Object.defineProperty(this, "visible", { value: builder });
1189
+ return builder;
1190
+ }
1191
+ };
1192
+ var getModelAnsi = (model, level, type, ...arguments_) => {
1193
+ if (model === "rgb") {
1194
+ if (level === "ansi16m") {
1195
+ return ansi_styles_default[type].ansi16m(...arguments_);
1196
+ }
1197
+ if (level === "ansi256") {
1198
+ return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
1199
+ }
1200
+ return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
1201
+ }
1202
+ if (model === "hex") {
1203
+ return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
1204
+ }
1205
+ return ansi_styles_default[type][model](...arguments_);
1206
+ };
1207
+ var usedModels = ["rgb", "hex", "ansi256"];
1208
+ for (const model of usedModels) {
1209
+ styles2[model] = {
1210
+ get() {
1211
+ const { level } = this;
1212
+ return function(...arguments_) {
1213
+ const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
1214
+ return createBuilder(this, styler, this[IS_EMPTY]);
1215
+ };
1216
+ }
1217
+ };
1218
+ const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
1219
+ styles2[bgModel] = {
1220
+ get() {
1221
+ const { level } = this;
1222
+ return function(...arguments_) {
1223
+ const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]);
1224
+ return createBuilder(this, styler, this[IS_EMPTY]);
1225
+ };
1226
+ }
1227
+ };
1228
+ }
1229
+ var proto = Object.defineProperties(() => {
1230
+ }, {
1231
+ ...styles2,
1232
+ level: {
1233
+ enumerable: true,
1234
+ get() {
1235
+ return this[GENERATOR].level;
1236
+ },
1237
+ set(level) {
1238
+ this[GENERATOR].level = level;
1239
+ }
1240
+ }
1241
+ });
1242
+ var createStyler = (open2, close, parent2) => {
1243
+ let openAll;
1244
+ let closeAll;
1245
+ if (parent2 === void 0) {
1246
+ openAll = open2;
1247
+ closeAll = close;
1248
+ } else {
1249
+ openAll = parent2.openAll + open2;
1250
+ closeAll = close + parent2.closeAll;
1251
+ }
1252
+ return {
1253
+ open: open2,
1254
+ close,
1255
+ openAll,
1256
+ closeAll,
1257
+ parent: parent2
1258
+ };
1259
+ };
1260
+ var createBuilder = (self, _styler, _isEmpty) => {
1261
+ const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
1262
+ Object.setPrototypeOf(builder, proto);
1263
+ builder[GENERATOR] = self;
1264
+ builder[STYLER] = _styler;
1265
+ builder[IS_EMPTY] = _isEmpty;
1266
+ return builder;
1267
+ };
1268
+ var applyStyle = (self, string) => {
1269
+ if (self.level <= 0 || !string) {
1270
+ return self[IS_EMPTY] ? "" : string;
1271
+ }
1272
+ let styler = self[STYLER];
1273
+ if (styler === void 0) {
1274
+ return string;
1275
+ }
1276
+ const { openAll, closeAll } = styler;
1277
+ if (string.includes("\x1B")) {
1278
+ while (styler !== void 0) {
1279
+ string = stringReplaceAll(string, styler.close, styler.open);
1280
+ styler = styler.parent;
1281
+ }
1282
+ }
1283
+ const lfIndex = string.indexOf("\n");
1284
+ if (lfIndex !== -1) {
1285
+ string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
1286
+ }
1287
+ return openAll + string + closeAll;
1288
+ };
1289
+ Object.defineProperties(createChalk.prototype, styles2);
1290
+ var chalk = createChalk();
1291
+ var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
1292
+ var source_default = chalk;
1293
+
1294
+ // src/lib/utilities/logger.ts
1295
+ var cli = false;
1296
+ var verbose = false;
1297
+ function setCli(value) {
1298
+ cli = value;
1299
+ }
1300
+ function setVerbose(value) {
1301
+ verbose = value;
1302
+ }
1303
+ function log(...data2) {
1304
+ console.log(...data2);
1305
+ }
1306
+ function warn(...data2) {
1307
+ console.warn(source_default.yellow("[Warning]"), ...data2);
1308
+ }
1309
+ function error(...data2) {
1310
+ console.error(source_default.red("[Error]"), ...data2);
1311
+ }
1312
+ function info(...data2) {
1313
+ if (!verbose)
1314
+ return;
1315
+ if (cli) {
1316
+ console.warn(source_default.green("[Info]"), ...data2);
1317
+ } else {
1318
+ console.log(...data2);
1319
+ }
1320
+ }
614
1321
 
615
1322
  // src/lib/local-tldraw-server.ts
616
1323
  import express from "express";
617
1324
 
618
1325
  // node_modules/.pnpm/get-port@7.0.0/node_modules/get-port/index.js
619
1326
  import net from "node:net";
620
- import os from "node:os";
1327
+ import os2 from "node:os";
621
1328
  var Locked = class extends Error {
622
1329
  constructor(port) {
623
1330
  super(`${port} is locked`);
@@ -630,7 +1337,7 @@ var lockedPorts = {
630
1337
  var releaseOldLockedPortsIntervalMs = 1e3 * 15;
631
1338
  var timeout;
632
1339
  var getLocalHosts = () => {
633
- const interfaces = os.networkInterfaces();
1340
+ const interfaces = os2.networkInterfaces();
634
1341
  const results = /* @__PURE__ */ new Set([void 0, "0.0.0.0"]);
635
1342
  for (const _interface of Object.values(interfaces)) {
636
1343
  for (const config of _interface) {
@@ -657,9 +1364,9 @@ var getAvailablePort = async (options, hosts) => {
657
1364
  for (const host of hosts) {
658
1365
  try {
659
1366
  await checkAvailablePort({ port: options.port, host });
660
- } catch (error) {
661
- if (!["EADDRNOTAVAIL", "EINVAL"].includes(error.code)) {
662
- throw error;
1367
+ } catch (error2) {
1368
+ if (!["EADDRNOTAVAIL", "EINVAL"].includes(error2.code)) {
1369
+ throw error2;
663
1370
  }
664
1371
  }
665
1372
  }
@@ -719,9 +1426,9 @@ async function getPorts(options) {
719
1426
  }
720
1427
  lockedPorts.young.add(availablePort);
721
1428
  return availablePort;
722
- } catch (error) {
723
- if (!["EADDRINUSE", "EACCES"].includes(error.code) && !(error instanceof Locked)) {
724
- throw error;
1429
+ } catch (error2) {
1430
+ if (!["EADDRINUSE", "EACCES"].includes(error2.code) && !(error2 instanceof Locked)) {
1431
+ throw error2;
725
1432
  }
726
1433
  }
727
1434
  }
@@ -732,31 +1439,25 @@ async function getPorts(options) {
732
1439
  import path, { dirname } from "node:path";
733
1440
  import { fileURLToPath } from "node:url";
734
1441
  var LocalTldrawServer = class {
735
- constructor(tldrData, verbose = false) {
1442
+ constructor(tldrData) {
736
1443
  this.tldrData = tldrData;
737
- this.verbose = verbose;
738
1444
  this.tldrData = tldrData;
739
1445
  }
740
- verbose;
741
- // eslint-disable-next-line perfectionist/sort-classes
742
1446
  server;
743
1447
  close() {
744
1448
  if (!this.server)
745
1449
  throw new Error("Server not started");
746
1450
  this.server.close();
747
- if (this.verbose)
748
- console.log("Stopped tldraw server");
1451
+ info("Stopped tldraw server");
749
1452
  }
750
1453
  async start() {
751
- if (this.verbose)
752
- console.log("Starting tldraw server...");
1454
+ info("Starting tldraw server...");
753
1455
  const scriptDirectory = dirname(fileURLToPath(import.meta.url));
754
1456
  const tldrawPath = path.join(
755
1457
  scriptDirectory,
756
1458
  scriptDirectory.endsWith("/src/lib") ? "../../dist/tldraw" : scriptDirectory.endsWith("/dist/lib") ? "../tldraw" : "../dist/tldraw"
757
1459
  );
758
- if (this.verbose)
759
- console.log(`tldraw served from "${tldrawPath}"`);
1460
+ info(`tldraw served from "${tldrawPath}"`);
760
1461
  const app = express();
761
1462
  const port = await getPorts();
762
1463
  app.get("/tldr-data", (_, response) => {
@@ -770,11 +1471,10 @@ var LocalTldrawServer = class {
770
1471
  app.use(express.static(tldrawPath));
771
1472
  try {
772
1473
  this.server = app.listen(port);
773
- } catch (error) {
774
- console.error(error);
1474
+ } catch (error2) {
1475
+ error(error2);
775
1476
  }
776
- if (this.verbose)
777
- console.log(`tldraw hosted at "${this.href}"`);
1477
+ info(`tldraw hosted at "${this.href}"`);
778
1478
  }
779
1479
  get href() {
780
1480
  if (!this.server)
@@ -3327,8 +4027,8 @@ var DomHandler = class {
3327
4027
  this.parser = null;
3328
4028
  this.handleCallback(null);
3329
4029
  }
3330
- onerror(error) {
3331
- this.handleCallback(error);
4030
+ onerror(error2) {
4031
+ this.handleCallback(error2);
3332
4032
  }
3333
4033
  onclosetag() {
3334
4034
  this.lastNode = null;
@@ -3384,11 +4084,11 @@ var DomHandler = class {
3384
4084
  const node = new ProcessingInstruction(name, data2);
3385
4085
  this.addNode(node);
3386
4086
  }
3387
- handleCallback(error) {
4087
+ handleCallback(error2) {
3388
4088
  if (typeof this.callback === "function") {
3389
- this.callback(error, this.dom);
3390
- } else if (error) {
3391
- throw error;
4089
+ this.callback(error2, this.dom);
4090
+ } else if (error2) {
4091
+ throw error2;
3392
4092
  }
3393
4093
  }
3394
4094
  addNode(node) {
@@ -7046,14 +7746,14 @@ function css(prop2, val2) {
7046
7746
  }
7047
7747
  function setCss(el, prop2, value, idx) {
7048
7748
  if (typeof prop2 === "string") {
7049
- const styles = getCss(el);
7050
- const val2 = typeof value === "function" ? value.call(el, idx, styles[prop2]) : value;
7749
+ const styles3 = getCss(el);
7750
+ const val2 = typeof value === "function" ? value.call(el, idx, styles3[prop2]) : value;
7051
7751
  if (val2 === "") {
7052
- delete styles[prop2];
7752
+ delete styles3[prop2];
7053
7753
  } else if (val2 != null) {
7054
- styles[prop2] = val2;
7754
+ styles3[prop2] = val2;
7055
7755
  }
7056
- el.attribs["style"] = stringify(styles);
7756
+ el.attribs["style"] = stringify(styles3);
7057
7757
  } else if (typeof prop2 === "object") {
7058
7758
  Object.keys(prop2).forEach((k, i) => {
7059
7759
  setCss(el, k, prop2[k], i);
@@ -7063,31 +7763,31 @@ function setCss(el, prop2, value, idx) {
7063
7763
  function getCss(el, prop2) {
7064
7764
  if (!el || !isTag2(el))
7065
7765
  return;
7066
- const styles = parse5(el.attribs["style"]);
7766
+ const styles3 = parse5(el.attribs["style"]);
7067
7767
  if (typeof prop2 === "string") {
7068
- return styles[prop2];
7768
+ return styles3[prop2];
7069
7769
  }
7070
7770
  if (Array.isArray(prop2)) {
7071
7771
  const newStyles = {};
7072
7772
  prop2.forEach((item) => {
7073
- if (styles[item] != null) {
7074
- newStyles[item] = styles[item];
7773
+ if (styles3[item] != null) {
7774
+ newStyles[item] = styles3[item];
7075
7775
  }
7076
7776
  });
7077
7777
  return newStyles;
7078
7778
  }
7079
- return styles;
7779
+ return styles3;
7080
7780
  }
7081
7781
  function stringify(obj) {
7082
7782
  return Object.keys(obj).reduce((str, prop2) => `${str}${str ? " " : ""}${prop2}: ${obj[prop2]};`, "");
7083
7783
  }
7084
- function parse5(styles) {
7085
- styles = (styles || "").trim();
7086
- if (!styles)
7784
+ function parse5(styles3) {
7785
+ styles3 = (styles3 || "").trim();
7786
+ if (!styles3)
7087
7787
  return {};
7088
7788
  const obj = {};
7089
7789
  let key;
7090
- for (const str of styles.split(";")) {
7790
+ for (const str of styles3.split(";")) {
7091
7791
  const n = str.indexOf(":");
7092
7792
  if (n < 1 || n === str.length - 1) {
7093
7793
  const trimmed = str.trimEnd();
@@ -16408,13 +17108,13 @@ var { root: root2 } = static_exports;
16408
17108
 
16409
17109
  // src/lib/tldraw-controller.ts
16410
17110
  import fs from "node:fs/promises";
16411
- import os3 from "node:os";
17111
+ import os4 from "node:os";
16412
17112
  import path2 from "node:path";
16413
17113
  import puppeteer from "puppeteer";
16414
17114
 
16415
17115
  // node_modules/.pnpm/untildify@5.0.0/node_modules/untildify/index.js
16416
- import os2 from "node:os";
16417
- var homeDirectory = os2.homedir();
17116
+ import os3 from "node:os";
17117
+ var homeDirectory = os3.homedir();
16418
17118
  function untildify(pathWithTilde) {
16419
17119
  if (typeof pathWithTilde !== "string") {
16420
17120
  throw new TypeError(`Expected a string, got ${typeof pathWithTilde}`);
@@ -16424,12 +17124,10 @@ function untildify(pathWithTilde) {
16424
17124
 
16425
17125
  // src/lib/tldraw-controller.ts
16426
17126
  var TldrawController = class {
16427
- constructor(href, verbose = false) {
17127
+ constructor(href) {
16428
17128
  this.href = href;
16429
- this.verbose = verbose;
16430
17129
  this.href = href;
16431
17130
  }
16432
- verbose;
16433
17131
  page;
16434
17132
  isEmpty;
16435
17133
  browser;
@@ -16439,8 +17137,7 @@ var TldrawController = class {
16439
17137
  return this.href.startsWith("http://localhost");
16440
17138
  }
16441
17139
  async start() {
16442
- if (this.verbose)
16443
- console.log("Starting Puppeteer...");
17140
+ info("Starting Puppeteer...");
16444
17141
  this.browser = await puppeteer.launch({
16445
17142
  args: this.isLocal ? ["--no-sandbox", "--disable-web-security"] : [],
16446
17143
  headless: "new"
@@ -16450,21 +17147,20 @@ var TldrawController = class {
16450
17147
  const messageType = message.type();
16451
17148
  const messageText = message.text();
16452
17149
  if (messageType === "error") {
16453
- console.error(`[Browser] ${messageText}`);
17150
+ error(source_default.blue("[Browser]"), messageText);
16454
17151
  } else if (messageType === "warning") {
16455
- console.warn(`[Browser] ${messageText}`);
16456
- } else if (this.verbose) {
16457
- console.log(`[Browser] ${messageText}`);
17152
+ warn(source_default.blue("[Browser]"), messageText);
17153
+ } else {
17154
+ info(source_default.blue("[Browser]"), messageText);
16458
17155
  }
16459
17156
  });
16460
17157
  this.client = await this.page.target().createCDPSession();
16461
17158
  await this.client.send("Browser.setDownloadBehavior", {
16462
17159
  behavior: "allowAndName",
16463
- downloadPath: os3.tmpdir(),
17160
+ downloadPath: os4.tmpdir(),
16464
17161
  eventsEnabled: true
16465
17162
  });
16466
- if (this.verbose)
16467
- console.log(`Navigating to: ${this.href}`);
17163
+ info(`Navigating to: ${this.href}`);
16468
17164
  await this.page.goto(this.href, { waitUntil: "networkidle0" });
16469
17165
  const shapeCount = await this.page.evaluate("editor.getCurrentPageShapes().length");
16470
17166
  this.isEmpty = shapeCount === 0;
@@ -16473,13 +17169,11 @@ var TldrawController = class {
16473
17169
  if (!this.browser)
16474
17170
  throw new Error("Controller not started");
16475
17171
  if (this.originalDarkMode !== void 0) {
16476
- if (this.verbose)
16477
- console.log(`Restoring dark mode: ${this.originalDarkMode}`);
17172
+ info(`Restoring dark mode: ${this.originalDarkMode}`);
16478
17173
  await this.setDarkMode(this.originalDarkMode);
16479
17174
  }
16480
17175
  await this.browser.close();
16481
- if (this.verbose)
16482
- console.log("Stopped controller");
17176
+ info("Stopped controller");
16483
17177
  }
16484
17178
  // Public method doesn't expose pageFrame
16485
17179
  async download(output, filename, format3, stripStyle, print) {
@@ -16493,7 +17187,7 @@ var TldrawController = class {
16493
17187
  for (const frame of frameNamesOrIds) {
16494
17188
  const pageFrame = await this.getPageFrameWithNameOrId(frame);
16495
17189
  if (pageFrame === void 0) {
16496
- console.warn(`Frame "${frame}" not found, skipping`);
17190
+ warn(`Frame "${frame}" not found, skipping`);
16497
17191
  } else {
16498
17192
  validPageFrames.push(pageFrame);
16499
17193
  }
@@ -16503,8 +17197,8 @@ var TldrawController = class {
16503
17197
  }
16504
17198
  const validFrameNames = validPageFrames.map((frame) => slugify(frame.name));
16505
17199
  const isFrameNameCollision = validFrameNames.length !== new Set(validFrameNames).size;
16506
- if (this.verbose && isFrameNameCollision) {
16507
- console.warn(
17200
+ if (isFrameNameCollision) {
17201
+ warn(
16508
17202
  "Frame names are not unique, including frame IDs in the output filenames to avoid collisions"
16509
17203
  );
16510
17204
  }
@@ -16533,8 +17227,7 @@ var TldrawController = class {
16533
17227
  async setTransparency(transparent) {
16534
17228
  if (!this.page)
16535
17229
  throw new Error("Controller not started");
16536
- if (this.verbose)
16537
- console.log(`Setting background transparency: ${transparent}`);
17230
+ info(`Setting background transparency: ${transparent}`);
16538
17231
  await this.page.evaluate(
16539
17232
  `editor.updateInstanceState(
16540
17233
  { exportBackground: ${!transparent} },
@@ -16545,8 +17238,7 @@ var TldrawController = class {
16545
17238
  async setDarkMode(darkMode) {
16546
17239
  if (!this.page)
16547
17240
  throw new Error("Controller not started");
16548
- if (this.verbose)
16549
- console.log(`Setting dark mode: ${darkMode}`);
17241
+ info(`Setting dark mode: ${darkMode}`);
16550
17242
  if (!this.originalDarkMode)
16551
17243
  this.originalDarkMode = await this.getDarkMode();
16552
17244
  await this.page.evaluate(`editor.user.updateUserPreferences({ isDarkMode: ${darkMode}})`);
@@ -16559,18 +17251,16 @@ var TldrawController = class {
16559
17251
  throw new Error("Cannot export an empty document");
16560
17252
  }
16561
17253
  if (stripStyle && format3 !== "svg") {
16562
- console.warn("--strip-style is only supported for SVG output");
17254
+ warn("--strip-style is only supported for SVG output");
16563
17255
  }
16564
17256
  if (pageFrame !== void 0 && format3 === "tldr") {
16565
- console.warn("--frames is not supported for tldr output, downloading entire document");
17257
+ warn("--frames is not supported for tldr output, downloading entire document");
16566
17258
  }
16567
17259
  const completionPromise = this.waitForDownloadCompletion();
16568
17260
  await this.closeMenus();
16569
17261
  let frameSuffix = "";
16570
17262
  if (pageFrame !== void 0 && format3 !== "tldr") {
16571
- if (this.verbose) {
16572
- console.log(`Selecting sketch frame "${pageFrame.name}" with ID "${pageFrame.id}"`);
16573
- }
17263
+ info(`Selecting sketch frame "${pageFrame.name}" with ID "${pageFrame.id}"`);
16574
17264
  frameSuffix = `-${slugify(pageFrame.name)}`;
16575
17265
  await this.page.evaluate("editor.selectNone()");
16576
17266
  await this.page.evaluate(`editor.select('${pageFrame.id}')`);
@@ -16590,7 +17280,7 @@ var TldrawController = class {
16590
17280
  }
16591
17281
  const downloadGuid = await completionPromise;
16592
17282
  await this.page.waitForNetworkIdle();
16593
- const downloadPath = path2.join(os3.tmpdir(), downloadGuid);
17283
+ const downloadPath = path2.join(os4.tmpdir(), downloadGuid);
16594
17284
  const outputPath = print ? downloadPath : path2.resolve(untildify(path2.join(output, `${filename}${frameSuffix}.${format3}`)));
16595
17285
  if (!print)
16596
17286
  await fs.rename(downloadPath, outputPath);
@@ -16689,11 +17379,11 @@ async function isType(fsStatType, statsMethodName, filePath) {
16689
17379
  try {
16690
17380
  const stats = await fsPromises[fsStatType](filePath);
16691
17381
  return stats[statsMethodName]();
16692
- } catch (error) {
16693
- if (error.code === "ENOENT") {
17382
+ } catch (error2) {
17383
+ if (error2.code === "ENOENT") {
16694
17384
  return false;
16695
17385
  }
16696
- throw error;
17386
+ throw error2;
16697
17387
  }
16698
17388
  }
16699
17389
  function isTypeSync(fsStatType, statsMethodName, filePath) {
@@ -16702,11 +17392,11 @@ function isTypeSync(fsStatType, statsMethodName, filePath) {
16702
17392
  }
16703
17393
  try {
16704
17394
  return fs2[fsStatType](filePath)[statsMethodName]();
16705
- } catch (error) {
16706
- if (error.code === "ENOENT") {
17395
+ } catch (error2) {
17396
+ if (error2.code === "ENOENT") {
16707
17397
  return false;
16708
17398
  }
16709
- throw error;
17399
+ throw error2;
16710
17400
  }
16711
17401
  }
16712
17402
  var isFile = isType.bind(null, "stat", "isFile");
@@ -16746,6 +17436,134 @@ function validatePathOrUrl(pathOrUrl, options = {}) {
16746
17436
  // src/lib/tldraw-to-image.ts
16747
17437
  import fs3 from "node:fs/promises";
16748
17438
  import path4 from "node:path";
17439
+
17440
+ // node_modules/.pnpm/parse-ms@4.0.0/node_modules/parse-ms/index.js
17441
+ var toZeroIfInfinity = (value) => Number.isFinite(value) ? value : 0;
17442
+ function parseNumber(milliseconds) {
17443
+ return {
17444
+ days: Math.trunc(milliseconds / 864e5),
17445
+ hours: Math.trunc(milliseconds / 36e5 % 24),
17446
+ minutes: Math.trunc(milliseconds / 6e4 % 60),
17447
+ seconds: Math.trunc(milliseconds / 1e3 % 60),
17448
+ milliseconds: Math.trunc(milliseconds % 1e3),
17449
+ microseconds: Math.trunc(toZeroIfInfinity(milliseconds * 1e3) % 1e3),
17450
+ nanoseconds: Math.trunc(toZeroIfInfinity(milliseconds * 1e6) % 1e3)
17451
+ };
17452
+ }
17453
+ function parseBigint(milliseconds) {
17454
+ return {
17455
+ days: milliseconds / 86400000n,
17456
+ hours: milliseconds / 3600000n % 24n,
17457
+ minutes: milliseconds / 60000n % 60n,
17458
+ seconds: milliseconds / 1000n % 60n,
17459
+ milliseconds: milliseconds % 1000n,
17460
+ microseconds: 0n,
17461
+ nanoseconds: 0n
17462
+ };
17463
+ }
17464
+ function parseMilliseconds(milliseconds) {
17465
+ switch (typeof milliseconds) {
17466
+ case "number": {
17467
+ if (Number.isFinite(milliseconds)) {
17468
+ return parseNumber(milliseconds);
17469
+ }
17470
+ break;
17471
+ }
17472
+ case "bigint": {
17473
+ return parseBigint(milliseconds);
17474
+ }
17475
+ }
17476
+ throw new TypeError("Expected a finite number or bigint");
17477
+ }
17478
+
17479
+ // node_modules/.pnpm/pretty-ms@9.0.0/node_modules/pretty-ms/index.js
17480
+ var isZero = (value) => value === 0 || value === 0n;
17481
+ var pluralize = (word, count) => count === 1 || count === 1n ? word : `${word}s`;
17482
+ var SECOND_ROUNDING_EPSILON = 1e-7;
17483
+ var ONE_DAY_IN_MILLISECONDS = 24n * 60n * 60n * 1000n;
17484
+ function prettyMilliseconds(milliseconds, options) {
17485
+ const isBigInt = typeof milliseconds === "bigint";
17486
+ if (!isBigInt && !Number.isFinite(milliseconds)) {
17487
+ throw new TypeError("Expected a finite number or bigint");
17488
+ }
17489
+ options = { ...options };
17490
+ if (options.colonNotation) {
17491
+ options.compact = false;
17492
+ options.formatSubMilliseconds = false;
17493
+ options.separateMilliseconds = false;
17494
+ options.verbose = false;
17495
+ }
17496
+ if (options.compact) {
17497
+ options.unitCount = 1;
17498
+ options.secondsDecimalDigits = 0;
17499
+ options.millisecondsDecimalDigits = 0;
17500
+ }
17501
+ let result = [];
17502
+ const floorDecimals = (value, decimalDigits) => {
17503
+ const flooredInterimValue = Math.floor(value * 10 ** decimalDigits + SECOND_ROUNDING_EPSILON);
17504
+ const flooredValue = Math.round(flooredInterimValue) / 10 ** decimalDigits;
17505
+ return flooredValue.toFixed(decimalDigits);
17506
+ };
17507
+ const add2 = (value, long, short, valueString) => {
17508
+ if ((result.length === 0 || !options.colonNotation) && isZero(value) && !(options.colonNotation && short === "m")) {
17509
+ return;
17510
+ }
17511
+ valueString = valueString ?? String(value);
17512
+ if (options.colonNotation) {
17513
+ const wholeDigits = valueString.includes(".") ? valueString.split(".")[0].length : valueString.length;
17514
+ const minLength = result.length > 0 ? 2 : 1;
17515
+ valueString = "0".repeat(Math.max(0, minLength - wholeDigits)) + valueString;
17516
+ } else {
17517
+ valueString += options.verbose ? " " + pluralize(long, value) : short;
17518
+ }
17519
+ result.push(valueString);
17520
+ };
17521
+ const parsed = parseMilliseconds(milliseconds);
17522
+ const days = BigInt(parsed.days);
17523
+ add2(days / 365n, "year", "y");
17524
+ add2(days % 365n, "day", "d");
17525
+ add2(Number(parsed.hours), "hour", "h");
17526
+ add2(Number(parsed.minutes), "minute", "m");
17527
+ if (options.separateMilliseconds || options.formatSubMilliseconds || !options.colonNotation && milliseconds < 1e3) {
17528
+ const seconds = Number(parsed.seconds);
17529
+ const milliseconds2 = Number(parsed.milliseconds);
17530
+ const microseconds = Number(parsed.microseconds);
17531
+ const nanoseconds = Number(parsed.nanoseconds);
17532
+ add2(seconds, "second", "s");
17533
+ if (options.formatSubMilliseconds) {
17534
+ add2(milliseconds2, "millisecond", "ms");
17535
+ add2(microseconds, "microsecond", "\xB5s");
17536
+ add2(nanoseconds, "nanosecond", "ns");
17537
+ } else {
17538
+ const millisecondsAndBelow = milliseconds2 + microseconds / 1e3 + nanoseconds / 1e6;
17539
+ const millisecondsDecimalDigits = typeof options.millisecondsDecimalDigits === "number" ? options.millisecondsDecimalDigits : 0;
17540
+ const roundedMilliseconds = millisecondsAndBelow >= 1 ? Math.round(millisecondsAndBelow) : Math.ceil(millisecondsAndBelow);
17541
+ const millisecondsString = millisecondsDecimalDigits ? millisecondsAndBelow.toFixed(millisecondsDecimalDigits) : roundedMilliseconds;
17542
+ add2(
17543
+ Number.parseFloat(millisecondsString),
17544
+ "millisecond",
17545
+ "ms",
17546
+ millisecondsString
17547
+ );
17548
+ }
17549
+ } else {
17550
+ const seconds = (isBigInt ? Number(milliseconds % ONE_DAY_IN_MILLISECONDS) : milliseconds) / 1e3 % 60;
17551
+ const secondsDecimalDigits = typeof options.secondsDecimalDigits === "number" ? options.secondsDecimalDigits : 1;
17552
+ const secondsFixed = floorDecimals(seconds, secondsDecimalDigits);
17553
+ const secondsString = options.keepDecimalsOnWholeSeconds ? secondsFixed : secondsFixed.replace(/\.0+$/, "");
17554
+ add2(Number.parseFloat(secondsString), "second", "s", secondsString);
17555
+ }
17556
+ if (result.length === 0) {
17557
+ return "0" + (options.verbose ? " milliseconds" : "ms");
17558
+ }
17559
+ const separator = options.colonNotation ? ":" : " ";
17560
+ if (typeof options.unitCount === "number") {
17561
+ result = result.slice(0, Math.max(options.unitCount, 1));
17562
+ }
17563
+ return result.join(separator);
17564
+ }
17565
+
17566
+ // src/lib/tldraw-to-image.ts
16749
17567
  var defaultOptions2 = {
16750
17568
  darkMode: false,
16751
17569
  format: "svg",
@@ -16758,36 +17576,36 @@ var defaultOptions2 = {
16758
17576
  verbose: false
16759
17577
  };
16760
17578
  async function tldrawToImage(tldrPathOrUrl, options) {
17579
+ const resolvedOptions = {
17580
+ ...defaultOptions2,
17581
+ ...stripUndefined(options ?? {})
17582
+ };
17583
+ const { darkMode, format: format3, frames, name, output, print, stripStyle, transparent, verbose: verbose2 } = resolvedOptions;
17584
+ const initialVerbosity = verbose;
17585
+ setVerbose(verbose2);
16761
17586
  if (options?.print && options.output !== void 0) {
16762
17587
  throw new Error("Cannot use --output with --print");
16763
17588
  }
16764
17589
  if (options?.print && options.name !== void 0) {
16765
- console.warn("Ignoring --name when using --print");
17590
+ warn("Ignoring --name when using --print");
16766
17591
  }
16767
- const resolvedOptions = {
16768
- ...defaultOptions2,
16769
- ...stripUndefined(options ?? {})
16770
- };
16771
- const { darkMode, format: format3, frames, name, output, print, stripStyle, transparent, verbose } = resolvedOptions;
16772
- if (verbose)
16773
- console.time("Export time");
17592
+ const startTime = performance.now();
16774
17593
  const validatedPathOrUrl = validatePathOrUrl(tldrPathOrUrl, {
16775
17594
  requireFileExistence: true,
16776
17595
  validFileExtensions: [".tldr"],
16777
17596
  validHostnames: ["www.tldraw.com"]
16778
17597
  });
16779
17598
  const isLocal = typeof validatedPathOrUrl === "string";
16780
- if (verbose)
16781
- console.log(isLocal ? "Local file detected" : "tldraw URL detected");
17599
+ info(isLocal ? "Local file detected" : "tldraw URL detected");
16782
17600
  const outputFilename = name === void 0 ? isLocal ? path4.basename(validatedPathOrUrl, path4.extname(validatedPathOrUrl)) : validatedPathOrUrl.pathname.split("/").pop() ?? validatedPathOrUrl.pathname : sanitizeName(name, format3);
16783
- if (isLocal && verbose)
16784
- console.log(`Loading tldr data "${validatedPathOrUrl}"`);
17601
+ if (isLocal)
17602
+ info(`Loading tldr data "${validatedPathOrUrl}"`);
16785
17603
  const tldrData = isLocal ? await fs3.readFile(validatedPathOrUrl, "utf8") : void 0;
16786
- const tldrawServer = new LocalTldrawServer(tldrData, verbose);
17604
+ const tldrawServer = new LocalTldrawServer(tldrData);
16787
17605
  if (isLocal)
16788
17606
  await tldrawServer.start();
16789
17607
  const tldrawUrl = isLocal ? tldrawServer.href : validatedPathOrUrl.href;
16790
- const tldrawController = new TldrawController(tldrawUrl, verbose);
17608
+ const tldrawController = new TldrawController(tldrawUrl);
16791
17609
  await tldrawController.start();
16792
17610
  await tldrawController.setTransparency(transparent);
16793
17611
  await tldrawController.setDarkMode(darkMode);
@@ -16821,8 +17639,8 @@ async function tldrawToImage(tldrPathOrUrl, options) {
16821
17639
  await tldrawController.close();
16822
17640
  if (isLocal)
16823
17641
  tldrawServer.close();
16824
- if (verbose)
16825
- console.timeEnd("Export time");
17642
+ info(`Export time: ${prettyMilliseconds(performance.now() - startTime)}`);
17643
+ setVerbose(initialVerbosity);
16826
17644
  return exportReport;
16827
17645
  }
16828
17646
  function stripUndefined(options) {
@@ -16868,10 +17686,10 @@ function nanoid(size = 21) {
16868
17686
 
16869
17687
  // src/lib/tldraw-open.ts
16870
17688
  import fs8 from "node:fs/promises";
16871
- import os5 from "node:os";
17689
+ import os6 from "node:os";
16872
17690
 
16873
17691
  // node_modules/.pnpm/open@10.0.3/node_modules/open/index.js
16874
- import process6 from "node:process";
17692
+ import process7 from "node:process";
16875
17693
  import { Buffer as Buffer2 } from "node:buffer";
16876
17694
  import path5 from "node:path";
16877
17695
  import { fileURLToPath as fileURLToPath3 } from "node:url";
@@ -16879,8 +17697,8 @@ import childProcess from "node:child_process";
16879
17697
  import fs7, { constants as fsConstants } from "node:fs/promises";
16880
17698
 
16881
17699
  // node_modules/.pnpm/is-wsl@3.1.0/node_modules/is-wsl/index.js
16882
- import process2 from "node:process";
16883
- import os4 from "node:os";
17700
+ import process3 from "node:process";
17701
+ import os5 from "node:os";
16884
17702
  import fs6 from "node:fs";
16885
17703
 
16886
17704
  // node_modules/.pnpm/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
@@ -16930,10 +17748,10 @@ function isInsideContainer() {
16930
17748
 
16931
17749
  // node_modules/.pnpm/is-wsl@3.1.0/node_modules/is-wsl/index.js
16932
17750
  var isWsl = () => {
16933
- if (process2.platform !== "linux") {
17751
+ if (process3.platform !== "linux") {
16934
17752
  return false;
16935
17753
  }
16936
- if (os4.release().toLowerCase().includes("microsoft")) {
17754
+ if (os5.release().toLowerCase().includes("microsoft")) {
16937
17755
  if (isInsideContainer()) {
16938
17756
  return false;
16939
17757
  }
@@ -16945,7 +17763,7 @@ var isWsl = () => {
16945
17763
  return false;
16946
17764
  }
16947
17765
  };
16948
- var is_wsl_default = process2.env.__IS_WSL_TEST__ ? isWsl : isWsl();
17766
+ var is_wsl_default = process3.env.__IS_WSL_TEST__ ? isWsl : isWsl();
16949
17767
 
16950
17768
  // node_modules/.pnpm/define-lazy-prop@3.0.0/node_modules/define-lazy-prop/index.js
16951
17769
  function defineLazyProperty(object, propertyName, valueGetter) {
@@ -16967,16 +17785,16 @@ function defineLazyProperty(object, propertyName, valueGetter) {
16967
17785
 
16968
17786
  // node_modules/.pnpm/default-browser@5.2.1/node_modules/default-browser/index.js
16969
17787
  import { promisify as promisify4 } from "node:util";
16970
- import process5 from "node:process";
17788
+ import process6 from "node:process";
16971
17789
  import { execFile as execFile4 } from "node:child_process";
16972
17790
 
16973
17791
  // node_modules/.pnpm/default-browser-id@5.0.0/node_modules/default-browser-id/index.js
16974
17792
  import { promisify } from "node:util";
16975
- import process3 from "node:process";
17793
+ import process4 from "node:process";
16976
17794
  import { execFile } from "node:child_process";
16977
17795
  var execFileAsync = promisify(execFile);
16978
17796
  async function defaultBrowserId() {
16979
- if (process3.platform !== "darwin") {
17797
+ if (process4.platform !== "darwin") {
16980
17798
  throw new Error("macOS only");
16981
17799
  }
16982
17800
  const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
@@ -16985,12 +17803,12 @@ async function defaultBrowserId() {
16985
17803
  }
16986
17804
 
16987
17805
  // node_modules/.pnpm/run-applescript@7.0.0/node_modules/run-applescript/index.js
16988
- import process4 from "node:process";
17806
+ import process5 from "node:process";
16989
17807
  import { promisify as promisify2 } from "node:util";
16990
17808
  import { execFile as execFile2, execFileSync } from "node:child_process";
16991
17809
  var execFileAsync2 = promisify2(execFile2);
16992
17810
  async function runAppleScript(script, { humanReadableOutput = true } = {}) {
16993
- if (process4.platform !== "darwin") {
17811
+ if (process5.platform !== "darwin") {
16994
17812
  throw new Error("macOS only");
16995
17813
  }
16996
17814
  const outputArguments = humanReadableOutput ? [] : ["-ss"];
@@ -17046,18 +17864,18 @@ async function defaultBrowser(_execFileAsync = execFileAsync3) {
17046
17864
  var execFileAsync4 = promisify4(execFile4);
17047
17865
  var titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
17048
17866
  async function defaultBrowser2() {
17049
- if (process5.platform === "darwin") {
17867
+ if (process6.platform === "darwin") {
17050
17868
  const id = await defaultBrowserId();
17051
17869
  const name = await bundleName(id);
17052
17870
  return { name, id };
17053
17871
  }
17054
- if (process5.platform === "linux") {
17872
+ if (process6.platform === "linux") {
17055
17873
  const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
17056
17874
  const id = stdout.trim();
17057
17875
  const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
17058
17876
  return { name, id };
17059
17877
  }
17060
- if (process5.platform === "win32") {
17878
+ if (process6.platform === "win32") {
17061
17879
  return defaultBrowser();
17062
17880
  }
17063
17881
  throw new Error("Only macOS, Linux, and Windows are supported");
@@ -17066,7 +17884,7 @@ async function defaultBrowser2() {
17066
17884
  // node_modules/.pnpm/open@10.0.3/node_modules/open/index.js
17067
17885
  var __dirname = path5.dirname(fileURLToPath3(import.meta.url));
17068
17886
  var localXdgOpenPath = path5.join(__dirname, "xdg-open");
17069
- var { platform, arch } = process6;
17887
+ var { platform, arch } = process7;
17070
17888
  var getWslDrivesMountPoint = /* @__PURE__ */ (() => {
17071
17889
  const defaultMountPoint = "/mnt/";
17072
17890
  let mountPoint;
@@ -17099,8 +17917,8 @@ var pTryEach = async (array, mapper) => {
17099
17917
  for (const item of array) {
17100
17918
  try {
17101
17919
  return await mapper(item);
17102
- } catch (error) {
17103
- latestError = error;
17920
+ } catch (error2) {
17921
+ latestError = error2;
17104
17922
  }
17105
17923
  }
17106
17924
  throw latestError;
@@ -17180,7 +17998,7 @@ var baseOpen = async (options) => {
17180
17998
  }
17181
17999
  } else if (platform === "win32" || is_wsl_default && !isInsideContainer() && !app) {
17182
18000
  const mountPoint = await getWslDrivesMountPoint();
17183
- command2 = is_wsl_default ? `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe` : `${process6.env.SYSTEMROOT || process6.env.windir || "C:\\Windows"}\\System32\\WindowsPowerShell\\v1.0\\powershell`;
18001
+ command2 = is_wsl_default ? `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe` : `${process7.env.SYSTEMROOT || process7.env.windir || "C:\\Windows"}\\System32\\WindowsPowerShell\\v1.0\\powershell`;
17184
18002
  cliArguments.push(
17185
18003
  "-NoProfile",
17186
18004
  "-NonInteractive",
@@ -17219,7 +18037,7 @@ var baseOpen = async (options) => {
17219
18037
  exeLocalXdgOpen = true;
17220
18038
  } catch {
17221
18039
  }
17222
- const useSystemXdgOpen = process6.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
18040
+ const useSystemXdgOpen = process7.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
17223
18041
  command2 = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
17224
18042
  }
17225
18043
  if (appArguments.length > 0) {
@@ -17322,7 +18140,7 @@ async function tldrawOpen(tldrPathOrUrl) {
17322
18140
  const [savedFile] = await tldrawToImage(validatedPathOrUrl.href, {
17323
18141
  format: "tldr",
17324
18142
  name: nanoid(),
17325
- output: os5.tmpdir()
18143
+ output: os6.tmpdir()
17326
18144
  });
17327
18145
  const href = await tldrawOpen(savedFile);
17328
18146
  await fs8.rm(savedFile, { force: true });
@@ -17332,10 +18150,41 @@ async function tldrawOpen(tldrPathOrUrl) {
17332
18150
  }
17333
18151
  const tldrawServer = new LocalTldrawServer(tldrData);
17334
18152
  await tldrawServer.start();
17335
- await open_default(tldrawServer.href);
18153
+ if (tldrPathOrUrl === void 0) {
18154
+ log(`Opened empty tldraw sketch at ${tldrawServer.href}`);
18155
+ } else {
18156
+ log(`Opened tldraw sketch "${tldrPathOrUrl}" at ${tldrawServer.href}`);
18157
+ }
18158
+ await open_default(tldrawServer.href, { wait: true });
17336
18159
  return tldrawServer.href;
17337
18160
  }
17338
18161
 
18162
+ // node_modules/.pnpm/plur@5.1.0/node_modules/plur/index.js
18163
+ var import_irregular_plurals = __toESM(require_irregular_plurals2(), 1);
18164
+ function plur(word, plural, count) {
18165
+ if (typeof plural === "number") {
18166
+ count = plural;
18167
+ }
18168
+ if (import_irregular_plurals.default.has(word.toLowerCase())) {
18169
+ plural = import_irregular_plurals.default.get(word.toLowerCase());
18170
+ const firstLetter = word.charAt(0);
18171
+ const isFirstLetterUpperCase = firstLetter === firstLetter.toUpperCase();
18172
+ if (isFirstLetterUpperCase) {
18173
+ plural = firstLetter + plural.slice(1);
18174
+ }
18175
+ const isWholeWordUpperCase = word === word.toUpperCase();
18176
+ if (isWholeWordUpperCase) {
18177
+ plural = plural.toUpperCase();
18178
+ }
18179
+ } else if (typeof plural !== "string") {
18180
+ plural = (word.replace(/(?:s|x|z|ch|sh)$/i, "$&e").replace(/([^aeiou])y$/i, "$1ie") + "s").replace(/i?e?s$/i, (match) => {
18181
+ const isTailLowerCase = word.slice(-1) === word.slice(-1).toLowerCase();
18182
+ return isTailLowerCase ? match.toLowerCase() : match.toUpperCase();
18183
+ });
18184
+ }
18185
+ return Math.abs(count) === 1 ? word : plural;
18186
+ }
18187
+
17339
18188
  // node_modules/.pnpm/yargs@17.7.2/node_modules/yargs/lib/platform-shims/esm.mjs
17340
18189
  import { notStrictEqual, strictEqual } from "assert";
17341
18190
 
@@ -17893,7 +18742,7 @@ var YargsParser = class {
17893
18742
  defaults[alias] = defaults[key];
17894
18743
  });
17895
18744
  });
17896
- let error = null;
18745
+ let error2 = null;
17897
18746
  checkConfiguration();
17898
18747
  let notFlags = [];
17899
18748
  const argv = Object.assign(/* @__PURE__ */ Object.create(null), { _: [] });
@@ -18077,7 +18926,7 @@ var YargsParser = class {
18077
18926
  toEat = typeof toEat !== "number" || isNaN(toEat) ? 1 : toEat;
18078
18927
  if (toEat === 0) {
18079
18928
  if (!isUndefined(argAfterEqualSign)) {
18080
- error = Error(__("Argument unexpected for: %s", key));
18929
+ error2 = Error(__("Argument unexpected for: %s", key));
18081
18930
  }
18082
18931
  setArg(key, defaultValue(key));
18083
18932
  return i;
@@ -18085,7 +18934,7 @@ var YargsParser = class {
18085
18934
  let available = isUndefined(argAfterEqualSign) ? 0 : 1;
18086
18935
  if (configuration["nargs-eats-options"]) {
18087
18936
  if (args2.length - (i + 1) + available < toEat) {
18088
- error = Error(__("Not enough arguments following: %s", key));
18937
+ error2 = Error(__("Not enough arguments following: %s", key));
18089
18938
  }
18090
18939
  available = toEat;
18091
18940
  } else {
@@ -18096,7 +18945,7 @@ var YargsParser = class {
18096
18945
  break;
18097
18946
  }
18098
18947
  if (available < toEat)
18099
- error = Error(__("Not enough arguments following: %s", key));
18948
+ error2 = Error(__("Not enough arguments following: %s", key));
18100
18949
  }
18101
18950
  let consumed = Math.min(available, toEat);
18102
18951
  if (!isUndefined(argAfterEqualSign) && consumed > 0) {
@@ -18134,7 +18983,7 @@ var YargsParser = class {
18134
18983
  }
18135
18984
  }
18136
18985
  if (typeof nargsCount === "number" && (nargsCount && argsToSet.length < nargsCount || isNaN(nargsCount) && argsToSet.length === 0)) {
18137
- error = Error(__("Not enough arguments following: %s", key));
18986
+ error2 = Error(__("Not enough arguments following: %s", key));
18138
18987
  }
18139
18988
  setArg(key, argsToSet);
18140
18989
  return i;
@@ -18243,7 +19092,7 @@ var YargsParser = class {
18243
19092
  config = e;
18244
19093
  }
18245
19094
  if (config instanceof Error) {
18246
- error = config;
19095
+ error2 = config;
18247
19096
  return;
18248
19097
  }
18249
19098
  } else {
@@ -18252,9 +19101,9 @@ var YargsParser = class {
18252
19101
  setConfigObject(config);
18253
19102
  } catch (ex) {
18254
19103
  if (ex.name === "PermissionDenied")
18255
- error = ex;
19104
+ error2 = ex;
18256
19105
  else if (argv2[configKey])
18257
- error = Error(__("Invalid JSON config file: %s", configPath));
19106
+ error2 = Error(__("Invalid JSON config file: %s", configPath));
18258
19107
  }
18259
19108
  }
18260
19109
  });
@@ -18283,8 +19132,8 @@ var YargsParser = class {
18283
19132
  if (typeof envPrefix === "undefined")
18284
19133
  return;
18285
19134
  const prefix = typeof envPrefix === "string" ? envPrefix : "";
18286
- const env2 = mixin2.env();
18287
- Object.keys(env2).forEach(function(envVar) {
19135
+ const env3 = mixin2.env();
19136
+ Object.keys(env3).forEach(function(envVar) {
18288
19137
  if (prefix === "" || envVar.lastIndexOf(prefix, 0) === 0) {
18289
19138
  const keys = envVar.split("__").map(function(key, i) {
18290
19139
  if (i === 0) {
@@ -18293,7 +19142,7 @@ var YargsParser = class {
18293
19142
  return camelCase2(key);
18294
19143
  });
18295
19144
  if ((configOnly && flags.configs[keys.join(".")] || !configOnly) && !hasKey(argv2, keys)) {
18296
- setArg(keys.join("."), env2[envVar]);
19145
+ setArg(keys.join("."), env3[envVar]);
18297
19146
  }
18298
19147
  }
18299
19148
  });
@@ -18312,7 +19161,7 @@ var YargsParser = class {
18312
19161
  argv2[ali] = value;
18313
19162
  });
18314
19163
  } catch (err) {
18315
- error = err;
19164
+ error2 = err;
18316
19165
  }
18317
19166
  }
18318
19167
  }
@@ -18525,10 +19374,10 @@ var YargsParser = class {
18525
19374
  function checkConfiguration() {
18526
19375
  Object.keys(flags.counts).find((key) => {
18527
19376
  if (checkAllAliases(key, flags.arrays)) {
18528
- error = Error(__("Invalid configuration: %s, opts.count excludes opts.array.", key));
19377
+ error2 = Error(__("Invalid configuration: %s, opts.count excludes opts.array.", key));
18529
19378
  return true;
18530
19379
  } else if (checkAllAliases(key, flags.nargs)) {
18531
- error = Error(__("Invalid configuration: %s, opts.count excludes opts.narg.", key));
19380
+ error2 = Error(__("Invalid configuration: %s, opts.count excludes opts.narg.", key));
18532
19381
  return true;
18533
19382
  }
18534
19383
  return false;
@@ -18539,7 +19388,7 @@ var YargsParser = class {
18539
19388
  argv: Object.assign(argvReturn, argv),
18540
19389
  configuration,
18541
19390
  defaulted: Object.assign({}, defaulted),
18542
- error,
19391
+ error: error2,
18543
19392
  newAliases: Object.assign({}, newAliases)
18544
19393
  };
18545
19394
  }
@@ -18603,11 +19452,11 @@ if (nodeVersion) {
18603
19452
  throw Error(`yargs parser supports a minimum Node.js version of ${minNodeVersion}. Read our version support policy: https://github.com/yargs/yargs-parser#supported-nodejs-versions`);
18604
19453
  }
18605
19454
  }
18606
- var env = process ? process.env : {};
19455
+ var env2 = process ? process.env : {};
18607
19456
  var parser = new YargsParser({
18608
19457
  cwd: process.cwd,
18609
19458
  env: () => {
18610
- return env;
19459
+ return env2;
18611
19460
  },
18612
19461
  format,
18613
19462
  normalize,
@@ -19314,9 +20163,9 @@ var CommandInstance = class {
19314
20163
  yargs.getInternalMethods().getUsageInstance().cacheHelpMessage();
19315
20164
  }
19316
20165
  if (isPromise(innerArgv) && !yargs.getInternalMethods().hasParseCallback()) {
19317
- innerArgv.catch((error) => {
20166
+ innerArgv.catch((error2) => {
19318
20167
  try {
19319
- yargs.getInternalMethods().getUsageInstance().fail(null, error);
20168
+ yargs.getInternalMethods().getUsageInstance().fail(null, error2);
19320
20169
  } catch (_err) {
19321
20170
  }
19322
20171
  });
@@ -22193,24 +23042,13 @@ var Yargs = YargsFactory(esm_default3);
22193
23042
  var yargs_default = Yargs;
22194
23043
 
22195
23044
  // src/cli/tldraw-cli.ts
23045
+ setCli(true);
22196
23046
  await yargs_default(hideBin(process.argv)).scriptName("tldraw-cli").command("$0 <command>", "CLI tools for tldraw.").command(
22197
- "open [file-or-url]",
22198
- 'Open a tldraw ".tldr" file or tldraw.com URL your default browser. Uses a locally-hosted instance of tldraw. Call open without an argument to open a blank sketch.',
22199
- (yargs) => yargs.positional("file-or-url", {
22200
- describe: "The .tldr file or tldraw.com sketch url to open. Omit to open a blank sketch. Prints the url of the local server to stdout.",
22201
- type: "string"
22202
- }),
22203
- async (argv) => {
22204
- const { fileOrUrl } = argv;
22205
- const localUrl = await tldrawOpen(fileOrUrl);
22206
- console.log(localUrl);
22207
- }
22208
- ).command(
22209
- "export <file-or-url>",
23047
+ "export <files-or-urls..>",
22210
23048
  'Export a local tldraw ".tldr" file or a tldraw.com URL to an svg, png, json, or tldr file. Prints the absolute path(s) to the exported image(s) to stdout.',
22211
- (yargs) => yargs.positional("file-or-url", {
23049
+ (yargs) => yargs.positional("files-or-urls", {
22212
23050
  demandOption: true,
22213
- describe: 'The sketch to export to an image \u2014 either a path to a local ".tldr" file, or a tldraw.com sketch URL',
23051
+ describe: "The tldraw sketch to export. May be one or more paths to local `.tldr` files, or tldraw.com sketch URLs. Accepts a mix of both file paths and URLs, and supports glob matching via your shell. Prints the absolute path(s) to the exported image(s) to `stdout`.",
22214
23052
  type: "string"
22215
23053
  }).option("format", {
22216
23054
  alias: "f",
@@ -22226,19 +23064,9 @@ await yargs_default(hideBin(process.argv)).scriptName("tldraw-cli").command("$0
22226
23064
  type: "string"
22227
23065
  }).option("name", {
22228
23066
  alias: "n",
22229
- defaultDescription: "The original file name or URL id is used",
22230
- describe: "Output image name",
23067
+ defaultDescription: "The original file name or URL id is used.",
23068
+ describe: "Output image name (without extension).",
22231
23069
  type: "string"
22232
- }).option("transparent", {
22233
- alias: "t",
22234
- default: false,
22235
- describe: "Output an image with a transparent background.",
22236
- type: "boolean"
22237
- }).option("dark-mode", {
22238
- alias: "d",
22239
- default: false,
22240
- describe: "Output a dark theme version of the image.",
22241
- type: "boolean"
22242
23070
  }).option("frames", {
22243
23071
  coerce(args) {
22244
23072
  return args.length === 0 ? true : args;
@@ -22247,20 +23075,30 @@ await yargs_default(hideBin(process.argv)).scriptName("tldraw-cli").command("$0
22247
23075
  // value to true, and still be able to extract meaning from the
22248
23076
  // absence of the option
22249
23077
  defaultDescription: "false",
22250
- describe: 'Export each sketch "frame" as a separate image, use the option flag alone to export all frames, or pass one or more frame names or IDs.',
23078
+ describe: 'Export each sketch "frame" as a separate image. Pass one or more frame names or IDs to export specific frames, or skip the arguments to export all frames.',
22251
23079
  type: "array"
23080
+ }).option("transparent", {
23081
+ alias: "t",
23082
+ default: false,
23083
+ describe: "Export an image with a transparent background.",
23084
+ type: "boolean"
23085
+ }).option("dark-mode", {
23086
+ alias: "d",
23087
+ default: false,
23088
+ describe: "Export a dark theme version of the image.",
23089
+ type: "boolean"
22252
23090
  }).option("strip-style", {
22253
23091
  default: false,
22254
- describe: "Remove all style tags from the SVG output. Applies to SVG output only.",
23092
+ describe: "Remove `<style>` elements from SVG output, useful to lighten the load of embedded fonts if you intend to provide your own stylesheets. Applies to SVG output only.",
22255
23093
  type: "boolean"
22256
23094
  }).option("print", {
22257
23095
  alias: "p",
22258
23096
  default: false,
22259
- describe: "Print the exported image(s) to stdout instead of saving to a file. Incompatible with --output, and overrides --name. PNGs are printed as base64-encoded strings.",
23097
+ describe: "Print the exported image(s) to stdout instead of saving to a file. Incompatible with `--output`, and overrides `--name`. PNGs are printed as base64-encoded strings.",
22260
23098
  type: "boolean"
22261
23099
  }).option("verbose", {
22262
23100
  default: false,
22263
- describe: "Enable verbose output",
23101
+ describe: "Enable verbose logging. All verbose logs and prefixed with their log level and are printed to `stderr` for ease of redirection.",
22264
23102
  type: "boolean"
22265
23103
  }).check((argv) => {
22266
23104
  if (argv.print && argv.output !== void 0) {
@@ -22271,7 +23109,7 @@ await yargs_default(hideBin(process.argv)).scriptName("tldraw-cli").command("$0
22271
23109
  async (argv) => {
22272
23110
  const {
22273
23111
  darkMode,
22274
- fileOrUrl,
23112
+ filesOrUrls,
22275
23113
  format: format3,
22276
23114
  frames,
22277
23115
  name,
@@ -22279,25 +23117,91 @@ await yargs_default(hideBin(process.argv)).scriptName("tldraw-cli").command("$0
22279
23117
  print,
22280
23118
  stripStyle,
22281
23119
  transparent,
22282
- verbose
23120
+ verbose: verbose2
22283
23121
  } = argv;
22284
- try {
22285
- const exportList = await tldrawToImage(fileOrUrl, {
22286
- darkMode,
22287
- format: format3,
22288
- // CLI never returns false, but the function accepts it for stand-alone use
22289
- frames,
22290
- name,
22291
- output,
22292
- print,
22293
- stripStyle,
22294
- transparent,
22295
- verbose
22296
- });
22297
- console.log(exportList.join("\n"));
23122
+ setVerbose(verbose2);
23123
+ info(`Exporting ${filesOrUrls.length} ${plur("sketch", filesOrUrls.length)}...`);
23124
+ let nameIndex = 0;
23125
+ const errorReport = [];
23126
+ for (const fileOrUrl of filesOrUrls) {
23127
+ try {
23128
+ const resolvedName = filesOrUrls.length > 1 && name !== void 0 ? `${name}-${nameIndex++}` : name;
23129
+ const exportList = await tldrawToImage(fileOrUrl, {
23130
+ darkMode,
23131
+ format: format3,
23132
+ // CLI never returns false, but the function accepts it for stand-alone use
23133
+ frames,
23134
+ name: resolvedName,
23135
+ output,
23136
+ print,
23137
+ stripStyle,
23138
+ transparent,
23139
+ verbose: verbose2
23140
+ });
23141
+ log(exportList.join("\n"));
23142
+ } catch (error2) {
23143
+ if (error2 instanceof Error) {
23144
+ errorReport.push(`Failed to export "${fileOrUrl}": ${error2.message}`);
23145
+ }
23146
+ }
23147
+ }
23148
+ const successCount = filesOrUrls.length - errorReport.length;
23149
+ if (errorReport.length > 0) {
23150
+ error(
23151
+ `${successCount} of ${filesOrUrls.length} ${plur("sketch", filesOrUrls.length)} exported successfully`
23152
+ );
23153
+ error(errorReport.join("\n"));
23154
+ process.exit(1);
23155
+ }
23156
+ if (successCount === 0) {
23157
+ error(
23158
+ `${successCount} of ${filesOrUrls.length} ${plur("sketch", filesOrUrls.length)} exported successfully`
23159
+ );
23160
+ } else {
23161
+ info(
23162
+ `All ${successCount} ${plur("sketch", filesOrUrls.length)} exported successfully`
23163
+ );
23164
+ }
23165
+ process.exit(0);
23166
+ }
23167
+ ).command(
23168
+ "open [files-or-urls..]",
23169
+ "Open a tldraw `.tldr` file or tldraw.com URL your default browser. Uses a locally-hosted instance of tldraw. Call `open` without an argument to open a blank sketch. Sketches opened via URL are temporarily copied to the local system, and will not be kept in sync with tldraw.com.",
23170
+ (yargs) => yargs.positional("files-or-urls", {
23171
+ describe: "The `.tldr` file(s) or tldraw.com sketch URL(s) to open. Omit the argument to open a blank sketch. Supports glob matching via your shell. Prints the URL of the local server to `stdout`.",
23172
+ type: "string"
23173
+ }),
23174
+ async (argv) => {
23175
+ const { filesOrUrls } = argv;
23176
+ const resultPromises = [];
23177
+ let errorCount = 0;
23178
+ if (filesOrUrls === void 0 || filesOrUrls.length === 0) {
23179
+ try {
23180
+ resultPromises.push(tldrawOpen());
23181
+ } catch (error2) {
23182
+ errorCount++;
23183
+ if (error2 instanceof Error) {
23184
+ error(`Failed to open:": ${error2.message}`);
23185
+ }
23186
+ }
23187
+ } else {
23188
+ for (const fileOrUrl of filesOrUrls) {
23189
+ try {
23190
+ resultPromises.push(tldrawOpen(fileOrUrl));
23191
+ } catch (error2) {
23192
+ errorCount++;
23193
+ if (error2 instanceof Error) {
23194
+ error(`Failed to open "${fileOrUrl}": ${error2.message}`);
23195
+ }
23196
+ }
23197
+ }
23198
+ }
23199
+ log(source_default.yellow(`Note: This process will exit once the browser is closed.`));
23200
+ await Promise.all(resultPromises);
23201
+ log(`Closing local tldraw ${plur("server", filesOrUrls ? filesOrUrls.length : 1)}`);
23202
+ if (errorCount === 0) {
22298
23203
  process.exit(0);
22299
- } catch (error) {
22300
- console.error("Export failed:", error);
23204
+ } else {
22301
23205
  process.exit(1);
22302
23206
  }
22303
23207
  }