@kubohiroya/turbowarp-plus-editor-git 0.16.0 → 0.17.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.
@@ -1,3 +1,4 @@
1
+ import { n as init_objectSpread2, t as _objectSpread2 } from "./objectSpread2-Dkd68nJH.js";
1
2
  // node_modules/diff/libesm/diff/base.js
2
3
  var Diff = class {
3
4
  diff(oldStr, newStr, options = {}) {
@@ -518,6 +519,518 @@ var ArrayDiff = class extends Diff {
518
519
  }
519
520
  };
520
521
  new ArrayDiff();
522
+ // node_modules/diff/libesm/patch/line-endings.js
523
+ function unixToWin(patch) {
524
+ if (Array.isArray(patch)) return patch.map((p) => unixToWin(p));
525
+ return Object.assign(Object.assign({}, patch), { hunks: patch.hunks.map((hunk) => Object.assign(Object.assign({}, hunk), { lines: hunk.lines.map((line, i) => {
526
+ var _a;
527
+ return line.startsWith("\\") || line.endsWith("\r") || ((_a = hunk.lines[i + 1]) === null || _a === void 0 ? void 0 : _a.startsWith("\\")) ? line : line + "\r";
528
+ }) })) });
529
+ }
530
+ function winToUnix(patch) {
531
+ if (Array.isArray(patch)) return patch.map((p) => winToUnix(p));
532
+ return Object.assign(Object.assign({}, patch), { hunks: patch.hunks.map((hunk) => Object.assign(Object.assign({}, hunk), { lines: hunk.lines.map((line) => line.endsWith("\r") ? line.substring(0, line.length - 1) : line) })) });
533
+ }
534
+ /**
535
+ * Returns true if the patch consistently uses Unix line endings (or only involves one line and has
536
+ * no line endings).
537
+ */
538
+ function isUnix(patch) {
539
+ if (!Array.isArray(patch)) patch = [patch];
540
+ return !patch.some((index) => index.hunks.some((hunk) => hunk.lines.some((line) => !line.startsWith("\\") && line.endsWith("\r"))));
541
+ }
542
+ /**
543
+ * Returns true if the patch uses Windows line endings and only Windows line endings.
544
+ */
545
+ function isWin(patch) {
546
+ if (!Array.isArray(patch)) patch = [patch];
547
+ return patch.some((index) => index.hunks.some((hunk) => hunk.lines.some((line) => line.endsWith("\r")))) && patch.every((index) => index.hunks.every((hunk) => hunk.lines.every((line, i) => {
548
+ var _a;
549
+ return line.startsWith("\\") || line.endsWith("\r") || ((_a = hunk.lines[i + 1]) === null || _a === void 0 ? void 0 : _a.startsWith("\\"));
550
+ })));
551
+ }
552
+ // node_modules/diff/libesm/patch/parse.js
553
+ /**
554
+ * Parses a unified diff format patch into a structured patch object.
555
+ *
556
+ * `parsePatch` has some understanding of Git's particular dialect of unified diff format.
557
+ * When parsing a Git patch, each index in the result may contain additional
558
+ * fields (`isRename`, `isBinary`, etc) not included in the data structure returned by
559
+ * `structuredPatch`; see the `StructuredPatch` interface for a full list.
560
+ *
561
+ * @return a JSON object representation of the patch, suitable for use with the `applyPatch`
562
+ * method. This parses to the same structure returned by `structuredPatch`, except that
563
+ * `oldFileName` and `newFileName` may be `undefined` if the patch doesn't contain enough
564
+ * information to determine them (e.g. a hunk-only patch with no file headers).
565
+ */
566
+ function parsePatch(uniDiff) {
567
+ const diffstr = uniDiff.split(/\n/), list = [];
568
+ let i = 0;
569
+ function isGitDiffHeader(line) {
570
+ return /^diff --git /.test(line);
571
+ }
572
+ function isDiffHeader(line) {
573
+ return isGitDiffHeader(line) || /^Index:\s/.test(line) || /^diff(?: -r \w+)+\s/.test(line);
574
+ }
575
+ function isFileHeader(line) {
576
+ return /^(---|\+\+\+)\s/.test(line);
577
+ }
578
+ function isHunkHeader(line) {
579
+ return /^@@\s/.test(line);
580
+ }
581
+ function parseIndex() {
582
+ var _a;
583
+ const index = {};
584
+ index.hunks = [];
585
+ list.push(index);
586
+ let seenDiffHeader = false;
587
+ while (i < diffstr.length) {
588
+ const line = diffstr[i];
589
+ if (isFileHeader(line) || isHunkHeader(line)) break;
590
+ if (isGitDiffHeader(line)) {
591
+ if (seenDiffHeader) return;
592
+ seenDiffHeader = true;
593
+ index.isGit = true;
594
+ const paths = parseGitDiffHeader(line);
595
+ if (paths) {
596
+ index.oldFileName = paths.oldFileName;
597
+ index.newFileName = paths.newFileName;
598
+ }
599
+ i++;
600
+ while (i < diffstr.length) {
601
+ const extLine = diffstr[i];
602
+ if (isFileHeader(extLine) || isHunkHeader(extLine) || isDiffHeader(extLine)) break;
603
+ const renameFromMatch = /^rename from (.*)/.exec(extLine);
604
+ if (renameFromMatch) {
605
+ index.oldFileName = "a/" + unquoteIfQuoted(renameFromMatch[1]);
606
+ index.isRename = true;
607
+ }
608
+ const renameToMatch = /^rename to (.*)/.exec(extLine);
609
+ if (renameToMatch) {
610
+ index.newFileName = "b/" + unquoteIfQuoted(renameToMatch[1]);
611
+ index.isRename = true;
612
+ }
613
+ const copyFromMatch = /^copy from (.*)/.exec(extLine);
614
+ if (copyFromMatch) {
615
+ index.oldFileName = "a/" + unquoteIfQuoted(copyFromMatch[1]);
616
+ index.isCopy = true;
617
+ }
618
+ const copyToMatch = /^copy to (.*)/.exec(extLine);
619
+ if (copyToMatch) {
620
+ index.newFileName = "b/" + unquoteIfQuoted(copyToMatch[1]);
621
+ index.isCopy = true;
622
+ }
623
+ const newFileModeMatch = /^new file mode (\d+)/.exec(extLine);
624
+ if (newFileModeMatch) {
625
+ index.isCreate = true;
626
+ index.newMode = newFileModeMatch[1];
627
+ }
628
+ const deletedFileModeMatch = /^deleted file mode (\d+)/.exec(extLine);
629
+ if (deletedFileModeMatch) {
630
+ index.isDelete = true;
631
+ index.oldMode = deletedFileModeMatch[1];
632
+ }
633
+ const oldModeMatch = /^old mode (\d+)/.exec(extLine);
634
+ if (oldModeMatch) index.oldMode = oldModeMatch[1];
635
+ const newModeMatch = /^new mode (\d+)/.exec(extLine);
636
+ if (newModeMatch) index.newMode = newModeMatch[1];
637
+ if (/^Binary files /.test(extLine)) index.isBinary = true;
638
+ i++;
639
+ }
640
+ continue;
641
+ } else if (isDiffHeader(line)) {
642
+ if (seenDiffHeader) return;
643
+ seenDiffHeader = true;
644
+ const headerMatch = /^(?:Index:|diff(?: -r \w+)+)\s+/.exec(line);
645
+ if (headerMatch) index.index = line.substring(headerMatch[0].length).trim();
646
+ }
647
+ i++;
648
+ }
649
+ parseFileHeader(index);
650
+ parseFileHeader(index);
651
+ if (index.oldFileName === void 0 !== (index.newFileName === void 0)) throw new Error("Missing " + (index.oldFileName !== void 0 ? "\"+++ ...\"" : "\"--- ...\"") + " file header for " + ((_a = index.oldFileName) !== null && _a !== void 0 ? _a : index.newFileName));
652
+ while (i < diffstr.length) {
653
+ const line = diffstr[i];
654
+ if (isDiffHeader(line) || isFileHeader(line) || /^===================================================================/.test(line)) break;
655
+ else if (isHunkHeader(line)) index.hunks.push(parseHunk());
656
+ else i++;
657
+ }
658
+ }
659
+ /**
660
+ * Parses the old and new filenames from a `diff --git` header line.
661
+ *
662
+ * The format is:
663
+ * diff --git a/<old-path> b/<new-path>
664
+ *
665
+ * When filenames contain special characters (including newlines, tabs,
666
+ * backslashes, or double quotes), Git quotes them with C-style escaping:
667
+ * diff --git "a/file\twith\ttabs.txt" "b/file\twith\ttabs.txt"
668
+ *
669
+ * When filenames don't contain special characters and the old and new names
670
+ * are the same, we can unambiguously split on ` b/` by finding where the
671
+ * two halves (including their a/ and b/ prefixes) yield matching bare names.
672
+ *
673
+ * A pathological case exists in which we cannot reliably determine the paths
674
+ * from the `diff --git` header. This case is when the following are true:
675
+ * - the old and new file paths differ
676
+ * - they are both unquoted (i.e. contain no special characters)
677
+ * - at least one of the underlying file paths includes the substring ` b/`
678
+ * In this scenario, we do not know which occurrence of ` b/` indicates the
679
+ * start of the new file path, so the header is inherently ambiguous. We thus
680
+ * select a possible interpretation arbitrarily and return that.
681
+ *
682
+ * Fortunately, this ambiguity should never matter, because in any patch
683
+ * genuinely output by Git in which this pathological scenario occurs, there
684
+ * must also be `rename from`/`rename to` or `copy from`/`copy to` extended
685
+ * headers present below the `diff --git` header. `parseIndex` will parse
686
+ * THOSE headers, from which we CAN unambiguously determine the filenames,
687
+ * and will discard the result returned by this function.
688
+ *
689
+ * Returns null if the header can't be parsed at all — e.g. a quoted filename
690
+ * has an unterminated quote, or if the unquoted header doesn't match the
691
+ * expected `a/... b/...` format. In that case, the caller (parseIndex)
692
+ * skips setting oldFileName/newFileName from this header, but they may
693
+ * still be set later from `---`/`+++` lines or `rename from`/`rename to`
694
+ * extended headers; if none of those are present either, they'll remain
695
+ * undefined in the output.
696
+ */
697
+ function parseGitDiffHeader(line) {
698
+ const rest = line.substring(11);
699
+ if (rest.startsWith("\"")) {
700
+ const oldPath = parseQuotedFileName(rest);
701
+ if (oldPath === null) return null;
702
+ const afterOld = rest.substring(oldPath.rawLength + 1);
703
+ let newFileName;
704
+ if (afterOld.startsWith("\"")) {
705
+ const newPath = parseQuotedFileName(afterOld);
706
+ if (newPath === null) return null;
707
+ newFileName = newPath.fileName;
708
+ } else newFileName = afterOld;
709
+ return {
710
+ oldFileName: oldPath.fileName,
711
+ newFileName
712
+ };
713
+ }
714
+ const quoteIdx = rest.indexOf("\"");
715
+ if (quoteIdx > 0) {
716
+ const oldFileName = rest.substring(0, quoteIdx - 1);
717
+ const newPath = parseQuotedFileName(rest.substring(quoteIdx));
718
+ if (newPath === null) return null;
719
+ return {
720
+ oldFileName,
721
+ newFileName: newPath.fileName
722
+ };
723
+ }
724
+ if (rest.startsWith("a/")) {
725
+ const splits = [];
726
+ let idx = 0;
727
+ while (true) {
728
+ idx = rest.indexOf(" b/", idx + 1);
729
+ if (idx === -1) break;
730
+ splits.push(idx);
731
+ }
732
+ if (splits.length > 0) {
733
+ const mid = splits[Math.floor(splits.length / 2)];
734
+ return {
735
+ oldFileName: rest.substring(0, mid),
736
+ newFileName: rest.substring(mid + 1)
737
+ };
738
+ }
739
+ }
740
+ return null;
741
+ }
742
+ /**
743
+ * If `s` starts with a double quote, unquotes it using C-style escape
744
+ * rules (as used by Git). Otherwise returns `s` as-is.
745
+ */
746
+ function unquoteIfQuoted(s) {
747
+ if (s.startsWith("\"")) {
748
+ const parsed = parseQuotedFileName(s);
749
+ if (parsed) return parsed.fileName;
750
+ }
751
+ return s;
752
+ }
753
+ /**
754
+ * Parses a C-style quoted filename as used by Git or GNU `diff -u`.
755
+ * Returns the unescaped filename and the raw length consumed (including quotes).
756
+ */
757
+ function parseQuotedFileName(s) {
758
+ if (!s.startsWith("\"")) return null;
759
+ let result = "";
760
+ let j = 1;
761
+ while (j < s.length) {
762
+ if (s[j] === "\"") return {
763
+ fileName: result,
764
+ rawLength: j + 1
765
+ };
766
+ if (s[j] === "\\" && j + 1 < s.length) {
767
+ j++;
768
+ switch (s[j]) {
769
+ case "a":
770
+ result += "\x07";
771
+ break;
772
+ case "b":
773
+ result += "\b";
774
+ break;
775
+ case "f":
776
+ result += "\f";
777
+ break;
778
+ case "n":
779
+ result += "\n";
780
+ break;
781
+ case "r":
782
+ result += "\r";
783
+ break;
784
+ case "t":
785
+ result += " ";
786
+ break;
787
+ case "v":
788
+ result += "\v";
789
+ break;
790
+ case "\\":
791
+ result += "\\";
792
+ break;
793
+ case "\"":
794
+ result += "\"";
795
+ break;
796
+ case "0":
797
+ case "1":
798
+ case "2":
799
+ case "3":
800
+ case "4":
801
+ case "5":
802
+ case "6":
803
+ case "7": {
804
+ if (j + 2 >= s.length || s[j + 1] < "0" || s[j + 1] > "7" || s[j + 2] < "0" || s[j + 2] > "7") return null;
805
+ const bytes = [parseInt(s.substring(j, j + 3), 8)];
806
+ j += 3;
807
+ while (s[j] === "\\" && s[j + 1] >= "0" && s[j + 1] <= "7") {
808
+ if (j + 3 >= s.length || s[j + 2] < "0" || s[j + 2] > "7" || s[j + 3] < "0" || s[j + 3] > "7") return null;
809
+ bytes.push(parseInt(s.substring(j + 1, j + 4), 8));
810
+ j += 4;
811
+ }
812
+ result += new TextDecoder("utf-8").decode(new Uint8Array(bytes));
813
+ continue;
814
+ }
815
+ default: return null;
816
+ }
817
+ } else result += s[j];
818
+ j++;
819
+ }
820
+ return null;
821
+ }
822
+ function parseFileHeader(index) {
823
+ const fileHeaderMatch = /^(---|\+\+\+)\s+/.exec(diffstr[i]);
824
+ if (fileHeaderMatch) {
825
+ const prefix = fileHeaderMatch[1], data = diffstr[i].substring(3).trim().split(" ", 2), header = (data[1] || "").trim();
826
+ let fileName = data[0];
827
+ if (fileName.startsWith("\"")) fileName = unquoteIfQuoted(fileName);
828
+ else fileName = fileName.replace(/\\\\/g, "\\");
829
+ if (prefix === "---") {
830
+ index.oldFileName = fileName;
831
+ index.oldHeader = header;
832
+ } else {
833
+ index.newFileName = fileName;
834
+ index.newHeader = header;
835
+ }
836
+ i++;
837
+ }
838
+ }
839
+ function parseHunk() {
840
+ var _a;
841
+ const chunkHeaderIndex = i, chunkHeader = diffstr[i++].split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/);
842
+ const hunk = {
843
+ oldStart: +chunkHeader[1],
844
+ oldLines: typeof chunkHeader[2] === "undefined" ? 1 : +chunkHeader[2],
845
+ newStart: +chunkHeader[3],
846
+ newLines: typeof chunkHeader[4] === "undefined" ? 1 : +chunkHeader[4],
847
+ lines: []
848
+ };
849
+ if (hunk.oldLines === 0) hunk.oldStart += 1;
850
+ if (hunk.newLines === 0) hunk.newStart += 1;
851
+ let addCount = 0, removeCount = 0;
852
+ for (; i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines || ((_a = diffstr[i]) === null || _a === void 0 ? void 0 : _a.startsWith("\\"))); i++) {
853
+ const operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? " " : diffstr[i][0];
854
+ if (operation === "+" || operation === "-" || operation === " " || operation === "\\") {
855
+ hunk.lines.push(diffstr[i]);
856
+ if (operation === "+") addCount++;
857
+ else if (operation === "-") removeCount++;
858
+ else if (operation === " ") {
859
+ addCount++;
860
+ removeCount++;
861
+ }
862
+ } else throw new Error(`Hunk at line ${chunkHeaderIndex + 1} contained invalid line ${diffstr[i]}`);
863
+ }
864
+ if (!addCount && hunk.newLines === 1) hunk.newLines = 0;
865
+ if (!removeCount && hunk.oldLines === 1) hunk.oldLines = 0;
866
+ if (addCount !== hunk.newLines) throw new Error("Added line count did not match for hunk at line " + (chunkHeaderIndex + 1));
867
+ if (removeCount !== hunk.oldLines) throw new Error("Removed line count did not match for hunk at line " + (chunkHeaderIndex + 1));
868
+ if (i < diffstr.length && diffstr[i] && /^[+ -]/.test(diffstr[i]) && !isFileHeader(diffstr[i])) throw new Error("Hunk at line " + (chunkHeaderIndex + 1) + " has more lines than expected (expected " + hunk.oldLines + " old lines and " + hunk.newLines + " new lines)");
869
+ return hunk;
870
+ }
871
+ while (i < diffstr.length) parseIndex();
872
+ return list;
873
+ }
874
+ // node_modules/diff/libesm/util/distance-iterator.js
875
+ function distance_iterator_default(start, minLine, maxLine) {
876
+ let wantForward = true, backwardExhausted = false, forwardExhausted = false, localOffset = 1;
877
+ return function iterator() {
878
+ if (wantForward && !forwardExhausted) {
879
+ if (backwardExhausted) localOffset++;
880
+ else wantForward = false;
881
+ if (start + localOffset <= maxLine) return start + localOffset;
882
+ forwardExhausted = true;
883
+ }
884
+ if (!backwardExhausted) {
885
+ if (!forwardExhausted) wantForward = true;
886
+ if (minLine <= start - localOffset) return start - localOffset++;
887
+ backwardExhausted = true;
888
+ return iterator();
889
+ }
890
+ };
891
+ }
892
+ // node_modules/diff/libesm/patch/apply.js
893
+ /**
894
+ * attempts to apply a unified diff patch.
895
+ *
896
+ * Hunks are applied first to last.
897
+ * `applyPatch` first tries to apply the first hunk at the line number specified in the hunk header, and with all context lines matching exactly.
898
+ * If that fails, it tries scanning backwards and forwards, one line at a time, to find a place to apply the hunk where the context lines match exactly.
899
+ * If that still fails, and `fuzzFactor` is greater than zero, it increments the maximum number of mismatches (missing, extra, or changed context lines) that there can be between the hunk context and a region where we are trying to apply the patch such that the hunk will still be considered to match.
900
+ * Regardless of `fuzzFactor`, lines to be deleted in the hunk *must* be present for a hunk to match, and the context lines *immediately* before and after an insertion must match exactly.
901
+ *
902
+ * Once a hunk is successfully fitted, the process begins again with the next hunk.
903
+ * Regardless of `fuzzFactor`, later hunks must be applied later in the file than earlier hunks.
904
+ *
905
+ * If a hunk cannot be successfully fitted *anywhere* with fewer than `fuzzFactor` mismatches, `applyPatch` fails and returns `false`.
906
+ *
907
+ * If a hunk is successfully fitted but not at the line number specified by the hunk header, all subsequent hunks have their target line number adjusted accordingly.
908
+ * (e.g. if the first hunk is applied 10 lines below where the hunk header said it should fit, `applyPatch` will *start* looking for somewhere to apply the second hunk 10 lines below where its hunk header says it goes.)
909
+ *
910
+ * If the patch was applied successfully, returns a string containing the patched text.
911
+ * If the patch could not be applied (because some hunks in the patch couldn't be fitted to the text in `source`), `applyPatch` returns false.
912
+ *
913
+ * @param patch a string diff or the output from the `parsePatch` or `structuredPatch` methods.
914
+ */
915
+ function applyPatch(source, patch, options = {}) {
916
+ let patches;
917
+ if (typeof patch === "string") patches = parsePatch(patch);
918
+ else if (Array.isArray(patch)) patches = patch;
919
+ else patches = [patch];
920
+ if (patches.length > 1) throw new Error("applyPatch only works with a single input.");
921
+ return applyStructuredPatch(source, patches[0], options);
922
+ }
923
+ function applyStructuredPatch(source, patch, options = {}) {
924
+ if (options.autoConvertLineEndings || options.autoConvertLineEndings == null) {
925
+ if (hasOnlyWinLineEndings(source) && isUnix(patch)) patch = unixToWin(patch);
926
+ else if (hasOnlyUnixLineEndings(source) && isWin(patch)) patch = winToUnix(patch);
927
+ }
928
+ const lines = source.split("\n"), hunks = patch.hunks, compareLine = options.compareLine || ((lineNumber, line, operation, patchContent) => line === patchContent), fuzzFactor = options.fuzzFactor || 0;
929
+ let minLine = 0;
930
+ if (fuzzFactor < 0 || !Number.isInteger(fuzzFactor)) throw new Error("fuzzFactor must be a non-negative integer");
931
+ if (!hunks.length) return source;
932
+ let prevLine = "", removeEOFNL = false, addEOFNL = false;
933
+ for (let i = 0; i < hunks[hunks.length - 1].lines.length; i++) {
934
+ const line = hunks[hunks.length - 1].lines[i];
935
+ if (line[0] == "\\") {
936
+ if (prevLine[0] == "+") removeEOFNL = true;
937
+ else if (prevLine[0] == "-") addEOFNL = true;
938
+ }
939
+ prevLine = line;
940
+ }
941
+ if (removeEOFNL) {
942
+ if (addEOFNL) {
943
+ if (!fuzzFactor && lines[lines.length - 1] == "") return false;
944
+ } else if (lines[lines.length - 1] == "") lines.pop();
945
+ else if (!fuzzFactor) return false;
946
+ } else if (addEOFNL) {
947
+ if (lines[lines.length - 1] != "") lines.push("");
948
+ else if (!fuzzFactor) return false;
949
+ }
950
+ /**
951
+ * Checks if the hunk can be made to fit at the provided location with at most `maxErrors`
952
+ * insertions, substitutions, or deletions, while ensuring also that:
953
+ * - lines deleted in the hunk match exactly, and
954
+ * - wherever an insertion operation or block of insertion operations appears in the hunk, the
955
+ * immediately preceding and following lines of context match exactly
956
+ *
957
+ * `toPos` should be set such that lines[toPos] is meant to match hunkLines[0].
958
+ *
959
+ * If the hunk can be applied, returns an object with properties `oldLineLastI` and
960
+ * `replacementLines`. Otherwise, returns null.
961
+ */
962
+ function applyHunk(hunkLines, toPos, maxErrors, hunkLinesI = 0, lastContextLineMatched = true, patchedLines = [], patchedLinesLength = 0) {
963
+ let nConsecutiveOldContextLines = 0;
964
+ let nextContextLineMustMatch = false;
965
+ for (; hunkLinesI < hunkLines.length; hunkLinesI++) {
966
+ const hunkLine = hunkLines[hunkLinesI], operation = hunkLine.length > 0 ? hunkLine[0] : " ", content = hunkLine.length > 0 ? hunkLine.substr(1) : hunkLine;
967
+ if (operation === "-") {
968
+ if (compareLine(toPos + 1, lines[toPos], operation, content)) {
969
+ toPos++;
970
+ nConsecutiveOldContextLines = 0;
971
+ } else {
972
+ if (!maxErrors || lines[toPos] == null) return null;
973
+ patchedLines[patchedLinesLength] = lines[toPos];
974
+ return applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI, false, patchedLines, patchedLinesLength + 1);
975
+ }
976
+ }
977
+ if (operation === "+") {
978
+ if (!lastContextLineMatched) return null;
979
+ patchedLines[patchedLinesLength] = content;
980
+ patchedLinesLength++;
981
+ nConsecutiveOldContextLines = 0;
982
+ nextContextLineMustMatch = true;
983
+ }
984
+ if (operation === " ") {
985
+ nConsecutiveOldContextLines++;
986
+ patchedLines[patchedLinesLength] = lines[toPos];
987
+ if (compareLine(toPos + 1, lines[toPos], operation, content)) {
988
+ patchedLinesLength++;
989
+ lastContextLineMatched = true;
990
+ nextContextLineMustMatch = false;
991
+ toPos++;
992
+ } else {
993
+ if (nextContextLineMustMatch || !maxErrors) return null;
994
+ return lines[toPos] && (applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI + 1, false, patchedLines, patchedLinesLength + 1) || applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI, false, patchedLines, patchedLinesLength + 1)) || applyHunk(hunkLines, toPos, maxErrors - 1, hunkLinesI + 1, false, patchedLines, patchedLinesLength);
995
+ }
996
+ }
997
+ }
998
+ patchedLinesLength -= nConsecutiveOldContextLines;
999
+ toPos -= nConsecutiveOldContextLines;
1000
+ patchedLines.length = patchedLinesLength;
1001
+ return {
1002
+ patchedLines,
1003
+ oldLineLastI: toPos - 1
1004
+ };
1005
+ }
1006
+ const resultLines = [];
1007
+ let prevHunkOffset = 0;
1008
+ for (let i = 0; i < hunks.length; i++) {
1009
+ const hunk = hunks[i];
1010
+ let hunkResult;
1011
+ const maxLine = lines.length - hunk.oldLines + fuzzFactor;
1012
+ let toPos;
1013
+ for (let maxErrors = 0; maxErrors <= fuzzFactor; maxErrors++) {
1014
+ toPos = hunk.oldStart + prevHunkOffset - 1;
1015
+ const iterator = distance_iterator_default(toPos, minLine, maxLine);
1016
+ for (; toPos !== void 0; toPos = iterator()) {
1017
+ hunkResult = applyHunk(hunk.lines, toPos, maxErrors);
1018
+ if (hunkResult) break;
1019
+ }
1020
+ if (hunkResult) break;
1021
+ }
1022
+ if (!hunkResult) return false;
1023
+ for (let i = minLine; i < toPos; i++) resultLines.push(lines[i]);
1024
+ for (let i = 0; i < hunkResult.patchedLines.length; i++) {
1025
+ const line = hunkResult.patchedLines[i];
1026
+ resultLines.push(line);
1027
+ }
1028
+ minLine = hunkResult.oldLineLastI + 1;
1029
+ prevHunkOffset = toPos + 1 - hunk.oldStart;
1030
+ }
1031
+ for (let i = minLine; i < lines.length; i++) resultLines.push(lines[i]);
1032
+ return resultLines.join("\n");
1033
+ }
521
1034
  // node_modules/diff/libesm/patch/create.js
