599
return '..\\'.repeat(fromLen - i) + toSplit.slice(i).join('\\');
600
}
602
>
// Trim any leading backslashes
603
>
let fromStart = 0;
604
>
while (fromStart < from.length &&
605
>
from.charCodeAt(fromStart) === CHAR_BACKWARD_SLASH) {
606
>
fromStart++;
607
>
}
608
>
// Trim trailing backslashes (applicable to UNC paths only)
609
>
let fromEnd = from.length;
610
>
while (fromEnd - 1 > fromStart &&
611
>
from.charCodeAt(fromEnd - 1) === CHAR_BACKWARD_SLASH) {
612
>
fromEnd--;
613
>
}
614
>
const fromLen = fromEnd - fromStart;
615
>
616
>
// Trim any leading backslashes
617
>
let toStart = 0;
618
>
while (toStart < to.length &&
619
>
to.charCodeAt(toStart) === CHAR_BACKWARD_SLASH) {
620
>
toStart++;
621
>
}
622
>
// Trim trailing backslashes (applicable to UNC paths only)
623
>
let toEnd = to.length;
624
>
while (toEnd - 1 > toStart &&
625
>
to.charCodeAt(toEnd - 1) === CHAR_BACKWARD_SLASH) {
626
>
toEnd--;
627
>
}
628
>
const toLen = toEnd - toStart;
629
>
630
>
// Compare paths to find the longest common path from root
631
>
const length = fromLen < toLen ? fromLen : toLen;
632
>
let lastCommonSep = -1;
633
>
let i = 0;
634
>
for (; i < length; i++) {
635
>
const fromCode = from.charCodeAt(fromStart + i);
636
>
if (fromCode !== to.charCodeAt(toStart + i)) {
637
>
break;
638
>
} else if (fromCode === CHAR_BACKWARD_SLASH) {
639
>
lastCommonSep = i;
640
>
}
641
>
}
642
>
643
>
// We found a mismatch before the first common path separator was seen, so
644
>
// return the original `to`.
645
>
if (i !== length) {
646
>
if (lastCommonSep === -1) {
647
>
return toOrig;
648
>
}
649
>
} else {
650
>
if (toLen > length) {
651
>
if (to.charCodeAt(toStart + i) === CHAR_BACKWARD_SLASH) {
652
>
// We get here if `from` is the exact base path for `to`.
653
>
// For example: from='C:\\foo\\bar'; to='C:\\foo\\bar\\baz'
654
>
return toOrig.slice(toStart + i + 1);
655
>
}
656
>
if (i === 2) {
657
// We get here if `from` is the device root.
658
// For example: from='C:\\'; to='C:\\foo'
659
return toOrig.slice(toStart + i);
660
}
662
>
if (fromLen > length) {
663
>
if (from.charCodeAt(fromStart + i) === CHAR_BACKWARD_SLASH) {
664
>
// We get here if `to` is the exact base path for `from`.
665
>
// For example: from='C:\\foo\\bar'; to='C:\\foo'
666
>
lastCommonSep = i;
667
>
} else if (i === 2) {
668
// We get here if `to` is the device root.
669
// For example: from='C:\\foo\\bar'; to='C:\\'
670
lastCommonSep = 3;
671
}
673
>
if (lastCommonSep === -1) {
674
lastCommonSep = 0;
675
}
677
>
678
>
let out = '';
679
>
// Generate the relative path based on the path difference between `to` and
680
>
// `from`
681
>
for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {
682
>
if (i === fromEnd || from.charCodeAt(i) === CHAR_BACKWARD_SLASH) {
683
>
out += out.length === 0 ? '..' : '\\..';
684
>
}
685
>
}
686
>
687
>
toStart += lastCommonSep;
688
>
689
>
// Lastly, append the rest of the destination (`to`) path that comes after
690
>
// the common path parts
691
>
if (out.length > 0) {
692
>
return `${out}${toOrig.slice(toStart, toEnd)}`;
693
>
}
694
695
if (toOrig.charCodeAt(toStart) === CHAR_BACKWARD_SLASH) {