@kitschpatrol/tldraw-cli 3.0.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 = "2.2.3";
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,27 +17169,25 @@ 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
- async download(output, filename, format3, stripStyle) {
16486
- return this._download(output, filename, format3, stripStyle);
17179
+ async download(output, filename, format3, stripStyle, print) {
17180
+ return this._download(output, filename, format3, stripStyle, void 0, print);
16487
17181
  }
16488
- async downloadFrame(output, filename, format3, stripStyle, frameNameOrId) {
16489
- return this.downloadFrames(output, filename, format3, stripStyle, [frameNameOrId]);
17182
+ async downloadFrame(output, filename, format3, stripStyle, frameNameOrId, print) {
17183
+ return this.downloadFrames(output, filename, format3, stripStyle, [frameNameOrId], print);
16490
17184
  }
16491
- async downloadFrames(output, filename, format3, stripStyle, frameNamesOrIds) {
17185
+ async downloadFrames(output, filename, format3, stripStyle, frameNamesOrIds, print) {
16492
17186
  const validPageFrames = [];
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
  }
@@ -16512,22 +17206,28 @@ var TldrawController = class {
16512
17206
  for (const frame of validPageFrames) {
16513
17207
  const frameSuffix = isFrameNameCollision ? `-${frame.id.replace("shape:", "")}` : "";
16514
17208
  outputAccumulator.push(
16515
- ...await this._download(output, `${filename}${frameSuffix}`, format3, stripStyle, frame)
17209
+ ...await this._download(
17210
+ output,
17211
+ `${filename}${frameSuffix}`,
17212
+ format3,
17213
+ stripStyle,
17214
+ frame,
17215
+ print
17216
+ )
16516
17217
  );
16517
17218
  }
16518
17219
  return outputAccumulator;
16519
17220
  }
16520
- async downloadAllFrames(output, filename, format3, stripStyle) {
17221
+ async downloadAllFrames(output, filename, format3, stripStyle, print) {
16521
17222
  const pageFrames = await this.getPageFrames();
16522
17223
  const frameNamesOrIds = pageFrames.map((f) => f.id);
16523
- return this.downloadFrames(output, filename, format3, stripStyle, frameNamesOrIds);
17224
+ return this.downloadFrames(output, filename, format3, stripStyle, frameNamesOrIds, print);
16524
17225
  }
16525
17226
  // Ephemeral means we don't have to restore the user's value
16526
17227
  async setTransparency(transparent) {
16527
17228
  if (!this.page)
16528
17229
  throw new Error("Controller not started");
16529
- if (this.verbose)
16530
- console.log(`Setting background transparency: ${transparent}`);
17230
+ info(`Setting background transparency: ${transparent}`);
16531
17231
  await this.page.evaluate(
16532
17232
  `editor.updateInstanceState(
16533
17233
  { exportBackground: ${!transparent} },
@@ -16538,34 +17238,29 @@ var TldrawController = class {
16538
17238
  async setDarkMode(darkMode) {
16539
17239
  if (!this.page)
16540
17240
  throw new Error("Controller not started");
16541
- if (this.verbose)
16542
- console.log(`Setting dark mode: ${darkMode}`);
17241
+ info(`Setting dark mode: ${darkMode}`);
16543
17242
  if (!this.originalDarkMode)
16544
17243
  this.originalDarkMode = await this.getDarkMode();
16545
17244
  await this.page.evaluate(`editor.user.updateUserPreferences({ isDarkMode: ${darkMode}})`);
16546
17245
  }
16547
17246
  // eslint-disable-next-line @typescript-eslint/naming-convention
16548
- async _download(output, filename, format3, stripStyle, pageFrame) {
17247
+ async _download(output, filename, format3, stripStyle, pageFrame, print) {
16549
17248
  if (!this.page)
16550
17249
  throw new Error("Controller not started");
16551
17250
  if (this.isEmpty) {
16552
17251
  throw new Error("Cannot export an empty document");
16553
17252
  }
16554
17253
  if (stripStyle && format3 !== "svg") {
16555
- console.warn("Warning: --strip-style is only supported for SVG output");
17254
+ warn("--strip-style is only supported for SVG output");
16556
17255
  }
16557
17256
  if (pageFrame !== void 0 && format3 === "tldr") {
16558
- console.warn(
16559
- "Warning: --frames is not supported for tldr output, downloading entire document"
16560
- );
17257
+ warn("--frames is not supported for tldr output, downloading entire document");
16561
17258
  }
16562
17259
  const completionPromise = this.waitForDownloadCompletion();
16563
17260
  await this.closeMenus();
16564
17261
  let frameSuffix = "";
16565
17262
  if (pageFrame !== void 0 && format3 !== "tldr") {
16566
- if (this.verbose) {
16567
- console.log(`Selecting sketch frame "${pageFrame.name}" with ID "${pageFrame.id}"`);
16568
- }
17263
+ info(`Selecting sketch frame "${pageFrame.name}" with ID "${pageFrame.id}"`);
16569
17264
  frameSuffix = `-${slugify(pageFrame.name)}`;
16570
17265
  await this.page.evaluate("editor.selectNone()");
16571
17266
  await this.page.evaluate(`editor.select('${pageFrame.id}')`);
@@ -16585,16 +17280,25 @@ var TldrawController = class {
16585
17280
  }
16586
17281
  const downloadGuid = await completionPromise;
16587
17282
  await this.page.waitForNetworkIdle();
16588
- const downloadPath = path2.join(os3.tmpdir(), downloadGuid);
16589
- const outputPath = path2.resolve(
16590
- untildify(path2.join(output, `${filename}${frameSuffix}.${format3}`))
16591
- );
16592
- await fs.rename(downloadPath, outputPath);
17283
+ const downloadPath = path2.join(os4.tmpdir(), downloadGuid);
17284
+ const outputPath = print ? downloadPath : path2.resolve(untildify(path2.join(output, `${filename}${frameSuffix}.${format3}`)));
17285
+ if (!print)
17286
+ await fs.rename(downloadPath, outputPath);
16593
17287
  if (stripStyle && format3 === "svg") {
16594
17288
  const svg = await fs.readFile(outputPath, "utf8");
16595
17289
  const strippedSvg = this.stripStyleElement(svg);
16596
17290
  await fs.writeFile(outputPath, strippedSvg);
16597
17291
  }
17292
+ if (print) {
17293
+ if (format3 === "png") {
17294
+ const buffer = await fs.readFile(outputPath);
17295
+ const outputBase64 = buffer.toString("base64");
17296
+ return [outputBase64];
17297
+ }
17298
+ const outputString = await fs.readFile(outputPath, "utf8");
17299
+ const outputStringNoNewlines = outputString.replaceAll("\n", "");
17300
+ return [outputStringNoNewlines];
17301
+ }
16598
17302
  return [outputPath];
16599
17303
  }
16600
17304
  async closeMenus() {
@@ -16675,11 +17379,11 @@ async function isType(fsStatType, statsMethodName, filePath) {
16675
17379
  try {
16676
17380
  const stats = await fsPromises[fsStatType](filePath);
16677
17381
  return stats[statsMethodName]();
16678
- } catch (error) {
16679
- if (error.code === "ENOENT") {
17382
+ } catch (error2) {
17383
+ if (error2.code === "ENOENT") {
16680
17384
  return false;
16681
17385
  }
16682
- throw error;
17386
+ throw error2;
16683
17387
  }
16684
17388
  }
16685
17389
  function isTypeSync(fsStatType, statsMethodName, filePath) {
@@ -16688,11 +17392,11 @@ function isTypeSync(fsStatType, statsMethodName, filePath) {
16688
17392
  }
16689
17393
  try {
16690
17394
  return fs2[fsStatType](filePath)[statsMethodName]();
16691
- } catch (error) {
16692
- if (error.code === "ENOENT") {
17395
+ } catch (error2) {
17396
+ if (error2.code === "ENOENT") {
16693
17397
  return false;
16694
17398
  }
16695
- throw error;
17399
+ throw error2;
16696
17400
  }
16697
17401
  }
16698
17402
  var isFile = isType.bind(null, "stat", "isFile");
@@ -16732,12 +17436,141 @@ function validatePathOrUrl(pathOrUrl, options = {}) {
16732
17436
  // src/lib/tldraw-to-image.ts
16733
17437
  import fs3 from "node:fs/promises";
16734
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
16735
17567
  var defaultOptions2 = {
16736
17568
  darkMode: false,
16737
17569
  format: "svg",
16738
17570
  frames: false,
16739
17571
  name: void 0,
16740
17572
  output: "./",
17573
+ print: false,
16741
17574
  stripStyle: false,
16742
17575
  transparent: false,
16743
17576
  verbose: false
@@ -16747,26 +17580,32 @@ async function tldrawToImage(tldrPathOrUrl, options) {
16747
17580
  ...defaultOptions2,
16748
17581
  ...stripUndefined(options ?? {})
16749
17582
  };
16750
- const { darkMode, format: format3, frames, name, output, stripStyle, transparent, verbose } = resolvedOptions;
16751
- if (verbose)
16752
- console.time("Export time");
17583
+ const { darkMode, format: format3, frames, name, output, print, stripStyle, transparent, verbose: verbose2 } = resolvedOptions;
17584
+ const initialVerbosity = verbose;
17585
+ setVerbose(verbose2);
17586
+ if (options?.print && options.output !== void 0) {
17587
+ throw new Error("Cannot use --output with --print");
17588
+ }
17589
+ if (options?.print && options.name !== void 0) {
17590
+ warn("Ignoring --name when using --print");
17591
+ }
17592
+ const startTime = performance.now();
16753
17593
  const validatedPathOrUrl = validatePathOrUrl(tldrPathOrUrl, {
16754
17594
  requireFileExistence: true,
16755
17595
  validFileExtensions: [".tldr"],
16756
17596
  validHostnames: ["www.tldraw.com"]
16757
17597
  });
16758
17598
  const isLocal = typeof validatedPathOrUrl === "string";
16759
- if (verbose)
16760
- console.log(isLocal ? "Local file detected" : "tldraw URL detected");
17599
+ info(isLocal ? "Local file detected" : "tldraw URL detected");
16761
17600
  const outputFilename = name === void 0 ? isLocal ? path4.basename(validatedPathOrUrl, path4.extname(validatedPathOrUrl)) : validatedPathOrUrl.pathname.split("/").pop() ?? validatedPathOrUrl.pathname : sanitizeName(name, format3);
16762
- if (isLocal && verbose)
16763
- console.log(`Loading tldr data "${validatedPathOrUrl}"`);
17601
+ if (isLocal)
17602
+ info(`Loading tldr data "${validatedPathOrUrl}"`);
16764
17603
  const tldrData = isLocal ? await fs3.readFile(validatedPathOrUrl, "utf8") : void 0;
16765
- const tldrawServer = new LocalTldrawServer(tldrData, verbose);
17604
+ const tldrawServer = new LocalTldrawServer(tldrData);
16766
17605
  if (isLocal)
16767
17606
  await tldrawServer.start();
16768
17607
  const tldrawUrl = isLocal ? tldrawServer.href : validatedPathOrUrl.href;
16769
- const tldrawController = new TldrawController(tldrawUrl, verbose);
17608
+ const tldrawController = new TldrawController(tldrawUrl);
16770
17609
  await tldrawController.start();
16771
17610
  await tldrawController.setTransparency(transparent);
16772
17611
  await tldrawController.setDarkMode(darkMode);
@@ -16776,7 +17615,8 @@ async function tldrawToImage(tldrPathOrUrl, options) {
16776
17615
  output,
16777
17616
  outputFilename,
16778
17617
  format3,
16779
- stripStyle
17618
+ stripStyle,
17619
+ print
16780
17620
  );
16781
17621
  } else if (Array.isArray(frames) && frames.length > 0) {
16782
17622
  exportReport = await tldrawController.downloadFrames(
@@ -16784,16 +17624,23 @@ async function tldrawToImage(tldrPathOrUrl, options) {
16784
17624
  outputFilename,
16785
17625
  format3,
16786
17626
  stripStyle,
16787
- frames
17627
+ frames,
17628
+ print
16788
17629
  );
16789
17630
  } else {
16790
- exportReport = await tldrawController.download(output, outputFilename, format3, stripStyle);
17631
+ exportReport = await tldrawController.download(
17632
+ output,
17633
+ outputFilename,
17634
+ format3,
17635
+ stripStyle,
17636
+ print
17637
+ );
16791
17638
  }
16792
17639
  await tldrawController.close();
16793
17640
  if (isLocal)
16794
17641
  tldrawServer.close();
16795
- if (verbose)
16796
- console.timeEnd("Export time");
17642
+ info(`Export time: ${prettyMilliseconds(performance.now() - startTime)}`);
17643
+ setVerbose(initialVerbosity);
16797
17644
  return exportReport;
16798
17645
  }
16799
17646
  function stripUndefined(options) {
@@ -16839,10 +17686,10 @@ function nanoid(size = 21) {
16839
17686
 
16840
17687
  // src/lib/tldraw-open.ts
16841
17688
  import fs8 from "node:fs/promises";
16842
- import os5 from "node:os";
17689
+ import os6 from "node:os";
16843
17690
 
16844
17691
  // node_modules/.pnpm/open@10.0.3/node_modules/open/index.js
16845
- import process6 from "node:process";
17692
+ import process7 from "node:process";
16846
17693
  import { Buffer as Buffer2 } from "node:buffer";
16847
17694
  import path5 from "node:path";
16848
17695
  import { fileURLToPath as fileURLToPath3 } from "node:url";
@@ -16850,8 +17697,8 @@ import childProcess from "node:child_process";
16850
17697
  import fs7, { constants as fsConstants } from "node:fs/promises";
16851
17698
 
16852
17699
  // node_modules/.pnpm/is-wsl@3.1.0/node_modules/is-wsl/index.js
16853
- import process2 from "node:process";
16854
- import os4 from "node:os";
17700
+ import process3 from "node:process";
17701
+ import os5 from "node:os";
16855
17702
  import fs6 from "node:fs";
16856
17703
 
16857
17704
  // node_modules/.pnpm/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
@@ -16901,10 +17748,10 @@ function isInsideContainer() {
16901
17748
 
16902
17749
  // node_modules/.pnpm/is-wsl@3.1.0/node_modules/is-wsl/index.js
16903
17750
  var isWsl = () => {
16904
- if (process2.platform !== "linux") {
17751
+ if (process3.platform !== "linux") {
16905
17752
  return false;
16906
17753
  }
16907
- if (os4.release().toLowerCase().includes("microsoft")) {
17754
+ if (os5.release().toLowerCase().includes("microsoft")) {
16908
17755
  if (isInsideContainer()) {
16909
17756
  return false;
16910
17757
  }
@@ -16916,7 +17763,7 @@ var isWsl = () => {
16916
17763
  return false;
16917
17764
  }
16918
17765
  };
16919
- var is_wsl_default = process2.env.__IS_WSL_TEST__ ? isWsl : isWsl();
17766
+ var is_wsl_default = process3.env.__IS_WSL_TEST__ ? isWsl : isWsl();
16920
17767
 
16921
17768
  // node_modules/.pnpm/define-lazy-prop@3.0.0/node_modules/define-lazy-prop/index.js
16922
17769
  function defineLazyProperty(object, propertyName, valueGetter) {
@@ -16938,16 +17785,16 @@ function defineLazyProperty(object, propertyName, valueGetter) {
16938
17785
 
16939
17786
  // node_modules/.pnpm/default-browser@5.2.1/node_modules/default-browser/index.js
16940
17787
  import { promisify as promisify4 } from "node:util";
16941
- import process5 from "node:process";
17788
+ import process6 from "node:process";
16942
17789
  import { execFile as execFile4 } from "node:child_process";
16943
17790
 
16944
17791
  // node_modules/.pnpm/default-browser-id@5.0.0/node_modules/default-browser-id/index.js
16945
17792
  import { promisify } from "node:util";
16946
- import process3 from "node:process";
17793
+ import process4 from "node:process";
16947
17794
  import { execFile } from "node:child_process";
16948
17795
  var execFileAsync = promisify(execFile);
16949
17796
  async function defaultBrowserId() {
16950
- if (process3.platform !== "darwin") {
17797
+ if (process4.platform !== "darwin") {
16951
17798
  throw new Error("macOS only");
16952
17799
  }
16953
17800
  const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
@@ -16956,12 +17803,12 @@ async function defaultBrowserId() {
16956
17803
  }
16957
17804
 
16958
17805
  // node_modules/.pnpm/run-applescript@7.0.0/node_modules/run-applescript/index.js
16959
- import process4 from "node:process";
17806
+ import process5 from "node:process";
16960
17807
  import { promisify as promisify2 } from "node:util";
16961
17808
  import { execFile as execFile2, execFileSync } from "node:child_process";
16962
17809
  var execFileAsync2 = promisify2(execFile2);
16963
17810
  async function runAppleScript(script, { humanReadableOutput = true } = {}) {
16964
- if (process4.platform !== "darwin") {
17811
+ if (process5.platform !== "darwin") {
16965
17812
  throw new Error("macOS only");
16966
17813
  }
16967
17814
  const outputArguments = humanReadableOutput ? [] : ["-ss"];
@@ -17017,18 +17864,18 @@ async function defaultBrowser(_execFileAsync = execFileAsync3) {
17017
17864
  var execFileAsync4 = promisify4(execFile4);
17018
17865
  var titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
17019
17866
  async function defaultBrowser2() {
17020
- if (process5.platform === "darwin") {
17867
+ if (process6.platform === "darwin") {
17021
17868
  const id = await defaultBrowserId();
17022
17869
  const name = await bundleName(id);
17023
17870
  return { name, id };
17024
17871
  }
17025
- if (process5.platform === "linux") {
17872
+ if (process6.platform === "linux") {
17026
17873
  const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
17027
17874
  const id = stdout.trim();
17028
17875
  const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
17029
17876
  return { name, id };
17030
17877
  }
17031
- if (process5.platform === "win32") {
17878
+ if (process6.platform === "win32") {
17032
17879
  return defaultBrowser();
17033
17880
  }
17034
17881
  throw new Error("Only macOS, Linux, and Windows are supported");
@@ -17037,7 +17884,7 @@ async function defaultBrowser2() {
17037
17884
  // node_modules/.pnpm/open@10.0.3/node_modules/open/index.js
17038
17885
  var __dirname = path5.dirname(fileURLToPath3(import.meta.url));
17039
17886
  var localXdgOpenPath = path5.join(__dirname, "xdg-open");
17040
- var { platform, arch } = process6;
17887
+ var { platform, arch } = process7;
17041
17888
  var getWslDrivesMountPoint = /* @__PURE__ */ (() => {
17042
17889
  const defaultMountPoint = "/mnt/";
17043
17890
  let mountPoint;
@@ -17070,8 +17917,8 @@ var pTryEach = async (array, mapper) => {
17070
17917
  for (const item of array) {
17071
17918
  try {
17072
17919
  return await mapper(item);
17073
- } catch (error) {
17074
- latestError = error;
17920
+ } catch (error2) {
17921
+ latestError = error2;
17075
17922
  }
17076
17923
  }
17077
17924
  throw latestError;
@@ -17151,7 +17998,7 @@ var baseOpen = async (options) => {
17151
17998
  }
17152
17999
  } else if (platform === "win32" || is_wsl_default && !isInsideContainer() && !app) {
17153
18000
  const mountPoint = await getWslDrivesMountPoint();
17154
- 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`;
17155
18002
  cliArguments.push(
17156
18003
  "-NoProfile",
17157
18004
  "-NonInteractive",
@@ -17190,7 +18037,7 @@ var baseOpen = async (options) => {
17190
18037
  exeLocalXdgOpen = true;
17191
18038
  } catch {
17192
18039
  }
17193
- const useSystemXdgOpen = process6.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
18040
+ const useSystemXdgOpen = process7.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
17194
18041
  command2 = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
17195
18042
  }
17196
18043
  if (appArguments.length > 0) {
@@ -17293,7 +18140,7 @@ async function tldrawOpen(tldrPathOrUrl) {
17293
18140
  const [savedFile] = await tldrawToImage(validatedPathOrUrl.href, {
17294
18141
  format: "tldr",
17295
18142
  name: nanoid(),
17296
- output: os5.tmpdir()
18143
+ output: os6.tmpdir()
17297
18144
  });
17298
18145
  const href = await tldrawOpen(savedFile);
17299
18146
  await fs8.rm(savedFile, { force: true });
@@ -17303,10 +18150,41 @@ async function tldrawOpen(tldrPathOrUrl) {
17303
18150
  }
17304
18151
  const tldrawServer = new LocalTldrawServer(tldrData);
17305
18152
  await tldrawServer.start();
17306
- 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 });
17307
18159
  return tldrawServer.href;
17308
18160
  }
17309
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
+
17310
18188
  // node_modules/.pnpm/yargs@17.7.2/node_modules/yargs/lib/platform-shims/esm.mjs
17311
18189
  import { notStrictEqual, strictEqual } from "assert";
17312
18190
 
@@ -17864,7 +18742,7 @@ var YargsParser = class {
17864
18742
  defaults[alias] = defaults[key];
17865
18743
  });
17866
18744
  });
17867
- let error = null;
18745
+ let error2 = null;
17868
18746
  checkConfiguration();
17869
18747
  let notFlags = [];
17870
18748
  const argv = Object.assign(/* @__PURE__ */ Object.create(null), { _: [] });
@@ -18048,7 +18926,7 @@ var YargsParser = class {
18048
18926
  toEat = typeof toEat !== "number" || isNaN(toEat) ? 1 : toEat;
18049
18927
  if (toEat === 0) {
18050
18928
  if (!isUndefined(argAfterEqualSign)) {
18051
- error = Error(__("Argument unexpected for: %s", key));
18929
+ error2 = Error(__("Argument unexpected for: %s", key));
18052
18930
  }
18053
18931
  setArg(key, defaultValue(key));
18054
18932
  return i;
@@ -18056,7 +18934,7 @@ var YargsParser = class {
18056
18934
  let available = isUndefined(argAfterEqualSign) ? 0 : 1;
18057
18935
  if (configuration["nargs-eats-options"]) {
18058
18936
  if (args2.length - (i + 1) + available < toEat) {
18059
- error = Error(__("Not enough arguments following: %s", key));
18937
+ error2 = Error(__("Not enough arguments following: %s", key));
18060
18938
  }
18061
18939
  available = toEat;
18062
18940
  } else {
@@ -18067,7 +18945,7 @@ var YargsParser = class {
18067
18945
  break;
18068
18946
  }
18069
18947
  if (available < toEat)
18070
- error = Error(__("Not enough arguments following: %s", key));
18948
+ error2 = Error(__("Not enough arguments following: %s", key));
18071
18949
  }
18072
18950
  let consumed = Math.min(available, toEat);
18073
18951
  if (!isUndefined(argAfterEqualSign) && consumed > 0) {
@@ -18105,7 +18983,7 @@ var YargsParser = class {
18105
18983
  }
18106
18984
  }
18107
18985
  if (typeof nargsCount === "number" && (nargsCount && argsToSet.length < nargsCount || isNaN(nargsCount) && argsToSet.length === 0)) {
18108
- error = Error(__("Not enough arguments following: %s", key));
18986
+ error2 = Error(__("Not enough arguments following: %s", key));
18109
18987
  }
18110
18988
  setArg(key, argsToSet);
18111
18989
  return i;
@@ -18214,7 +19092,7 @@ var YargsParser = class {
18214
19092
  config = e;
18215
19093
  }
18216
19094
  if (config instanceof Error) {
18217
- error = config;
19095
+ error2 = config;
18218
19096
  return;
18219
19097
  }
18220
19098
  } else {
@@ -18223,9 +19101,9 @@ var YargsParser = class {
18223
19101
  setConfigObject(config);
18224
19102
  } catch (ex) {
18225
19103
  if (ex.name === "PermissionDenied")
18226
- error = ex;
19104
+ error2 = ex;
18227
19105
  else if (argv2[configKey])
18228
- error = Error(__("Invalid JSON config file: %s", configPath));
19106
+ error2 = Error(__("Invalid JSON config file: %s", configPath));
18229
19107
  }
18230
19108
  }
18231
19109
  });
@@ -18254,8 +19132,8 @@ var YargsParser = class {
18254
19132
  if (typeof envPrefix === "undefined")
18255
19133
  return;
18256
19134
  const prefix = typeof envPrefix === "string" ? envPrefix : "";
18257
- const env2 = mixin2.env();
18258
- Object.keys(env2).forEach(function(envVar) {
19135
+ const env3 = mixin2.env();
19136
+ Object.keys(env3).forEach(function(envVar) {
18259
19137
  if (prefix === "" || envVar.lastIndexOf(prefix, 0) === 0) {
18260
19138
  const keys = envVar.split("__").map(function(key, i) {
18261
19139
  if (i === 0) {
@@ -18264,7 +19142,7 @@ var YargsParser = class {
18264
19142
  return camelCase2(key);
18265
19143
  });
18266
19144
  if ((configOnly && flags.configs[keys.join(".")] || !configOnly) && !hasKey(argv2, keys)) {
18267
- setArg(keys.join("."), env2[envVar]);
19145
+ setArg(keys.join("."), env3[envVar]);
18268
19146
  }
18269
19147
  }
18270
19148
  });
@@ -18283,7 +19161,7 @@ var YargsParser = class {
18283
19161
  argv2[ali] = value;
18284
19162
  });
18285
19163
  } catch (err) {
18286
- error = err;
19164
+ error2 = err;
18287
19165
  }
18288
19166
  }
18289
19167
  }
@@ -18496,10 +19374,10 @@ var YargsParser = class {
18496
19374
  function checkConfiguration() {
18497
19375
  Object.keys(flags.counts).find((key) => {
18498
19376
  if (checkAllAliases(key, flags.arrays)) {
18499
- error = Error(__("Invalid configuration: %s, opts.count excludes opts.array.", key));
19377
+ error2 = Error(__("Invalid configuration: %s, opts.count excludes opts.array.", key));
18500
19378
  return true;
18501
19379
  } else if (checkAllAliases(key, flags.nargs)) {
18502
- error = Error(__("Invalid configuration: %s, opts.count excludes opts.narg.", key));
19380
+ error2 = Error(__("Invalid configuration: %s, opts.count excludes opts.narg.", key));
18503
19381
  return true;
18504
19382
  }
18505
19383
  return false;
@@ -18510,7 +19388,7 @@ var YargsParser = class {
18510
19388
  argv: Object.assign(argvReturn, argv),
18511
19389
  configuration,
18512
19390
  defaulted: Object.assign({}, defaulted),
18513
- error,
19391
+ error: error2,
18514
19392
  newAliases: Object.assign({}, newAliases)
18515
19393
  };
18516
19394
  }
@@ -18574,11 +19452,11 @@ if (nodeVersion) {
18574
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`);
18575
19453
  }
18576
19454
  }
18577
- var env = process ? process.env : {};
19455
+ var env2 = process ? process.env : {};
18578
19456
  var parser = new YargsParser({
18579
19457
  cwd: process.cwd,
18580
19458
  env: () => {
18581
- return env;
19459
+ return env2;
18582
19460
  },
18583
19461
  format,
18584
19462
  normalize,
@@ -19285,9 +20163,9 @@ var CommandInstance = class {
19285
20163
  yargs.getInternalMethods().getUsageInstance().cacheHelpMessage();
19286
20164
  }
19287
20165
  if (isPromise(innerArgv) && !yargs.getInternalMethods().hasParseCallback()) {
19288
- innerArgv.catch((error) => {
20166
+ innerArgv.catch((error2) => {
19289
20167
  try {
19290
- yargs.getInternalMethods().getUsageInstance().fail(null, error);
20168
+ yargs.getInternalMethods().getUsageInstance().fail(null, error2);
19291
20169
  } catch (_err) {
19292
20170
  }
19293
20171
  });
@@ -22164,24 +23042,13 @@ var Yargs = YargsFactory(esm_default3);
22164
23042
  var yargs_default = Yargs;
22165
23043
 
22166
23044
  // src/cli/tldraw-cli.ts
23045
+ setCli(true);
22167
23046
  await yargs_default(hideBin(process.argv)).scriptName("tldraw-cli").command("$0 <command>", "CLI tools for tldraw.").command(
22168
- "open [file-or-url]",
22169
- '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.',
22170
- (yargs) => yargs.positional("file-or-url", {
22171
- 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.",
22172
- type: "string"
22173
- }),
22174
- async (argv) => {
22175
- const { fileOrUrl } = argv;
22176
- const localUrl = await tldrawOpen(fileOrUrl);
22177
- console.log(localUrl);
22178
- }
22179
- ).command(
22180
- "export <file-or-url>",
23047
+ "export <files-or-urls..>",
22181
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.',
22182
- (yargs) => yargs.positional("file-or-url", {
23049
+ (yargs) => yargs.positional("files-or-urls", {
22183
23050
  demandOption: true,
22184
- 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`.",
22185
23052
  type: "string"
22186
23053
  }).option("format", {
22187
23054
  alias: "f",
@@ -22191,24 +23058,15 @@ await yargs_default(hideBin(process.argv)).scriptName("tldraw-cli").command("$0
22191
23058
  type: "string"
22192
23059
  }).option("output", {
22193
23060
  alias: "o",
22194
- default: "./",
23061
+ default: void 0,
23062
+ defaultDescription: '"./"',
22195
23063
  describe: "Output image directory.",
22196
23064
  type: "string"
22197
23065
  }).option("name", {
22198
23066
  alias: "n",
22199
- defaultDescription: "The original file name or URL id is used",
22200
- describe: "Output image name",
23067
+ defaultDescription: "The original file name or URL id is used.",
23068
+ describe: "Output image name (without extension).",
22201
23069
  type: "string"
22202
- }).option("transparent", {
22203
- alias: "t",
22204
- default: false,
22205
- describe: "Output an image with a transparent background.",
22206
- type: "boolean"
22207
- }).option("dark-mode", {
22208
- alias: "d",
22209
- default: false,
22210
- describe: "Output a dark theme version of the image.",
22211
- type: "boolean"
22212
23070
  }).option("frames", {
22213
23071
  coerce(args) {
22214
23072
  return args.length === 0 ? true : args;
@@ -22217,45 +23075,133 @@ await yargs_default(hideBin(process.argv)).scriptName("tldraw-cli").command("$0
22217
23075
  // value to true, and still be able to extract meaning from the
22218
23076
  // absence of the option
22219
23077
  defaultDescription: "false",
22220
- 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.',
22221
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"
22222
23090
  }).option("strip-style", {
22223
23091
  default: false,
22224
- 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.",
23093
+ type: "boolean"
23094
+ }).option("print", {
23095
+ alias: "p",
23096
+ default: false,
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.",
22225
23098
  type: "boolean"
22226
23099
  }).option("verbose", {
22227
23100
  default: false,
22228
- 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.",
22229
23102
  type: "boolean"
23103
+ }).check((argv) => {
23104
+ if (argv.print && argv.output !== void 0) {
23105
+ throw new Error("Cannot use --output with --print");
23106
+ }
23107
+ return true;
22230
23108
  }),
22231
23109
  async (argv) => {
22232
23110
  const {
22233
23111
  darkMode,
22234
- fileOrUrl,
23112
+ filesOrUrls,
22235
23113
  format: format3,
22236
23114
  frames,
22237
23115
  name,
22238
23116
  output,
23117
+ print,
22239
23118
  stripStyle,
22240
23119
  transparent,
22241
- verbose
23120
+ verbose: verbose2
22242
23121
  } = argv;
22243
- try {
22244
- const exportList = await tldrawToImage(fileOrUrl, {
22245
- darkMode,
22246
- format: format3,
22247
- // CLI never returns false, but the function accepts it for stand-alone use
22248
- frames,
22249
- name,
22250
- output,
22251
- stripStyle,
22252
- transparent,
22253
- verbose
22254
- });
22255
- 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) {
22256
23203
  process.exit(0);
22257
- } catch (error) {
22258
- console.error("Export failed:", error);
23204
+ } else {
22259
23205
  process.exit(1);
22260
23206
  }
22261
23207
  }