522
1035
  /**
523
1036
  * Returns true if the filename contains characters that require C-style
@@ -736,6 +1249,145 @@ function splitLines(text) {
736
1249
  else result.push(result.pop().slice(0, -1));
737
1250
  return result;
738
1251
  }
1252
+ // \0@oxc-project+runtime@0.156.0/helpers/esm/objectWithoutPropertiesLoose.js
1253
+ init_objectSpread2();
1254
+ function _objectWithoutPropertiesLoose(r, e) {
1255
+ if (null == r) return {};
1256
+ var t = {};
1257
+ for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
1258
+ if (e.includes(n)) continue;
1259
+ t[n] = r[n];
1260
+ }
1261
+ return t;
1262
+ }
1263
+ // \0@oxc-project+runtime@0.156.0/helpers/esm/objectWithoutProperties.js
1264
+ function _objectWithoutProperties(e, t) {
1265
+ if (null == e) return {};
1266
+ var o, r, i = _objectWithoutPropertiesLoose(e, t);
1267
+ if (Object.getOwnPropertySymbols) {
1268
+ var s = Object.getOwnPropertySymbols(e);
1269
+ for (r = 0; r < s.length; r++) o = s[r], t.includes(o) || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
1270
+ }
1271
+ return i;
1272
+ }
1273
+ // src/project-source-patch.ts
1274
+ var _excluded = ["blocks"];
1275
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1276
+ function readProject(source) {
1277
+ const project = JSON.parse(source);
1278
+ if (!isRecord(project) || !Array.isArray(project.targets) || !project.targets.every((target) => isRecord(target) && typeof target.name === "string" && typeof target.isStage === "boolean" && (target.blocks === void 0 || isRecord(target.blocks)))) throw new Error("Expected a project.source.json with Scratch targets and blocks.");
1279
+ const parsed = project;
1280
+ return _objectSpread2(_objectSpread2({}, parsed), {}, { targets: parsed.targets.map((target) => {
1281
+ var _target$blocks;
1282
+ return _objectSpread2(_objectSpread2({}, target), {}, { blocks: (_target$blocks = target.blocks) !== null && _target$blocks !== void 0 ? _target$blocks : {} });
1283
+ }) });
1284
+ }
1285
+ /** Reads one version of a project.source.json. `null` stands for a version in which the file does not exist. */
1286
+ function parseProjectSource(source) {
1287
+ return source === null ? { targets: [] } : readProject(source);
1288
+ }
1289
+ /** Keep the original lines and include enough context to render both sides from the patch alone. */
1290
+ function createProjectSourceDiff(before, after) {
1291
+ readProject(before);
1292
+ readProject(after);
1293
+ const patch = createTwoFilesPatch("a/project.source.json", "b/project.source.json", before, after, void 0, void 0, {
1294
+ context: Infinity,
1295
+ timeout: 1e3
1296
+ });
1297
+ if (patch === void 0) throw new Error("Project source diff exceeded its time limit.");
1298
+ return "diff --git a/project.source.json b/project.source.json\n" + patch.replace(/^=+\n/, "");
1299
+ }
1300
+ function readProjectSourceDiff(patch, beforeSource) {
1301
+ const [file, extra] = parsePatch(patch);
1302
+ if (!file || extra || !file.oldFileName || !file.newFileName) throw new Error("Expected a single unified text diff.");
1303
+ if (beforeSource !== void 0) {
1304
+ const before = readProject(beforeSource);
1305
+ const after = applyPatch(beforeSource, file);
1306
+ if (after === false) throw new Error("The original project does not match this diff.");
1307
+ return [before, readProject(after)];
1308
+ }
1309
+ if (!file.hunks.length) return null;
1310
+ const before = [], after = [];
1311
+ for (const hunk of file.hunks) {
1312
+ if (hunk.oldStart !== before.length + 1 || hunk.newStart !== after.length + 1) throw new Error("The diff omits project context.");
1313
+ for (const line of hunk.lines) {
1314
+ if (line.startsWith(" ") || line.startsWith("-")) before.push(line.slice(1));
1315
+ if (line.startsWith(" ") || line.startsWith("+")) after.push(line.slice(1));
1316
+ }
1317
+ }
1318
+ return [readProject(before.join("\n")), readProject(after.join("\n"))];
1319
+ }
1320
+ function equal(a, b) {
1321
+ if (a === b) return true;
1322
+ if (Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((value, i) => equal(value, b[i]));
1323
+ if (!isRecord(a) || !isRecord(b)) return false;
1324
+ const keys = Object.keys(a);
1325
+ return keys.length === Object.keys(b).length && keys.every((key) => Object.hasOwn(b, key) && equal(a[key], b[key]));
1326
+ }
1327
+ var targetKey = (target) => target.isStage ? "stage" : "sprite:" + target.name;
1328
+ function changedParts(before, after) {
1329
+ if (!isRecord(before) || !isRecord(after)) return [];
1330
+ const result = [];
1331
+ const visibleInput = (input) => {
1332
+ var _input$;
1333
+ return Array.isArray(input) ? (_input$ = input[1]) !== null && _input$ !== void 0 ? _input$ : input[2] : input;
1334
+ };
1335
+ for (const group of ["inputs", "fields"]) {
1336
+ const oldGroup = isRecord(before[group]) ? before[group] : {};
1337
+ const newGroup = isRecord(after[group]) ? after[group] : {};
1338
+ for (const name of /* @__PURE__ */ new Set([...Object.keys(oldGroup), ...Object.keys(newGroup)])) {
1339
+ const a = oldGroup[name], b = newGroup[name];
1340
+ if (group === "inputs" ? !equal(visibleInput(a), visibleInput(b)) : !equal(a, b)) result.push({
1341
+ kind: group === "inputs" ? "input" : "field",
1342
+ name
1343
+ });
1344
+ }
1345
+ }
1346
+ return result;
1347
+ }
1348
+ function compareProjectBlocks(before, after) {
1349
+ const oldTargets = new Map(before.targets.map((target) => [targetKey(target), target]));
1350
+ const newTargets = new Map(after.targets.map((target) => [targetKey(target), target]));
1351
+ const changes = [];
1352
+ let unchanged = 0;
1353
+ for (const key of /* @__PURE__ */ new Set([...oldTargets.keys(), ...newTargets.keys()])) {
1354
+ var _oldTarget$blocks, _newTarget$blocks;
1355
+ const oldTarget = oldTargets.get(key), newTarget = newTargets.get(key);
1356
+ const oldBlocks = (_oldTarget$blocks = oldTarget === null || oldTarget === void 0 ? void 0 : oldTarget.blocks) !== null && _oldTarget$blocks !== void 0 ? _oldTarget$blocks : {}, newBlocks = (_newTarget$blocks = newTarget === null || newTarget === void 0 ? void 0 : newTarget.blocks) !== null && _newTarget$blocks !== void 0 ? _newTarget$blocks : {};
1357
+ for (const id of /* @__PURE__ */ new Set([...Object.keys(oldBlocks), ...Object.keys(newBlocks)])) {
1358
+ const hadBlock = Object.hasOwn(oldBlocks, id), hasBlock = Object.hasOwn(newBlocks, id);
1359
+ const a = oldBlocks[id], b = newBlocks[id];
1360
+ if (hadBlock && hasBlock && equal(a, b)) {
1361
+ unchanged++;
1362
+ continue;
1363
+ }
1364
+ const fields = isRecord(a) && isRecord(b) ? [.../* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)])].filter((field) => !equal(a[field], b[field])) : [];
1365
+ changes.push({
1366
+ key: JSON.stringify([key, id]),
1367
+ before: hadBlock && oldTarget ? {
1368
+ target: oldTarget,
1369
+ id
1370
+ } : void 0,
1371
+ after: hasBlock && newTarget ? {
1372
+ target: newTarget,
1373
+ id
1374
+ } : void 0,
1375
+ kind: !hadBlock ? "added" : !hasBlock ? "removed" : "updated",
1376
+ fields,
1377
+ parts: changedParts(a, b)
1378
+ });
1379
+ }
1380
+ }
1381
+ const withoutBlocks = (project) => _objectSpread2(_objectSpread2({}, project), {}, { targets: project.targets.map((_ref) => {
1382
+ let { blocks: _ } = _ref;
1383
+ return _objectWithoutProperties(_ref, _excluded);
1384
+ }) });
1385
+ return {
1386
+ changes,
1387
+ unchanged,
1388
+ otherChanges: !equal(withoutBlocks(before), withoutBlocks(after))
1389
+ };
1390
+ }
739
1391
  // src/project-asset-paths.ts
740
1392
  /** The largest asset a thumbnail reads. */
741
1393
  var assetLimit = 10485760;
@@ -758,4 +1410,4 @@ function assetsDirectoryParts(settings) {
758
1410
  const parts = value.split("/");
759
1411
  return parts.every((part) => part && part !== "." && part !== ".." && part.toLowerCase() !== ".git" && !/[\\\0-\x1f\x7f]/.test(part)) ? parts : null;
760
1412
  }
761
- export { createTwoFilesPatch as a, isAssetName as i, assetsDirectoryParts as n, hasOnlyUnixLineEndings as o, folderSettingsLimit as r, hasOnlyWinLineEndings as s, assetLimit as t };
1413
+ export { compareProjectBlocks as a, isRecord as c, targetKey as d, createTwoFilesPatch as f, isAssetName as i, parseProjectSource as l, assetsDirectoryParts as n, createProjectSourceDiff as o, folderSettingsLimit as r, equal as s, assetLimit as t, readProjectSourceDiff as u };