<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Velopack Blog</title>
        <link>https://docs.velopack.io/es/blog</link>
        <description>Velopack Blog</description>
        <lastBuildDate>Sun, 31 May 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>es</language>
        <item>
            <title><![CDATA[Your dependencies are a liability]]></title>
            <link>https://docs.velopack.io/es/blog/2026/05/31/supply-chain-attacks</link>
            <guid>https://docs.velopack.io/es/blog/2026/05/31/supply-chain-attacks</guid>
            <pubDate>Sun, 31 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[If you've been paying attention to the security space over the last couple of years, you've probably noticed a trend. Supply chain attacks are everywhere. They affect everyone: that tiny utility package buried deep in your dependency tree, giant companies with teams of engineers, solo maintainers, and everyone in between.]]></description>
            <content:encoded><![CDATA[<p>If you've been paying attention to the security space over the last couple of years, you've probably noticed a trend. Supply chain attacks are everywhere. They affect everyone: that tiny utility package buried deep in your dependency tree, giant companies with teams of engineers, solo maintainers, and everyone in between.</p>
<p>I've been thinking about this a lot recently, partly because we went through the exercise of hardening our own repos at Velopack, and partly because some of the attacks that surfaced recently are genuinely terrifying. I wanted to talk about what's been happening, why it matters, and what you can actually do about it.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="some-attacks-that-should-keep-you-up-at-night">Some attacks that should keep you up at night<a href="https://docs.velopack.io/es/blog/2026/05/31/supply-chain-attacks#some-attacks-that-should-keep-you-up-at-night" class="hash-link" aria-label="Enlace directo al Some attacks that should keep you up at night" title="Enlace directo al Some attacks that should keep you up at night" translate="no">​</a></h2>
<p>The one that set the tone was <strong>XZ Utils</strong> in early 2024. A threat actor spent <em>two and a half years</em> building trust as a contributor to a widely used Linux compression library. They submitted helpful patches, did code reviews, gradually became a co-maintainer. Then they slipped a backdoor into the build process, hidden inside obfuscated test fixture files. It scored a perfect 10.0 CVSS and would have given them remote code execution on basically any Linux server running OpenSSH. The only reason it got caught was because a Microsoft engineer noticed his SSH connections were using slightly more CPU than usual. Two years of social engineering, and the detection mechanism was one person noticing a performance blip. No automated tool, no CI check, no scanner caught it. Just luck.</p>
<p>The <strong>Axios</strong> compromise in early 2026 was a different kind of wake-up call. Axios gets around 70 million downloads a week on npm. A North Korean state actor compromised the lead maintainer's PC through social engineering, stole their npm credentials, and published trojanized versions that installed a RAT on anyone who updated. The malicious versions were live for about three hours, and because of how npm version ranges work (<code>^1.14.0</code>), CI pipelines across the ecosystem automatically pulled in the compromised version.</p>
<p><strong>Shai-Hulud</strong> in late 2025 was the first self-replicating npm worm. It started with phishing emails that looked like they came from npm, asking developers to "update" their MFA settings. Once they had a developer's token, the worm would automatically find every other package that developer maintained, inject malicious postinstall scripts, and publish new versions. No human in the loop. It infected around 200 packages before it was contained, and CISA had to put out an advisory.</p>
<p>The <strong>tj-actions</strong> GitHub Actions compromise in March 2025 hit 23,000+ repositories by poisoning a widely-used action's version tags so they pointed to malicious code. The <strong>Ultralytics</strong> (YOLO) PyPI compromise happened through a GitHub Actions script injection vulnerability, and the malicious code only existed in the PyPI-distributed package, not in the source repo. The <strong>Polyfill.io</strong> takeover was someone buying the domain and CDN, then injecting malicious redirects into 100,000+ websites.</p>
<p>Every major package ecosystem has been hit. npm, PyPI, crates.io, NuGet, Go modules, none of them are immune.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-these-attacks-actually-work">How these attacks actually work<a href="https://docs.velopack.io/es/blog/2026/05/31/supply-chain-attacks#how-these-attacks-actually-work" class="hash-link" aria-label="Enlace directo al How these attacks actually work" title="Enlace directo al How these attacks actually work" translate="no">​</a></h2>
<p>If you look at the patterns, a few attack vectors come up repeatedly.</p>
<p><strong>Maintainer account compromise</strong> is the most dangerous. Phishing for credentials, social engineering, malware on a developer's machine. The attacker publishes from a trusted account to a trusted package. No typo in the name, no unfamiliar publisher, it looks completely legitimate. The Axios attack is the textbook example.</p>
<p><strong>Typosquatting and dependency confusion</strong> are the most common by volume. Publishing <code>requets</code> instead of <code>requests</code>, or registering a public package with the same name as a company's internal package. Sonatype has logged over a million malicious packages across registries, and the vast majority are this type. Each individual one has limited impact, but at scale it adds up.</p>
<p><strong>CI/CD pipeline attacks</strong> are the force multiplier. If you can compromise a build pipeline, every artifact it produces is tainted, and CI systems are implicitly trusted. The Ultralytics attack stole PyPI upload tokens through a GitHub Actions vulnerability. The LiteLLM compromise in 2026 happened because their CI pipeline used a compromised security scanner, which exfiltrated their PyPI publishing tokens.</p>
<p><strong>Build script abuse</strong> is easy to overlook. npm's <code>postinstall</code>, Cargo's <code>build.rs</code>, Python's <code>setup.py</code> all execute arbitrary code with full system privileges at install time, before any runtime sandboxing kicks in. Only about 2% of npm packages actually need postinstall scripts, but the mechanism is there for all of them.</p>
<p><strong>Developer tooling and IDE extensions</strong> are a growing attack surface, and one that scales with team size. Every developer on your team who installs a VS Code extension is a potential entry point. In May 2026, the popular <strong>Nx Console</strong> extension (2.2 million installs, Verified Publisher badge) was compromised after a contributor's GitHub token was stolen through a separate supply chain attack on TanStack. The attacker pushed a malicious version that was live for just 18 minutes, but auto-updates pushed it to around 6,000 installs. One of those installs was on a GitHub employee's machine, and the stolen credentials were used to exfiltrate 3,800 internal GitHub repositories. Separately, two AI coding assistant extensions marketed as ChatGPT tools were found exfiltrating every source file developers opened back to servers in China, with a combined 1.5 million installs. The more developers you have, the more IDE extensions, browser tools, and local utilities are in play, and each one is a trust boundary you're probably not auditing.</p>
<p>The through-line here is that most of these attacks don't require finding a vulnerability in code. They exploit trust in maintainers, registries, CI systems, and the build process itself.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-we-did-about-it">What we did about it<a href="https://docs.velopack.io/es/blog/2026/05/31/supply-chain-attacks#what-we-did-about-it" class="hash-link" aria-label="Enlace directo al What we did about it" title="Enlace directo al What we did about it" translate="no">​</a></h2>
<p>We recently went through our repos at Velopack and tightened things up. Here's what that looked like in practice, and what I'd suggest if you haven't done this yet.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="lock-your-dependencies">Lock your dependencies<a href="https://docs.velopack.io/es/blog/2026/05/31/supply-chain-attacks#lock-your-dependencies" class="hash-link" aria-label="Enlace directo al Lock your dependencies" title="Enlace directo al Lock your dependencies" translate="no">​</a></h3>
<p>Commit your lockfiles (<code>Cargo.lock</code>, <code>package-lock.json</code>, etc.) and use them in CI. For Rust, that means adding <code>--locked</code> to every <code>cargo build</code>, <code>cargo test</code>, and <code>cargo clippy</code> command in your workflows. This ensures CI uses the exact versions you tested locally and fails if the lockfile is out of date. Without this, a compromised dependency could publish a new semver-compatible version and your CI would silently pick it up.</p>
<p>For GitHub Actions, <strong>pin actions to full commit SHAs</strong> instead of version tags. The tj-actions attack worked because tags are mutable. The attacker moved the tag to point at malicious code. A commit SHA can't be changed after the fact.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="run-dependency-audits-in-ci">Run dependency audits in CI<a href="https://docs.velopack.io/es/blog/2026/05/31/supply-chain-attacks#run-dependency-audits-in-ci" class="hash-link" aria-label="Enlace directo al Run dependency audits in CI" title="Enlace directo al Run dependency audits in CI" translate="no">​</a></h3>
<p>We added <a href="https://github.com/EmbarkStudios/cargo-deny" target="_blank" rel="noopener noreferrer" class="">cargo-deny</a> to our CI pipeline, which checks four things on every build:</p>
<ul>
<li class=""><strong>Advisories</strong>: does any dependency have a known vulnerability in the RustSec database?</li>
<li class=""><strong>Licenses</strong>: is every dependency using an approved license? (we maintain an explicit allowlist)</li>
<li class=""><strong>Bans</strong>: are there any wildcard version requirements that could pull in anything?</li>
<li class=""><strong>Sources</strong>: is every dependency coming from an expected registry?</li>
</ul>
<p>The npm equivalent would be something like <code>npm audit</code> or <a href="https://socket.dev/" target="_blank" rel="noopener noreferrer" class="">Socket</a>. The point is to automate this so it runs on every PR, not just when someone remembers to check.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="delay-non-security-updates">Delay non-security updates<a href="https://docs.velopack.io/es/blog/2026/05/31/supply-chain-attacks#delay-non-security-updates" class="hash-link" aria-label="Enlace directo al Delay non-security updates" title="Enlace directo al Delay non-security updates" translate="no">​</a></h3>
<p>We configured Renovate to wait 14 days before proposing updates for non-security patches. Most malicious package versions get caught and pulled within 24-72 hours. A two-week buffer means you're almost never the first to discover a compromised version.</p>
<p>Security vulnerabilities bypass this delay entirely. We set those to create PRs immediately with a <code>security</code> label so they don't get lost.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="restrict-ci-permissions">Restrict CI permissions<a href="https://docs.velopack.io/es/blog/2026/05/31/supply-chain-attacks#restrict-ci-permissions" class="hash-link" aria-label="Enlace directo al Restrict CI permissions" title="Enlace directo al Restrict CI permissions" translate="no">​</a></h3>
<p>By default, GitHub Actions tokens have write access to your repository. That's more than most workflows need. Set <code>permissions: contents: read</code> at the workflow level and only escalate where necessary. If a compromised action runs in your workflow, the blast radius is much smaller when the token can only read.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="other-things-worth-doing">Other things worth doing<a href="https://docs.velopack.io/es/blog/2026/05/31/supply-chain-attacks#other-things-worth-doing" class="hash-link" aria-label="Enlace directo al Other things worth doing" title="Enlace directo al Other things worth doing" translate="no">​</a></h3>
<p><strong>Use OIDC-based "trusted publishers"</strong> for package registries if they support it (PyPI and npm both do now). Your CI publishes packages using short-lived tokens tied to your specific workflow, instead of long-lived API keys that can be stolen and used from anywhere.</p>
<p><strong>Disable postinstall scripts</strong> where possible. <code>npm config set ignore-scripts true</code> or use pnpm, then explicitly whitelist the packages that actually need them. This eliminates one of the most common payload delivery mechanisms.</p>
<p><strong>Enforce MFA on all registry accounts</strong>, preferably hardware keys. The Shai-Hulud phishing attack used a transparent proxy that forwarded credentials to the real npm site, TOTP codes included. Hardware security keys (FIDO2/WebAuthn) would have blocked it because they're bound to the actual domain.</p>
<p><strong>Evaluate new dependencies before adding them.</strong> Check the <a href="https://scorecard.dev/" target="_blank" rel="noopener noreferrer" class="">OpenSSF Scorecard</a>, look at the maintainer's activity, consider whether you actually need the package or if you're pulling in a library for something you could write in 20 lines. Every dependency is a trust relationship. Fewer dependencies means fewer things that can go wrong.</p>
<p><strong>Audit your team's IDE extensions.</strong> After the Nx Console and MaliciousCorgi incidents, this should be on every organization's radar. Consider maintaining an approved list of extensions, or at minimum disabling auto-updates for extensions so compromised versions don't silently roll out across your team.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-uncomfortable-truth">The uncomfortable truth<a href="https://docs.velopack.io/es/blog/2026/05/31/supply-chain-attacks#the-uncomfortable-truth" class="hash-link" aria-label="Enlace directo al The uncomfortable truth" title="Enlace directo al The uncomfortable truth" translate="no">​</a></h2>
<p>There's no silver bullet. The XZ Utils attack bypassed everything. It was a trusted maintainer with legitimate access making changes that passed review. No lockfile, no scanner, no audit tool would have caught it.</p>
<p>What we can do is raise the bar. The vast majority of supply chain attacks are far less sophisticated than XZ. They're someone publishing <code>ax1os</code> and hoping a developer fat-fingers their install command, or spraying phishing emails at maintainers. The defenses I've listed here handle most of those.</p>
<p>Most of this stuff takes an afternoon to set up. Adding <code>--locked</code> to your CI commands is a one-line change. Setting up cargo-deny or npm audit is maybe an hour of work. Configuring a release age delay on Renovate is a config file change. The cost is low and the protection is real.</p>
<p>If you maintain open source, or really any project with dependencies, take an afternoon and go through this list. Your future self will thank you when the next big supply chain incident drops and your build pipeline isn't blindly trusting everything the internet hands it.</p>]]></content:encoded>
            <category>security</category>
            <category>supply-chain</category>
            <category>ci</category>
            <category>dependencies</category>
        </item>
        <item>
            <title><![CDATA[What a Data Router/Loader is and why you need it!]]></title>
            <link>https://docs.velopack.io/es/blog/2024/05/24/seemless-router-preloading</link>
            <guid>https://docs.velopack.io/es/blog/2024/05/24/seemless-router-preloading</guid>
            <pubDate>Fri, 24 May 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[In the last year we've seen a shift in react-router and @tanstack-router towards the idea of a "Data Router" or "Loader" which allows you to strongly tie your data fetching directly to your router. There are some benefits and drawbacks to this approach, but overall if it's done well it can result in a very measurable improvement to user experience.]]></description>
            <content:encoded><![CDATA[<p>In the last year we've seen a shift in <code>react-router</code> and <code>@tanstack-router</code> towards the idea of a "Data Router" or "Loader" which allows you to strongly tie your data fetching directly to your router. There are some benefits and drawbacks to this approach, but overall if it's done well it can result in a very measurable improvement to user experience.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="whats-the-big-deal-anyway">What's the big deal anyway?<a href="https://docs.velopack.io/es/blog/2024/05/24/seemless-router-preloading#whats-the-big-deal-anyway" class="hash-link" aria-label="Enlace directo al What's the big deal anyway?" title="Enlace directo al What's the big deal anyway?" translate="no">​</a></h2>
<p>There is a flaw underpinning many React applications, called "render/fetch chains" or sometimes "waterfall loading". What this refers to is the phenomenon where you end up with a series of ajax requests to load required data, one after another with <code>useEffect</code> instead of loading data in parallel
The reason this happens is data fetching is tightly coupled to component rendering.</p>
<p>Image a scenario where a parent component needs to fetch before rendering (perhaps showing a loading spinner in the meantime). Once it's loaded it's data it renders itself and any children. Now imagine a child <em>also</em> needs to fetch some data. It can only get started after the parent has fully loaded since the data fetch happens once the child renders. Here's an example:</p>
<div class="language-jsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-jsx codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token keyword module" style="color:hsl(301, 63%, 40%)">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">React</span><span class="token imports punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token imports"> </span><span class="token imports punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token imports"> useEffect</span><span class="token imports punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token imports"> useState </span><span class="token imports punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword module" style="color:hsl(301, 63%, 40%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">'react'</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token comment" style="color:hsl(230, 4%, 64%)">// Simulating a data fetching function which takes 3s to complete</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:hsl(221, 87%, 60%)">fetchData</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:hsl(221, 87%, 60%)">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Promise</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token parameter">resolve</span><span class="token plain"> </span><span class="token arrow operator" style="color:hsl(221, 87%, 60%)">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">setTimeout</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:hsl(221, 87%, 60%)">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">resolve</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"Data loaded"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">3000</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">function</span><span class="token plain"> </span><span class="token function maybe-class-name" style="color:hsl(221, 87%, 60%)">ParentComponent</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> setData</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">useState</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword null nil" style="color:hsl(301, 63%, 40%)">null</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token plain">loading</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> setLoading</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">useState</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token boolean" style="color:hsl(35, 99%, 36%)">true</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token function" style="color:hsl(221, 87%, 60%)">useEffect</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:hsl(221, 87%, 60%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token function" style="color:hsl(221, 87%, 60%)">fetchData</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token method function property-access" style="color:hsl(221, 87%, 60%)">then</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token parameter">data</span><span class="token plain"> </span><span class="token arrow operator" style="color:hsl(221, 87%, 60%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">      </span><span class="token function" style="color:hsl(221, 87%, 60%)">setData</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">      </span><span class="token function" style="color:hsl(221, 87%, 60%)">setLoading</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token boolean" style="color:hsl(35, 99%, 36%)">false</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token keyword control-flow" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">loading</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag" style="color:hsl(5, 74%, 59%)">p</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text">Loading...</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;/</span><span class="token tag" style="color:hsl(5, 74%, 59%)">p</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token keyword control-flow" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag" style="color:hsl(5, 74%, 59%)">div</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain-text">        </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag" style="color:hsl(5, 74%, 59%)">h1</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text">Parent Component</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;/</span><span class="token tag" style="color:hsl(5, 74%, 59%)">h1</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain-text">        </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag" style="color:hsl(5, 74%, 59%)">p</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;/</span><span class="token tag" style="color:hsl(5, 74%, 59%)">p</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain-text">        </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag class-name" style="color:hsl(35, 99%, 36%)">ChildComponent</span><span class="token tag" style="color:hsl(5, 74%, 59%)"> </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">/&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain-text">    </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;/</span><span class="token tag" style="color:hsl(5, 74%, 59%)">div</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">function</span><span class="token plain"> </span><span class="token function maybe-class-name" style="color:hsl(221, 87%, 60%)">ChildComponent</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> setData</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">useState</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword null nil" style="color:hsl(301, 63%, 40%)">null</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token plain">loading</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> setLoading</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">useState</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token boolean" style="color:hsl(35, 99%, 36%)">true</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token function" style="color:hsl(221, 87%, 60%)">useEffect</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:hsl(221, 87%, 60%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token function" style="color:hsl(221, 87%, 60%)">fetchData</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token method function property-access" style="color:hsl(221, 87%, 60%)">then</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token parameter">data</span><span class="token plain"> </span><span class="token arrow operator" style="color:hsl(221, 87%, 60%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">      </span><span class="token function" style="color:hsl(221, 87%, 60%)">setData</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">      </span><span class="token function" style="color:hsl(221, 87%, 60%)">setLoading</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token boolean" style="color:hsl(35, 99%, 36%)">false</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token keyword control-flow" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">loading</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag" style="color:hsl(5, 74%, 59%)">p</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text">Loading...</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;/</span><span class="token tag" style="color:hsl(5, 74%, 59%)">p</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token keyword control-flow" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag" style="color:hsl(5, 74%, 59%)">div</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain-text">        </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag" style="color:hsl(5, 74%, 59%)">h2</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text">Child Component</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;/</span><span class="token tag" style="color:hsl(5, 74%, 59%)">h2</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain-text">        </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag" style="color:hsl(5, 74%, 59%)">p</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;/</span><span class="token tag" style="color:hsl(5, 74%, 59%)">p</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain-text">    </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;/</span><span class="token tag" style="color:hsl(5, 74%, 59%)">div</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword module" style="color:hsl(301, 63%, 40%)">export</span><span class="token plain"> </span><span class="token keyword module" style="color:hsl(301, 63%, 40%)">default</span><span class="token plain"> </span><span class="token maybe-class-name">ParentComponent</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><br></div></code></pre></div></div>
<p>This is a super common pattern. It's also a very bad pattern. The larger your app becomes, the slower things get as more component hierarchy gets added.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="enter-the-router-loader">Enter the Router Loader<a href="https://docs.velopack.io/es/blog/2024/05/24/seemless-router-preloading#enter-the-router-loader" class="hash-link" aria-label="Enlace directo al Enter the Router Loader" title="Enlace directo al Enter the Router Loader" translate="no">​</a></h2>
<p>Libraries such as react-router (version 6.4 and above) and @tanstack/router have introduced significant improvements by adding "Data Loading" as a core feature. These router libraries manage streamline data fetching directly within the routing layer. This approach leverages the router's awareness of the component hierarchy and lifecycle to optimally schedule and parallelize data fetching tasks before the components even begin rendering.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="benefits-of-using-a-data-routerloader">Benefits of Using a Data Router/Loader<a href="https://docs.velopack.io/es/blog/2024/05/24/seemless-router-preloading#benefits-of-using-a-data-routerloader" class="hash-link" aria-label="Enlace directo al Benefits of Using a Data Router/Loader" title="Enlace directo al Benefits of Using a Data Router/Loader" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="parallel-data-fetching">Parallel Data Fetching<a href="https://docs.velopack.io/es/blog/2024/05/24/seemless-router-preloading#parallel-data-fetching" class="hash-link" aria-label="Enlace directo al Parallel Data Fetching" title="Enlace directo al Parallel Data Fetching" translate="no">​</a></h4>
<p>By initiating all required data fetching at the router level, these libraries can load data in parallel rather than sequentially. This significantly reduces the total time waiting for data across nested routes, avoiding the "waterfall" effect seen in traditional React data fetching patterns.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="decoupling-data-fetching-from-ui-rendering">Decoupling Data Fetching from UI Rendering<a href="https://docs.velopack.io/es/blog/2024/05/24/seemless-router-preloading#decoupling-data-fetching-from-ui-rendering" class="hash-link" aria-label="Enlace directo al Decoupling Data Fetching from UI Rendering" title="Enlace directo al Decoupling Data Fetching from UI Rendering" translate="no">​</a></h4>
<p>This architecture separates the concerns of data fetching and UI rendering. Components are responsible solely for presenting data and handling user interactions, not for fetching the data they display. This separation makes the components more reusable and easier to manage.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="improved-user-experience">Improved User Experience<a href="https://docs.velopack.io/es/blog/2024/05/24/seemless-router-preloading#improved-user-experience" class="hash-link" aria-label="Enlace directo al Improved User Experience" title="Enlace directo al Improved User Experience" translate="no">​</a></h4>
<p>Loading data before rendering the component tree means that users see a complete UI without awkward loading states popping in sequentially. This can significantly improve the perceived performance of your application.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="simplified-component-logic">Simplified Component Logic<a href="https://docs.velopack.io/es/blog/2024/05/24/seemless-router-preloading#simplified-component-logic" class="hash-link" aria-label="Enlace directo al Simplified Component Logic" title="Enlace directo al Simplified Component Logic" translate="no">​</a></h4>
<p>Components no longer need to manage their own data fetching logic with useEffect and state. The router loader handles all the asynchronous logic, simplifying your React components and making them cleaner and more focused on their primary function—rendering UI.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="potential-drawbacks">Potential Drawbacks<a href="https://docs.velopack.io/es/blog/2024/05/24/seemless-router-preloading#potential-drawbacks" class="hash-link" aria-label="Enlace directo al Potential Drawbacks" title="Enlace directo al Potential Drawbacks" translate="no">​</a></h3>
<p>While the benefits are considerable, there are a few trade-offs to consider:</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="increased-complexity-in-the-router">Increased Complexity in the Router<a href="https://docs.velopack.io/es/blog/2024/05/24/seemless-router-preloading#increased-complexity-in-the-router" class="hash-link" aria-label="Enlace directo al Increased Complexity in the Router" title="Enlace directo al Increased Complexity in the Router" translate="no">​</a></h4>
<p>The logic for data fetching moves into the routing configuration, which can become complex if not managed carefully. This might increase the learning curve or the amount of boilerplate code, especially in large applications with many routes and data dependencies.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="less-flexibility-for-dynamic-fetching-conditions">Less Flexibility for Dynamic Fetching Conditions<a href="https://docs.velopack.io/es/blog/2024/05/24/seemless-router-preloading#less-flexibility-for-dynamic-fetching-conditions" class="hash-link" aria-label="Enlace directo al Less Flexibility for Dynamic Fetching Conditions" title="Enlace directo al Less Flexibility for Dynamic Fetching Conditions" translate="no">​</a></h4>
<p>Since data fetching is configured per-route, dynamically changing fetching logic based on component state or props can be more cumbersome. You might need additional patterns or libraries to handle more complex, dynamic scenarios.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="code-sample">Code Sample<a href="https://docs.velopack.io/es/blog/2024/05/24/seemless-router-preloading#code-sample" class="hash-link" aria-label="Enlace directo al Code Sample" title="Enlace directo al Code Sample" translate="no">​</a></h2>
<p>I'll take our code sample from earlier and update it for loaders:</p>
<div class="language-jsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-jsx codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token keyword module" style="color:hsl(301, 63%, 40%)">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">React</span><span class="token plain"> </span><span class="token keyword module" style="color:hsl(301, 63%, 40%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">'react'</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword module" style="color:hsl(301, 63%, 40%)">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token imports"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token imports">  </span><span class="token imports maybe-class-name">BrowserRouter</span><span class="token imports"> </span><span class="token imports keyword module" style="color:hsl(301, 63%, 40%)">as</span><span class="token imports"> </span><span class="token imports maybe-class-name">Router</span><span class="token imports punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token imports"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token imports">  </span><span class="token imports maybe-class-name">Route</span><span class="token imports punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token imports"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token imports">  </span><span class="token imports maybe-class-name">Routes</span><span class="token imports punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token imports"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token imports">  </span><span class="token imports maybe-class-name">Outlet</span><span class="token imports punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token imports"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token imports">  useLoaderData</span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token imports"></span><span class="token imports punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword module" style="color:hsl(301, 63%, 40%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">'react-router-dom'</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token comment" style="color:hsl(230, 4%, 64%)">// Simulating a data fetching function which takes 3s to complete</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:hsl(221, 87%, 60%)">fetchData</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:hsl(221, 87%, 60%)">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Promise</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token parameter">resolve</span><span class="token plain"> </span><span class="token arrow operator" style="color:hsl(221, 87%, 60%)">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">setTimeout</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:hsl(221, 87%, 60%)">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">resolve</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"Data loaded"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">3000</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token comment" style="color:hsl(230, 4%, 64%)">// Data loader function for the parent component</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">async</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">parentLoader</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> data </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:hsl(301, 63%, 40%)">await</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">fetchData</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token keyword control-flow" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:hsl(5, 74%, 59%)">parentData</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> data </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token comment" style="color:hsl(230, 4%, 64%)">// Data loader function for the child component</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">async</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">childLoader</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> data </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:hsl(301, 63%, 40%)">await</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">fetchData</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token keyword control-flow" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:hsl(5, 74%, 59%)">childData</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> data </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">function</span><span class="token plain"> </span><span class="token function maybe-class-name" style="color:hsl(221, 87%, 60%)">ParentComponent</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> parentData </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">useLoaderData</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token keyword control-flow" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag" style="color:hsl(5, 74%, 59%)">div</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag" style="color:hsl(5, 74%, 59%)">h1</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text">Parent Component</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;/</span><span class="token tag" style="color:hsl(5, 74%, 59%)">h1</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag" style="color:hsl(5, 74%, 59%)">p</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain">parentData</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;/</span><span class="token tag" style="color:hsl(5, 74%, 59%)">p</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag class-name" style="color:hsl(35, 99%, 36%)">Outlet</span><span class="token tag" style="color:hsl(5, 74%, 59%)"> </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">/&gt;</span><span class="token plain-text">  </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token comment" style="color:hsl(230, 4%, 64%)">/* Child components will be rendered here */</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain-text">    </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;/</span><span class="token tag" style="color:hsl(5, 74%, 59%)">div</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">function</span><span class="token plain"> </span><span class="token function maybe-class-name" style="color:hsl(221, 87%, 60%)">ChildComponent</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> childData </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">useLoaderData</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token keyword control-flow" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag" style="color:hsl(5, 74%, 59%)">div</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag" style="color:hsl(5, 74%, 59%)">h2</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text">Child Component</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;/</span><span class="token tag" style="color:hsl(5, 74%, 59%)">h2</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag" style="color:hsl(5, 74%, 59%)">p</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain">childData</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;/</span><span class="token tag" style="color:hsl(5, 74%, 59%)">p</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain-text">    </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;/</span><span class="token tag" style="color:hsl(5, 74%, 59%)">div</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> router </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">createBrowserRouter</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token literal-property property" style="color:hsl(5, 74%, 59%)">path</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"/"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token literal-property property" style="color:hsl(5, 74%, 59%)">element</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag class-name" style="color:hsl(35, 99%, 36%)">ParentComponent</span><span class="token tag" style="color:hsl(5, 74%, 59%)"> </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">/&gt;</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token literal-property property" style="color:hsl(5, 74%, 59%)">loader</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> parentLoader</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token literal-property property" style="color:hsl(5, 74%, 59%)">children</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token literal-property property" style="color:hsl(5, 74%, 59%)">path</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"child"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token literal-property property" style="color:hsl(5, 74%, 59%)">element</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag class-name" style="color:hsl(35, 99%, 36%)">ChildComponent</span><span class="token tag" style="color:hsl(5, 74%, 59%)"> </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">/&gt;</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token literal-property property" style="color:hsl(5, 74%, 59%)">loader</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> childLoader</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">function</span><span class="token plain"> </span><span class="token function maybe-class-name" style="color:hsl(221, 87%, 60%)">App</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token keyword control-flow" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag class-name" style="color:hsl(35, 99%, 36%)">RouterProvider</span><span class="token tag" style="color:hsl(5, 74%, 59%)"> </span><span class="token tag attr-name" style="color:hsl(35, 99%, 36%)">router</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:hsl(119, 34%, 47%)">=</span><span class="token tag script language-javascript punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token tag script language-javascript" style="color:hsl(5, 74%, 59%)">router</span><span class="token tag script language-javascript punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token tag" style="color:hsl(5, 74%, 59%)"> </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">/&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword module" style="color:hsl(301, 63%, 40%)">export</span><span class="token plain"> </span><span class="token keyword module" style="color:hsl(301, 63%, 40%)">default</span><span class="token plain"> </span><span class="token maybe-class-name">App</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><br></div></code></pre></div></div>
<p>In the above sample we can see that the data loading is defined in our router from the beginning - so when the user navigates to <code>/child</code>, react-router can get going fetching both the parent and child data simultaneously. The UX here can be further enhanced (and easily) by using deferred data and React Suspense enabling you to show placeholder UI instead of generic spinners, but I'll save that for another topic.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="react-router-vs-tanstackrouter---which-to-use"><code>react-router</code> vs. <code>@tanstack/router</code> - Which to use?<a href="https://docs.velopack.io/es/blog/2024/05/24/seemless-router-preloading#react-router-vs-tanstackrouter---which-to-use" class="hash-link" aria-label="Enlace directo al react-router-vs-tanstackrouter---which-to-use" title="Enlace directo al react-router-vs-tanstackrouter---which-to-use" translate="no">​</a></h2>
<p>It's no question that react-router used to be the king of React SPA navigation before it was acquired by Remix in 2024. Since the acquisition though, it's clear that drastic changes are being made to fit it in better to their commercial offering and community feedback is being largely ignored. Also, it's missing out on several key features.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="react-router">react-router<a href="https://docs.velopack.io/es/blog/2024/05/24/seemless-router-preloading#react-router" class="hash-link" aria-label="Enlace directo al react-router" title="Enlace directo al react-router" translate="no">​</a></h4>
<ul>
<li class=""><strong>Pro:</strong> Has a huge legacy and is more widely used</li>
<li class=""><strong>Con:</strong> Limited TypeScript support (more runtime errors)</li>
<li class=""><strong>Con:</strong> Core logic is not exported, making it very hard to integrate with non-standard use-cases</li>
<li class=""><strong>Con:</strong> New versions often have rewrite-inducing major changes</li>
<li class=""><strong>Con:</strong> No ability to customize pre/loader behaviors (eg. timeouts)</li>
<li class=""><strong>Con:</strong> In order to make use of loaders properly, you need to switch from traditional <code>Route</code> components to a data router which many people will not be familiar with.</li>
<li class=""><strong>Con:</strong> Documentation is atrocious and unsearchable.</li>
</ul>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="tanstackrouter">@tanstack/router<a href="https://docs.velopack.io/es/blog/2024/05/24/seemless-router-preloading#tanstackrouter" class="hash-link" aria-label="Enlace directo al @tanstack/router" title="Enlace directo al @tanstack/router" translate="no">​</a></h4>
<ul>
<li class=""><strong>Pro:</strong> First class TypeScript support in all aspects</li>
<li class=""><strong>Pro:</strong> Smaller / simpler code base</li>
<li class=""><strong>Pro:</strong> Supports code-based routing (like react-router) but also supports auto-generated routing based on file names.</li>
<li class=""><strong>Pro:</strong> API is very clean and mostly exported, resulting in a very extensible and customisable solution</li>
<li class=""><strong>Pro:</strong> Very customizable data loading behaviors, with fully deferred, partially with timeouts, etc</li>
<li class=""><strong>Pro:</strong> Intent based Preloading (eg. user hovering on a link) allows you to speed up data loading even further</li>
<li class=""><strong>Pro:</strong> Documented integrations with <code>@tanstack/query</code> (formerly <code>react-query</code>) which is already widely used.</li>
<li class=""><strong>Con:</strong> <code>@tanstack/router</code> is the new kid on the block.</li>
</ul>
<p>I might be biased, but I think it's clear from the list above that <code>@tanstack/router</code> is the winner for me.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion">Conclusion<a href="https://docs.velopack.io/es/blog/2024/05/24/seemless-router-preloading#conclusion" class="hash-link" aria-label="Enlace directo al Conclusion" title="Enlace directo al Conclusion" translate="no">​</a></h2>
<p>Adopting a Data Router/Loader can significantly enhance the structure and performance of large-scale React applications by optimizing data fetching strategies. While this approach introduces some complexities, the overall benefits in terms of performance gains and cleaner code generally outweigh these concerns. As with any architectural decision, it’s crucial to evaluate whether the specific benefits align with the needs and scale of your project.</p>
<p>Incorporating a Data Router/Loader could be a game changer for your React app, ensuring that data management is as efficient and unobtrusive as possible. As you refactor or start new projects, consider how leveraging these advanced routing capabilities might enhance both developer experience and your UX.</p>]]></content:encoded>
            <category>react</category>
            <category>ui</category>
            <category>router</category>
            <category>typescript</category>
        </item>
        <item>
            <title><![CDATA[Portable SymbolicLink in .NET]]></title>
            <link>https://docs.velopack.io/es/blog/2024/03/19/portable-dotnet-symlinks</link>
            <guid>https://docs.velopack.io/es/blog/2024/03/19/portable-dotnet-symlinks</guid>
            <pubDate>Tue, 19 Mar 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Due to .app bundles on OSX requiring me to preserve internal symlinks in Velopack, I've had to work on a cross-platform and cross-framework implementation for handling symlinks.]]></description>
            <content:encoded><![CDATA[<p>Due to <code>.app</code> bundles on OSX requiring me to preserve internal symlinks in <a href="https://velopack.io/" target="_blank" rel="noopener noreferrer" class="">Velopack</a>, I've had to work on a cross-platform and cross-framework implementation for handling symlinks.</p>
<p>If you're only targeting <code>.NET 6</code> and higher, you can stop reading here - because there's already great support in the framework via <code>FileSystemInfo.LinkTarget</code>, <code>Directory.CreateSymbolicLink</code> and other built-in methods.</p>
<p>If you need to target the Full .Net Framework, then read on...</p>
<p>If you just want the final code without the prologue, <a href="https://docs.velopack.io/es/blog/2024/03/19/portable-dotnet-symlinks#final-solution" class="">then click here</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="starting-point">Starting Point<a href="https://docs.velopack.io/es/blog/2024/03/19/portable-dotnet-symlinks#starting-point" class="hash-link" aria-label="Enlace directo al Starting Point" title="Enlace directo al Starting Point" translate="no">​</a></h2>
<p>As I eluded to above, the addition of cross platform varients will simplify things for us on other operating systems, so I started by writing an API which delegates to those functions.</p>
<div class="language-cs codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cs codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">internal</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">class</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">SymbolicLink</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">public</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">void</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">Create</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">bool</span><span class="token plain"> overwrite </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(35, 99%, 36%)">true</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        linkPath </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetFullPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        targetPath </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetFullPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token plain">Directory</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&amp;&amp;</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token plain">File</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">IOException</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"Target path does not exist."</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Directory</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">||</span><span class="token plain"> File</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">overwrite</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                Utility</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">DeleteFileOrDirectoryHard</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">IOException</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"Junction / symlink path already exists and overwrite parameter is false."</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">var</span><span class="token plain"> finalTarget </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token return-type class-name" style="color:hsl(35, 99%, 36%)">relative</span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token return-type class-name" style="color:hsl(35, 99%, 36%)">            </span><span class="token return-type class-name punctuation" style="color:hsl(119, 34%, 47%)">?</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">GetRelativePath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetDirectoryName</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Directory</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            Directory</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">CreateSymbolicLink</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> finalTarget</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">else</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">File</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            File</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">CreateSymbolicLink</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> finalTarget</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">IOException</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"Target path does not exist."</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">public</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">bool</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">TryGetLinkFsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">out</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">var</span><span class="token plain"> _</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">public</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">void</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">Delete</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">var</span><span class="token plain"> isLink </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">TryGetLinkFsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">out</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">var</span><span class="token plain"> fsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">fsi </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">null</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&amp;&amp;</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token plain">isLink</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">IOException</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"Path is not a junction point."</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            fsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">?.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Delete</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">public</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">GetTarget</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token function" style="color:hsl(221, 87%, 60%)">TryGetLinkFsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">out</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">var</span><span class="token plain"> fsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> fsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">LinkTarget</span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">IOException</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"Path does not exist or is not a junction point / symlink."</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">bool</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">TryGetLinkFsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">out</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">FileSystemInfo</span><span class="token plain"> fsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        fsi </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">null</span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Directory</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            fsi </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">DirectoryInfo</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">else</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">File</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            fsi </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">FileInfo</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> fsi </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">null</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">fsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Attributes </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&amp;</span><span class="token plain"> FileAttributes</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">ReparsePoint</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><br></div></code></pre></div></div>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</div><div class="admonitionContent_BuS1"><p>The <code>Utility.DeleteFileOrDirectoryHard()</code> function is provided by internal code in Velopack to delete a file or directory. If you are implementing this yourself, take care not to delete a directory recursively that contains junctions or symlinks, because it is possible to create cyclic junctions. If you encounter a directory with the <code>FileAttributes.ReparsePoint</code> flag, then you should just delete it rather than recursing.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="support-for-net-framework">Support for .Net Framework<a href="https://docs.velopack.io/es/blog/2024/03/19/portable-dotnet-symlinks#support-for-net-framework" class="hash-link" aria-label="Enlace directo al Support for .Net Framework" title="Enlace directo al Support for .Net Framework" translate="no">​</a></h2>
<p>I cheated slightly with the implementation of the above API, because I copied the public API of the <a href="https://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=15633" target="_blank" rel="noopener noreferrer" class="">JunctionPoint.cs</a> library by Jeff Brown on CodeProject, hoping to just copy it in to my project and conditionally compile in one or the other.</p>
<p><a href="https://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=15633" target="_blank" rel="noopener noreferrer" class="">JunctionPoint.cs</a>, was great, but unfortunately it only supports directory junctions and not file links. I set out to enhance this library as is, but things have moved on and there are higher level abstractions in Win32 these days, so I scrapped and moved on to something simpler:</p>
<div class="language-cs codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cs codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token attribute class-name" style="color:hsl(35, 99%, 36%)">DllImport</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token attribute attribute-arguments string" style="color:hsl(119, 34%, 47%)">"kernel32.dll"</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token attribute attribute-arguments"> CharSet </span><span class="token attribute attribute-arguments operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token attribute attribute-arguments"> CharSet</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token attribute attribute-arguments">Unicode</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token attribute attribute-arguments"> SetLastError </span><span class="token attribute attribute-arguments operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token attribute attribute-arguments"> </span><span class="token attribute attribute-arguments boolean" style="color:hsl(35, 99%, 36%)">true</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">extern</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">bool</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">CreateSymbolicLink</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> lpSymlinkFileName</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> lpTargetFileName</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> dwFlags</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token attribute class-name" style="color:hsl(35, 99%, 36%)">DllImport</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token attribute attribute-arguments string" style="color:hsl(119, 34%, 47%)">"Kernel32.dll"</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token attribute attribute-arguments"> SetLastError </span><span class="token attribute attribute-arguments operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token attribute attribute-arguments"> </span><span class="token attribute attribute-arguments boolean" style="color:hsl(35, 99%, 36%)">true</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token attribute attribute-arguments"> CharSet </span><span class="token attribute attribute-arguments operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token attribute attribute-arguments"> CharSet</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token attribute attribute-arguments">Auto</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">extern</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">GetFinalPathNameByHandle</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">IntPtr</span><span class="token plain"> hFile</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token attribute class-name" style="color:hsl(35, 99%, 36%)">MarshalAs</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token attribute attribute-arguments">UnmanagedType</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token attribute attribute-arguments">LPTStr</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">StringBuilder</span><span class="token plain"> lpszFilePath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> cchFilePath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> dwFlags</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><br></div></code></pre></div></div>
<p>The <code>CreateSymbolicLink</code> and <code>GetFinalPathNameByHandle</code> provide simple solutions which I could conditionally compile in on the full framework, for example:</p>
<div class="language-cs codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cs codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Directory</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)">#</span><span class="token preprocessor property directive keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)"> NETFRAMEWORK</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token function" style="color:hsl(221, 87%, 60%)">CreateSymbolicLink</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> finalTarget</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> SYMBOLIC_LINK_FLAG_DIRECTORY </span><span class="token operator" style="color:hsl(221, 87%, 60%)">|</span><span class="token plain"> SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token function" style="color:hsl(221, 87%, 60%)">ThrowLastWin32Error</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"Unable to create junction point / symlink."</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)">#</span><span class="token preprocessor property directive keyword" style="color:hsl(301, 63%, 40%)">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    Directory</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">CreateSymbolicLink</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> finalTarget</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)">#</span><span class="token preprocessor property directive keyword" style="color:hsl(301, 63%, 40%)">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><br></div></code></pre></div></div>
<p>This is enough if all you need to do is support absolute paths.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="adding-relative-paths">Adding Relative Paths<a href="https://docs.velopack.io/es/blog/2024/03/19/portable-dotnet-symlinks#adding-relative-paths" class="hash-link" aria-label="Enlace directo al Adding Relative Paths" title="Enlace directo al Adding Relative Paths" translate="no">​</a></h2>
<p>I was relatively happy with the simplicitly of the solution above, but since I was preserving symlinks within a self-contained application bundle, I needed support for relative paths, when creating and reading symlinks.</p>
<p>Unfortunately <code>Path.GetRelativePath</code> only exists on .NET, so we'll need a new implementation for that, which I stole from <a href="https://github.com/RT-Projects/RT.Util/blob/690d15694dacde9234a8f39eb0d9ba6db34e249d/RT.Util.Core/Paths/PathUtil.cs#L297" target="_blank" rel="noopener noreferrer" class="">RT.Util</a> - a project written my a friend of mine.</p>
<p>Also <code>GetFinalPathNameByHandle</code> resolves relative paths to absolute paths before it gets back to us, so we're going to have to switch back to using <code>DeviceIoControl</code> which I was hoping to avoid.</p>
<p>This function didn't turn out too complicated, but writing it involved a lot of searching on the topic, debugging, and so forth.</p>
<p>One of the things I got stuck on (without realising it) is that <code>CreateFile</code> is very picky when it comes to the flags passed in. You need <code>FILE_FLAG_BACKUP_SEMANTICS</code> and <code>FILE_FLAG_OPEN_REPARSE_POINT</code>.</p>
<div class="language-cs codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cs codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">GetTargetWin32</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">// https://github.com/microsoft/BuildXL/blob/main/Public/Src/Utilities/Native/IO/Windows/FileSystem.Win.cs#L2711</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">// http://blog.kalmbach-software.de/2008/02/28/howto-correctly-read-reparse-data-in-vista/</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">// https://github.com/dotnet/runtime/blob/e5f0c361f5baea5e2b56e1776143d841b0cc6e6c/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Windows.cs#L544</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">SafeFileHandle</span><span class="token plain"> handle </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">CreateFile</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token named-parameter punctuation" style="color:hsl(119, 34%, 47%)">dwDesiredAccess</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        FileShare</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">ReadWrite </span><span class="token operator" style="color:hsl(221, 87%, 60%)">|</span><span class="token plain"> FileShare</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Delete</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token named-parameter punctuation" style="color:hsl(119, 34%, 47%)">lpSecurityAttributes</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> IntPtr</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Zero</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        FileMode</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Open</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token named-parameter punctuation" style="color:hsl(119, 34%, 47%)">dwFlagsAndAttributes</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> EFileAttributes</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">BackupSemantics </span><span class="token operator" style="color:hsl(221, 87%, 60%)">|</span><span class="token plain"> EFileAttributes</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">OpenReparsePoint</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token named-parameter punctuation" style="color:hsl(119, 34%, 47%)">hTemplateFile</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> IntPtr</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Zero</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Marshal</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetLastWin32Error</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token function" style="color:hsl(221, 87%, 60%)">ThrowLastWin32Error</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"Unable to open reparse point."</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> bufferSize </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> INITIAL_REPARSE_DATA_BUFFER_SIZE</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> errorCode </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> ERROR_INSUFFICIENT_BUFFER</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">byte</span><span class="token class-name punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token class-name punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"> buffer </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">null</span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">while</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">errorCode </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> ERROR_MORE_DATA </span><span class="token operator" style="color:hsl(221, 87%, 60%)">||</span><span class="token plain"> errorCode </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> ERROR_INSUFFICIENT_BUFFER</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        buffer </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name keyword" style="color:hsl(301, 63%, 40%)">byte</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token plain">bufferSize</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">bool</span><span class="token plain"> success </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(35, 99%, 36%)">false</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> bufferReturnedSize</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        success </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">DeviceIoControl</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            handle</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            FSCTL_GET_REPARSE_POINT</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            IntPtr</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Zero</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            buffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            bufferSize</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">out</span><span class="token plain"> bufferReturnedSize</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            IntPtr</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Zero</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        bufferSize </span><span class="token operator" style="color:hsl(221, 87%, 60%)">*=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">2</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        errorCode </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> success </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">?</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> Marshal</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetLastWin32Error</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">errorCode </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">Win32Exception</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">errorCode</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> PrintNameOffsetIndex </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">12</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> PrintNameLengthIndex </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">14</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> SubsNameOffsetIndex </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">8</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> SubsNameLengthIndex </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">10</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> reparsePointTag </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> BitConverter</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">ToUInt32</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">buffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">reparsePointTag </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!=</span><span class="token plain"> IO_REPARSE_TAG_SYMLINK </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&amp;&amp;</span><span class="token plain"> reparsePointTag </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!=</span><span class="token plain"> IO_REPARSE_TAG_MOUNT_POINT</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">NotSupportedException</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token interpolation-string string" style="color:hsl(119, 34%, 47%)">$"Reparse point tag </span><span class="token interpolation-string interpolation punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token interpolation-string interpolation expression language-csharp">reparsePointTag</span><span class="token interpolation-string interpolation format-string punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token interpolation-string interpolation format-string">X</span><span class="token interpolation-string interpolation punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token interpolation-string string" style="color:hsl(119, 34%, 47%)"> not supported"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> pathBufferOffsetIndex </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">reparsePointTag </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> IO_REPARSE_TAG_SYMLINK</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">?</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">20</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">16</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> nameOffset </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> BitConverter</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">ToInt16</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">buffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> PrintNameOffsetIndex</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> nameLength </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> BitConverter</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">ToInt16</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">buffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> PrintNameLengthIndex</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> targetPath </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> Encoding</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Unicode</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetString</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">buffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> pathBufferOffsetIndex </span><span class="token operator" style="color:hsl(221, 87%, 60%)">+</span><span class="token plain"> nameOffset</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> nameLength</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">IsNullOrWhiteSpace</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        nameOffset </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> BitConverter</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">ToInt16</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">buffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> SubsNameOffsetIndex</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        nameLength </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> BitConverter</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">ToInt16</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">buffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> SubsNameLengthIndex</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        targetPath </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> Encoding</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Unicode</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetString</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">buffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> pathBufferOffsetIndex </span><span class="token operator" style="color:hsl(221, 87%, 60%)">+</span><span class="token plain"> nameOffset</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> nameLength</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="final-solution">Final Solution<a href="https://docs.velopack.io/es/blog/2024/03/19/portable-dotnet-symlinks#final-solution" class="hash-link" aria-label="Enlace directo al Final Solution" title="Enlace directo al Final Solution" translate="no">​</a></h2>
<p>The final code works for .Net Framework, as well as NET 6.0 and above. It supports writing/reading both absolute or relative paths. The code is released as a part of Velopack, which is under the MIT license.</p>
<div class="language-cs codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cs codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">internal</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">class</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">SymbolicLink</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// &lt;summary&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// Creates a symlink from the specified directory to the specified target directory.</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// &lt;/summary&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// &lt;param name="linkPath"&gt;The symlink path&lt;/param&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// &lt;param name="targetPath"&gt;The target directory or file&lt;/param&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// &lt;param name="overwrite"&gt;If true overwrites an existing reparse point or empty directory&lt;/param&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// &lt;param name="relative"&gt;If true, stores a relative path from the link to the target, rather than an absolute path.&lt;/param&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">public</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">void</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">Create</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">bool</span><span class="token plain"> overwrite </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(35, 99%, 36%)">true</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">bool</span><span class="token plain"> relative </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(35, 99%, 36%)">false</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        linkPath </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetFullPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        targetPath </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetFullPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token plain">Directory</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&amp;&amp;</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token plain">File</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">IOException</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"Target path does not exist."</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Directory</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">||</span><span class="token plain"> File</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">overwrite</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                Utility</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">DeleteFileOrDirectoryHard</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">IOException</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"Junction / symlink path already exists and overwrite parameter is false."</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">var</span><span class="token plain"> finalTarget </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token return-type class-name" style="color:hsl(35, 99%, 36%)">relative</span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token return-type class-name" style="color:hsl(35, 99%, 36%)">            </span><span class="token return-type class-name punctuation" style="color:hsl(119, 34%, 47%)">?</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">GetRelativePath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetDirectoryName</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Directory</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)">#</span><span class="token preprocessor property directive keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)"> NETFRAMEWORK</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token function" style="color:hsl(221, 87%, 60%)">CreateSymbolicLink</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> finalTarget</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> SYMBOLIC_LINK_FLAG_DIRECTORY </span><span class="token operator" style="color:hsl(221, 87%, 60%)">|</span><span class="token plain"> SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                </span><span class="token function" style="color:hsl(221, 87%, 60%)">ThrowLastWin32Error</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"Unable to create junction point / symlink."</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)">#</span><span class="token preprocessor property directive keyword" style="color:hsl(301, 63%, 40%)">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            Directory</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">CreateSymbolicLink</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> finalTarget</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)">#</span><span class="token preprocessor property directive keyword" style="color:hsl(301, 63%, 40%)">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">else</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">File</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)">#</span><span class="token preprocessor property directive keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)"> NETFRAMEWORK</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token function" style="color:hsl(221, 87%, 60%)">CreateSymbolicLink</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> finalTarget</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> SYMBOLIC_LINK_FLAG_FILE </span><span class="token operator" style="color:hsl(221, 87%, 60%)">|</span><span class="token plain"> SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                </span><span class="token function" style="color:hsl(221, 87%, 60%)">ThrowLastWin32Error</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"Unable to create junction point / symlink."</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)">#</span><span class="token preprocessor property directive keyword" style="color:hsl(301, 63%, 40%)">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            File</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">CreateSymbolicLink</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> finalTarget</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)">#</span><span class="token preprocessor property directive keyword" style="color:hsl(301, 63%, 40%)">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">IOException</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"Target path does not exist."</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// &lt;summary&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// Returns true if the specified path exists and is a junction point or symlink.</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// If the path exists but is not a junction point or symlink, returns false.</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// &lt;/summary&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">public</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">bool</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">TryGetLinkFsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">out</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">var</span><span class="token plain"> _</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// &lt;summary&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// Does nothing if the path does not exist. If the path exists but is not </span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// a junction / symlink, throws an IOException.</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// &lt;/summary&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">public</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">void</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">Delete</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">var</span><span class="token plain"> isLink </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">TryGetLinkFsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">out</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">var</span><span class="token plain"> fsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">fsi </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">null</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&amp;&amp;</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token plain">isLink</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">IOException</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"Path is not a junction point."</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            fsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">?.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Delete</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// &lt;summary&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// Get the target of a junction point or symlink.</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// &lt;/summary&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// &lt;param name="linkPath"&gt;The location of the symlink or junction point&lt;/param&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// &lt;param name="resolve"&gt;If true, will return the full path to the target.</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// If false, will return the link target unadulterated - so it may be a </span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token comment" style="color:hsl(230, 4%, 64%)">/// relative or an absolute path.&lt;/param&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">public</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">GetTarget</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">bool</span><span class="token plain"> resolve </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(35, 99%, 36%)">true</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token function" style="color:hsl(221, 87%, 60%)">TryGetLinkFsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">out</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">var</span><span class="token plain"> fsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> target</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)">#</span><span class="token preprocessor property directive keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)"> NETFRAMEWORK</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            target </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">GetTargetWin32</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)">#</span><span class="token preprocessor property directive keyword" style="color:hsl(301, 63%, 40%)">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            target </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> fsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">LinkTarget</span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)">#</span><span class="token preprocessor property directive keyword" style="color:hsl(301, 63%, 40%)">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token plain">resolve</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> target</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">IsPathRooted</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">target</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                </span><span class="token comment" style="color:hsl(230, 4%, 64%)">// if the path is absolute, we can return it as is.</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetFullPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">target</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                </span><span class="token comment" style="color:hsl(230, 4%, 64%)">// if it is a relative path, we need to resolve it as it relates to the location of linkPath</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetFullPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Combine</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetDirectoryName</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> target</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">IOException</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"Path does not exist or is not a junction point / symlink."</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">bool</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">TryGetLinkFsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">out</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">FileSystemInfo</span><span class="token plain"> fsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        fsi </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">null</span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Directory</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            fsi </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">DirectoryInfo</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">else</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">File</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Exists</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            fsi </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">FileInfo</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> fsi </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">null</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">fsi</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Attributes </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&amp;</span><span class="token plain"> FileAttributes</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">ReparsePoint</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">GetRelativePath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> relativeTo</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)">#</span><span class="token preprocessor property directive keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)"> NETFRAMEWORK</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        relativeTo </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetFullPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">relativeTo</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        path </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetFullPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">ToggleRelative</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">relativeTo</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)">#</span><span class="token preprocessor property directive keyword" style="color:hsl(301, 63%, 40%)">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetRelativePath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">relativeTo</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)">#</span><span class="token preprocessor property directive keyword" style="color:hsl(301, 63%, 40%)">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)">#</span><span class="token preprocessor property directive keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)"> NETFRAMEWORK</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token plain">Flags</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">enum</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">EFileAttributes</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> </span><span class="token type-list keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        Readonly </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x00000001</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        Hidden </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x00000002</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        System </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x00000004</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        Directory </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x00000010</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        Archive </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x00000020</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        Device </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x00000040</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        Normal </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x00000080</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        Temporary </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x00000100</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        SparseFile </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x00000200</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        ReparsePoint </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x00000400</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        Compressed </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x00000800</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        Offline </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x00001000</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        NotContentIndexed </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x00002000</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        Encrypted </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x00004000</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        Write_Through </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x80000000</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        Overlapped </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x40000000</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        NoBuffering </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x20000000</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        RandomAccess </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x10000000</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        SequentialScan </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x08000000</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        DeleteOnClose </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x04000000</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        BackupSemantics </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x02000000</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        PosixSemantics </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x01000000</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        OpenReparsePoint </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x00200000</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        OpenNoRecall </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x00100000</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        FirstPipeInstance </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x00080000</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token attribute class-name" style="color:hsl(35, 99%, 36%)">DllImport</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token attribute attribute-arguments string" style="color:hsl(119, 34%, 47%)">"kernel32.dll"</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token attribute attribute-arguments"> CharSet </span><span class="token attribute attribute-arguments operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token attribute attribute-arguments"> CharSet</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token attribute attribute-arguments">Unicode</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token attribute attribute-arguments"> SetLastError </span><span class="token attribute attribute-arguments operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token attribute attribute-arguments"> </span><span class="token attribute attribute-arguments boolean" style="color:hsl(35, 99%, 36%)">true</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">extern</span><span class="token plain"> </span><span class="token return-type class-name" style="color:hsl(35, 99%, 36%)">SafeFileHandle</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">CreateFile</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> lpFileName</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">FileAccess</span><span class="token plain"> dwDesiredAccess</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">FileShare</span><span class="token plain"> dwShareMode</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">IntPtr</span><span class="token plain"> lpSecurityAttributes</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">FileMode</span><span class="token plain"> dwCreationDisposition</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">EFileAttributes</span><span class="token plain"> dwFlagsAndAttributes</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">IntPtr</span><span class="token plain"> hTemplateFile</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token attribute class-name" style="color:hsl(35, 99%, 36%)">DllImport</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token attribute attribute-arguments string" style="color:hsl(119, 34%, 47%)">"kernel32.dll"</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token attribute attribute-arguments"> CharSet </span><span class="token attribute attribute-arguments operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token attribute attribute-arguments"> CharSet</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token attribute attribute-arguments">Unicode</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token attribute attribute-arguments"> SetLastError </span><span class="token attribute attribute-arguments operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token attribute attribute-arguments"> </span><span class="token attribute attribute-arguments boolean" style="color:hsl(35, 99%, 36%)">true</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">extern</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">bool</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">CreateSymbolicLink</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> lpSymlinkFileName</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> lpTargetFileName</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> dwFlags</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> SYMBOLIC_LINK_FLAG_FILE </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> SYMBOLIC_LINK_FLAG_DIRECTORY </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x1</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x2</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> INITIAL_REPARSE_DATA_BUFFER_SIZE </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">1024</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> FSCTL_GET_REPARSE_POINT </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x000900a8</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> ERROR_INSUFFICIENT_BUFFER </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0x7A</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> ERROR_MORE_DATA </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0xEA</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> IO_REPARSE_TAG_SYMLINK </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0xA000000C</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> IO_REPARSE_TAG_MOUNT_POINT </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0xA0000003</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token attribute class-name" style="color:hsl(35, 99%, 36%)">DllImport</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token attribute attribute-arguments string" style="color:hsl(119, 34%, 47%)">"Kernel32.dll"</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token attribute attribute-arguments"> SetLastError </span><span class="token attribute attribute-arguments operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token attribute attribute-arguments"> </span><span class="token attribute attribute-arguments boolean" style="color:hsl(35, 99%, 36%)">true</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token attribute attribute-arguments"> CharSet </span><span class="token attribute attribute-arguments operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token attribute attribute-arguments"> CharSet</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token attribute attribute-arguments">Auto</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">extern</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">GetFinalPathNameByHandle</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name" style="color:hsl(35, 99%, 36%)">IntPtr</span><span class="token plain"> hFile</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token attribute class-name" style="color:hsl(35, 99%, 36%)">MarshalAs</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token attribute attribute-arguments">UnmanagedType</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token attribute attribute-arguments">LPTStr</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">StringBuilder</span><span class="token plain"> lpszFilePath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> cchFilePath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> dwFlags</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token attribute class-name" style="color:hsl(35, 99%, 36%)">DllImport</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token attribute attribute-arguments string" style="color:hsl(119, 34%, 47%)">"kernel32.dll"</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token attribute attribute-arguments"> SetLastError </span><span class="token attribute attribute-arguments operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token attribute attribute-arguments"> </span><span class="token attribute attribute-arguments boolean" style="color:hsl(35, 99%, 36%)">true</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token attribute target keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token attribute punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token attribute"> </span><span class="token attribute class-name" style="color:hsl(35, 99%, 36%)">MarshalAs</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token attribute attribute-arguments">UnmanagedType</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token attribute attribute-arguments">Bool</span><span class="token attribute attribute-arguments punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">extern</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">bool</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">DeviceIoControl</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">SafeFileHandle</span><span class="token plain"> deviceHandle</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> ioControlCode</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">IntPtr</span><span class="token plain"> inputBuffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> inputBufferSize</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">byte</span><span class="token class-name punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token class-name punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"> outputBuffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> outputBufferSize</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">out</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> bytesReturned</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">IntPtr</span><span class="token plain"> overlapped</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">GetTargetWin32</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token comment" style="color:hsl(230, 4%, 64%)">// https://github.com/microsoft/BuildXL/blob/main/Public/Src/Utilities/Native/IO/Windows/FileSystem.Win.cs#L2711</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token comment" style="color:hsl(230, 4%, 64%)">// http://blog.kalmbach-software.de/2008/02/28/howto-correctly-read-reparse-data-in-vista/</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token comment" style="color:hsl(230, 4%, 64%)">// https://github.com/dotnet/runtime/blob/e5f0c361f5baea5e2b56e1776143d841b0cc6e6c/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Windows.cs#L544</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">SafeFileHandle</span><span class="token plain"> handle </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">CreateFile</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            linkPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token named-parameter punctuation" style="color:hsl(119, 34%, 47%)">dwDesiredAccess</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            FileShare</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">ReadWrite </span><span class="token operator" style="color:hsl(221, 87%, 60%)">|</span><span class="token plain"> FileShare</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Delete</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token named-parameter punctuation" style="color:hsl(119, 34%, 47%)">lpSecurityAttributes</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> IntPtr</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Zero</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            FileMode</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Open</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token named-parameter punctuation" style="color:hsl(119, 34%, 47%)">dwFlagsAndAttributes</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> EFileAttributes</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">BackupSemantics </span><span class="token operator" style="color:hsl(221, 87%, 60%)">|</span><span class="token plain"> EFileAttributes</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">OpenReparsePoint</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token named-parameter punctuation" style="color:hsl(119, 34%, 47%)">hTemplateFile</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> IntPtr</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Zero</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Marshal</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetLastWin32Error</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token function" style="color:hsl(221, 87%, 60%)">ThrowLastWin32Error</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"Unable to open reparse point."</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> bufferSize </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> INITIAL_REPARSE_DATA_BUFFER_SIZE</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> errorCode </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> ERROR_INSUFFICIENT_BUFFER</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">byte</span><span class="token class-name punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token class-name punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"> buffer </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">null</span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">while</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">errorCode </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> ERROR_MORE_DATA </span><span class="token operator" style="color:hsl(221, 87%, 60%)">||</span><span class="token plain"> errorCode </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> ERROR_INSUFFICIENT_BUFFER</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            buffer </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name keyword" style="color:hsl(301, 63%, 40%)">byte</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token plain">bufferSize</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">bool</span><span class="token plain"> success </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(35, 99%, 36%)">false</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> bufferReturnedSize</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            success </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">DeviceIoControl</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                handle</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                FSCTL_GET_REPARSE_POINT</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                IntPtr</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Zero</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                buffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                bufferSize</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">out</span><span class="token plain"> bufferReturnedSize</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                IntPtr</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Zero</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            bufferSize </span><span class="token operator" style="color:hsl(221, 87%, 60%)">*=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">2</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            errorCode </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> success </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">?</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> Marshal</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetLastWin32Error</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">errorCode </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">Win32Exception</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">errorCode</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> PrintNameOffsetIndex </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">12</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> PrintNameLengthIndex </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">14</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> SubsNameOffsetIndex </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">8</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> SubsNameLengthIndex </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">10</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> reparsePointTag </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> BitConverter</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">ToUInt32</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">buffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">reparsePointTag </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!=</span><span class="token plain"> IO_REPARSE_TAG_SYMLINK </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&amp;&amp;</span><span class="token plain"> reparsePointTag </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!=</span><span class="token plain"> IO_REPARSE_TAG_MOUNT_POINT</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">NotSupportedException</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token interpolation-string string" style="color:hsl(119, 34%, 47%)">$"Reparse point tag </span><span class="token interpolation-string interpolation punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token interpolation-string interpolation expression language-csharp">reparsePointTag</span><span class="token interpolation-string interpolation format-string punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token interpolation-string interpolation format-string">X</span><span class="token interpolation-string interpolation punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token interpolation-string string" style="color:hsl(119, 34%, 47%)"> not supported"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token plain"> pathBufferOffsetIndex </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">uint</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">reparsePointTag </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> IO_REPARSE_TAG_SYMLINK</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">?</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">20</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">16</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> nameOffset </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> BitConverter</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">ToInt16</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">buffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> PrintNameOffsetIndex</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> nameLength </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> BitConverter</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">ToInt16</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">buffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> PrintNameLengthIndex</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> targetPath </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> Encoding</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Unicode</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetString</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">buffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> pathBufferOffsetIndex </span><span class="token operator" style="color:hsl(221, 87%, 60%)">+</span><span class="token plain"> nameOffset</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> nameLength</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">IsNullOrWhiteSpace</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            nameOffset </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> BitConverter</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">ToInt16</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">buffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> SubsNameOffsetIndex</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            nameLength </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> BitConverter</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">ToInt16</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">buffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> SubsNameLengthIndex</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            targetPath </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> Encoding</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Unicode</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetString</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">buffer</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> pathBufferOffsetIndex </span><span class="token operator" style="color:hsl(221, 87%, 60%)">+</span><span class="token plain"> nameOffset</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> nameLength</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> targetPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">void</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">ThrowLastWin32Error</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> message</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">IOException</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> Marshal</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetExceptionForHR</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Marshal</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetHRForLastWin32Error</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">ToggleRelative</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> basePath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> toggledPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token comment" style="color:hsl(230, 4%, 64%)">// from https://github.com/RT-Projects/RT.Util/blob/master/RT.Util.Core/Paths/PathUtil.cs#L297</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">basePath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Length </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">Exception</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"InvalidBasePath"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">toggledPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Length </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">Exception</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"InvalidToggledPath"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token plain">Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">IsPathRooted</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">basePath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">Exception</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"BasePathNotAbsolute"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">try</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> basePath </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetFullPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">basePath </span><span class="token operator" style="color:hsl(221, 87%, 60%)">+</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"\\"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">Exception</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"InvalidBasePath"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token operator" style="color:hsl(221, 87%, 60%)">!</span><span class="token plain">Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">IsPathRooted</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">toggledPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">try</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">StripTrailingSeparator</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetFullPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Combine</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">basePath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> toggledPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">                </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">Exception</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"InvalidToggledPath"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token comment" style="color:hsl(230, 4%, 64%)">// Both basePath and toggledPath are absolute. Need to relativize toggledPath.</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">try</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> toggledPath </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">GetFullPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">toggledPath </span><span class="token operator" style="color:hsl(221, 87%, 60%)">+</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"\\"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">Exception</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"InvalidToggledPath"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> prevPos </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">-</span><span class="token number" style="color:hsl(35, 99%, 36%)">1</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> pos </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> toggledPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">IndexOf</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">DirectorySeparatorChar</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">while</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">pos </span><span class="token operator" style="color:hsl(221, 87%, 60%)">!=</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">-</span><span class="token number" style="color:hsl(35, 99%, 36%)">1</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&amp;&amp;</span><span class="token plain"> pos </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&lt;</span><span class="token plain"> basePath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Length </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&amp;&amp;</span><span class="token plain"> basePath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Substring</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> pos </span><span class="token operator" style="color:hsl(221, 87%, 60%)">+</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">1</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Equals</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">toggledPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Substring</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> pos </span><span class="token operator" style="color:hsl(221, 87%, 60%)">+</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">1</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> StringComparison</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">OrdinalIgnoreCase</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            prevPos </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> pos</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            pos </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> toggledPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">IndexOf</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">DirectorySeparatorChar</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> pos </span><span class="token operator" style="color:hsl(221, 87%, 60%)">+</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">1</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">prevPos </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">-</span><span class="token number" style="color:hsl(35, 99%, 36%)">1</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">throw</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">Exception</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">"PathsOnDifferentDrives"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">var</span><span class="token plain"> piece </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> basePath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Substring</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">prevPos </span><span class="token operator" style="color:hsl(221, 87%, 60%)">+</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">1</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">var</span><span class="token plain"> result </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">StripTrailingSeparator</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token string" style="color:hsl(119, 34%, 47%)">".."</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">+</span><span class="token plain"> Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">DirectorySeparatorChar</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Repeat</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">piece</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Count</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">ch </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=&gt;</span><span class="token plain"> ch </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> Path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">DirectorySeparatorChar</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token operator" style="color:hsl(221, 87%, 60%)">+</span><span class="token plain"> toggledPath</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Substring</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">prevPos </span><span class="token operator" style="color:hsl(221, 87%, 60%)">+</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">1</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> result</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Length </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">?</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"."</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> result</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">Repeat</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">this</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> input</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> numTimes</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">numTimes </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">""</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">numTimes </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">1</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> input</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">numTimes </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">2</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> input </span><span class="token operator" style="color:hsl(221, 87%, 60%)">+</span><span class="token plain"> input</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">var</span><span class="token plain"> sb </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name" style="color:hsl(35, 99%, 36%)">StringBuilder</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">for</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">int</span><span class="token plain"> i </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"> i </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&lt;</span><span class="token plain"> numTimes</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"> i</span><span class="token operator" style="color:hsl(221, 87%, 60%)">++</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            sb</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Append</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">input</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> sb</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">ToString</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">private</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">static</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">StripTrailingSeparator</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token class-name keyword" style="color:hsl(301, 63%, 40%)">string</span><span class="token plain"> path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Length </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&lt;</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">1</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token plain">path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Length </span><span class="token operator" style="color:hsl(221, 87%, 60%)">-</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">1</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> </span><span class="token char" style="color:hsl(119, 34%, 47%)">'/'</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">||</span><span class="token plain"> path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token plain">path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Length </span><span class="token operator" style="color:hsl(221, 87%, 60%)">-</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">1</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> </span><span class="token char" style="color:hsl(119, 34%, 47%)">'\\'</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Length </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">3</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">&amp;&amp;</span><span class="token plain"> path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token number" style="color:hsl(35, 99%, 36%)">1</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">==</span><span class="token plain"> </span><span class="token char" style="color:hsl(119, 34%, 47%)">':'</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">?</span><span class="token plain"> path </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">:</span><span class="token plain"> path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">Substring</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token plain">Length </span><span class="token operator" style="color:hsl(221, 87%, 60%)">-</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">1</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">return</span><span class="token plain"> path</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token preprocessor property" style="color:hsl(5, 74%, 59%)">#</span><span class="token preprocessor property directive keyword" style="color:hsl(301, 63%, 40%)">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div></code></pre></div></div>]]></content:encoded>
            <category>cross-platform</category>
        </item>
        <item>
            <title><![CDATA[A developer's deployment nightmare]]></title>
            <link>https://docs.velopack.io/es/blog/2024/03/07/why-is-distribution-so-hard</link>
            <guid>https://docs.velopack.io/es/blog/2024/03/07/why-is-distribution-so-hard</guid>
            <pubDate>Thu, 07 Mar 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[In the world of software development, crafting the application is only half the battle. The other half? Getting your hard work onto the devices of users, which, let me tell you, is easier said than done. For those of us who have wrestled with the tangled web of software distribution, the headaches are all too familiar. It's like you're expected to be a jack-of-all-trades, mastering not one, not two, but a myriad of update frameworks and installers, each as diverse as the platforms and languages they cater to.]]></description>
            <content:encoded><![CDATA[<p>In the world of software development, crafting the application is only half the battle. The other half? Getting your hard work onto the devices of users, which, let me tell you, is easier said than done. For those of us who have wrestled with the tangled web of software distribution, the headaches are all too familiar. It's like you're expected to be a jack-of-all-trades, mastering not one, not two, but a myriad of update frameworks and installers, each as diverse as the platforms and languages they cater to.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-bane-of-cross-platform-distribution">The Bane of Cross-Platform Distribution<a href="https://docs.velopack.io/es/blog/2024/03/07/why-is-distribution-so-hard#the-bane-of-cross-platform-distribution" class="hash-link" aria-label="Enlace directo al The Bane of Cross-Platform Distribution" title="Enlace directo al The Bane of Cross-Platform Distribution" translate="no">​</a></h2>
<p>Imagine you've just developed this killer app. It's sleek, it's fast, and it's ready to make waves across Windows, macOS, and Linux. But wait, here comes the catch – updating this marvel. Suddenly, you're diving into the deep end of software update frameworks. For Windows, you might use Squirrel.Windows. For macOS, you're looking at Squirrel.Mac or Sparkle. And for Linux, oh boy, maybe AppImageUpdate, Snap, Flatpak, or a number of others.</p>
<p>And guess what? Each of these frameworks comes with its own set of quirks, documentation, setup, and debugging nightmares. You thought you signed up to be a developer, not a juggler, trying to keep all these different platforms and tools in the air. It's enough to make anyone question their life choices.</p>
<p>And what about if you're maintaining products written in different programming languages? You're stuck with this problem all over again because many of these frameworks are language specific.</p>
<p><em><strong>All this ultimately takes time away from time which could be spent improving your actual product.</strong></em></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-installer-conundrum">The Installer Conundrum<a href="https://docs.velopack.io/es/blog/2024/03/07/why-is-distribution-so-hard#the-installer-conundrum" class="hash-link" aria-label="Enlace directo al The Installer Conundrum" title="Enlace directo al The Installer Conundrum" translate="no">​</a></h2>
<p>Then there's the joy of dealing with installers. If you thought update frameworks were fun, installers are the party you never wanted to attend. Windows has WiX, NSIS, InnoSetup, or other commercial solutions, macOS prefers DMG or PKG, and Linux, well, it could be anything from a simple .deb to a more complex script. Each installer type is a world unto itself, requiring unique skills and knowledge to create and maintain.</p>
<p>The real kicker? Debugging. Something goes wrong, and suddenly you're deep in log files, trying to decipher where your installer decided to take a holiday. And let's not even start on the multitude of environments and versions your app needs to support. It's enough to give even the most seasoned developer a headache.</p>
<p>Not even going to mention CI, because now you're figuring out how to get all these tool working again in a possibly remote environment.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-common-approach-more-like-common-frustration">A Common Approach? More Like Common Frustration<a href="https://docs.velopack.io/es/blog/2024/03/07/why-is-distribution-so-hard#a-common-approach-more-like-common-frustration" class="hash-link" aria-label="Enlace directo al A Common Approach? More Like Common Frustration" title="Enlace directo al A Common Approach? More Like Common Frustration" translate="no">​</a></h2>
<p>So, how do we brave souls typically tackle this Herculean task? Some of us go down the path of learning and mastering each tool and framework needed for our app's distribution. It's time-consuming, it's frustrating, and let's be honest, it's incredibly inefficient. Others might opt for a team of specialists, each versed in the arcane arts of their respective platform's distribution. Effective, perhaps, but not exactly practical or cost-efficient for smaller teams or solo devs.</p>
<p>And through all this, we haven't even touched on the ongoing maintenance these frameworks require. Updates, bug fixes, platform changes – it's a never-ending cycle of toil and trouble.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-light-at-the-end-of-the-tunnel">The Light at the End of the Tunnel<a href="https://docs.velopack.io/es/blog/2024/03/07/why-is-distribution-so-hard#the-light-at-the-end-of-the-tunnel" class="hash-link" aria-label="Enlace directo al The Light at the End of the Tunnel" title="Enlace directo al The Light at the End of the Tunnel" translate="no">​</a></h2>
<p>Now, after painting quite the bleak picture, you might be wondering if there's any respite from this madness. Well, fellow developers, there is, and it goes by Velopack. Picture this: a single, streamlined framework that not only spans across Windows, macOS, and Linux but embraces a multitude of programming languages - so it goes with you no matter what app you're developing. A framework that's faster, smaller, handles updating, installing, eliminating the need to juggle a circus of tools and frameworks.</p>
<p>With Velopack, the promise is simple: learn once, apply everywhere. No more scrambling to keep up with the latest in installer technology or update frameworks. No more sleepless nights debugging a platform-specific distribution issue. Velopack offers a unified approach to software distribution, allowing developers to focus on what they do best – creating amazing software.</p>
<p><em><strong>Did I mention it's free to use?</strong></em></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="not-just-another-tool">Not Just Another Tool<a href="https://docs.velopack.io/es/blog/2024/03/07/why-is-distribution-so-hard#not-just-another-tool" class="hash-link" aria-label="Enlace directo al Not Just Another Tool" title="Enlace directo al Not Just Another Tool" translate="no">​</a></h2>
<p>Now, I know what you're thinking. "Great, another tool to learn." But hear me out. Velopack isn't just another drop in the ocean of software distribution tools. It's a lifeline thrown to developers drowning in the complexity of cross-platform distribution. By simplifying the process, Velopack frees up valuable time and resources, allowing us to channel our efforts into innovation and improvement, rather than maintenance and troubleshooting.</p>
<p>In the grand scheme of things, Velopack represents more than just a technical solution. It's a testament to the fact that sometimes, the best way to solve a complex problem is to step back and simplify. For developers tired of the distribution dance, Velopack offers a chance to change the tune, focusing on what matters most – delivering great software to our users.</p>
<p>So, if you're like me, fed up with the distribution dilemma and looking for a way out, give Velopack a try. It might just be the breath of fresh air your development process needs.</p>]]></content:encoded>
            <category>cross-platform</category>
            <category>squirrel</category>
            <category>pain</category>
            <category>deployment</category>
        </item>
        <item>
            <title><![CDATA[Choosing a documentation site generator]]></title>
            <link>https://docs.velopack.io/es/blog/2024/03/02/choosing-docs-site</link>
            <guid>https://docs.velopack.io/es/blog/2024/03/02/choosing-docs-site</guid>
            <pubDate>Sat, 02 Mar 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[There are plenty of great options available for static site documentation generators, I wouldn't even bother trying to name them all.]]></description>
            <content:encoded><![CDATA[<p>There are plenty of great options available for static site documentation generators, I wouldn't even bother trying to name them all.</p>
<p>The journey to find one that would work for <a class="" href="https://docs.velopack.io/es/">Velopack</a> was painful and took a few tries.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="docfx">Docfx<a href="https://docs.velopack.io/es/blog/2024/03/02/choosing-docs-site#docfx" class="hash-link" aria-label="Enlace directo al Docfx" title="Enlace directo al Docfx" translate="no">​</a></h2>
<p>Since we started out as a <code>C#</code> library, it made sense to start with <code>docfx</code>, which was appealing because if you just need to launch a documentation site as quickly as possible for a C# project, it seems to work well. The design is nothing to be proud of, but it's functional.</p>
<p>You can compile <code>.csproj</code> files to the corresponding docfx metadata (<code>.yml</code>), merge your extra markdown (<code>.md</code>) and output a static website in one command, and they even have <a href="https://dotnet.github.io/docfx/#publish-to-github-pages" target="_blank" rel="noopener noreferrer" class="">handy instructions on their homepage</a> on how to publish this to a Github Pages site.</p>
<p>Beyond the basics is where things started to get rough. We built the <a href="https://velopack.io/" target="_blank" rel="noopener noreferrer" class="">Velopack marketing site</a>, I wanted to merge the two sites together, but I spent many hours pulling our my hair getting docfx to work with relative url's that live in parent directories <code>../../the-website</code> for example. The solution I went with was in the website build script, copy all the files needed into the docfx project, build the site, and then copy the compiled assets back out. Far from elegant.</p>
<p>Also, good luck actually testing and seeing how anything looks - because there's no <code>watch</code> or <code>hmr</code> functionality built in, and compile times even for a small project could be as much as 10-20s. You need your own build scripts (eg. gulp) with watch built in if you want to get any real work done.</p>
<p>The next problem was styling. I wanted the documentation site to match the style of the marketing site, which I thought wouldn't be hard since they both used Bootstrap 5 (in fact, I picked Bootstrap 5 for the marketing site for this exact reason!). To get anything done, I needed to eject most of the underlying template files (which are handlebar based) and edit them directly. Since the template was already pre-compiled, the css it took to wrangle it into a good looking state was not "easy" per say, but bootstrap is fairly clean.</p>
<p>This site served us for a while. The design was okay (not great) and the built-in search was sub-par, but it worked for a month before I outgrew it and gave up. Velopack was expanding to support other programming langauges (Rust, C++, JS, etc) and became a multi-repo project.</p>
<p>The promise of <code>one command -&gt; get doc site</code> was nowhere in sight. My build script for docfx was hundreds of lines long, copying files every which way, and in the end there were still crucial parts of the site I just could not alter or hook in to.</p>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>tl;dr;</div><div class="admonitionContent_BuS1"><p>Docfx is great for C# project, that needs the most basic documentation with no styling or extensibility. The moment you need anything more than the default template, you should look elsewhere and I'm sorry I didn't do that earlier.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="nextra">Nextra<a href="https://docs.velopack.io/es/blog/2024/03/02/choosing-docs-site#nextra" class="hash-link" aria-label="Enlace directo al Nextra" title="Enlace directo al Nextra" translate="no">​</a></h2>
<p>I am a fan of React and next.js, and so when I found a static site documentation engine built on both, I was over the moon. It was easy to get up and running, copy all my markdown in, even add inline React components to my markdown using <code>mdx</code>.</p>
<p>This time I wasn't going to get burned though, I was going to test everything I needed up front.</p>
<p>Out of the gate, TypeScript support was mixed, this wasn't a deal breaker for me. It needs to be set up manually, and some files just need to be <code>.js</code> or it won't work.</p>
<p>Dev server / HMR worked well to start with, but the build to static files is where things got hairier. Nextra is built as a JS SPA, and designed to deploy to Vercel or Netlify. There is an option to <code>output: "export"</code> your site to static files, this is the only way it will actually emit <code>.html</code> files, but with this option enabled the development server stops working. It also disables image optimisation and SPA/JS style navigation. Not an insurmountable problem but definitely an inconvenience for both me and my users.</p>
<p>The final problem which caused everything to fall apart was the styling. I'm by no means a designer, but I am a stickler for consistency. I wanted the background of the Nextra site to match that of the Velopack marketing site. Surely this would be an easy change.</p>
<p>It turns out changing the background just can't really be done. As is sometimes the case with React websites, the css class structure becomes totally incomprehensible, so writing manual css classes was out of the picture, and there was no setting or variable to override anywhere. Judging by some of the issues (eg. <a href="https://github.com/shuding/nextra/discussions/2185" target="_blank" rel="noopener noreferrer" class="">#2185</a>, <a href="https://github.com/shuding/nextra/issues/788" target="_blank" rel="noopener noreferrer" class="">#788</a>, <a href="https://github.com/shuding/nextra/issues/2122" target="_blank" rel="noopener noreferrer" class="">#2122</a>, and so on) this was not just a "me being thick" problem.</p>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>tl;dr;</div><div class="admonitionContent_BuS1"><p>Nextra is better, you get HMR, the site out of the box looks great, but deployment and styling options are limited.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="docusaurus">Docusaurus<a href="https://docs.velopack.io/es/blog/2024/03/02/choosing-docs-site#docusaurus" class="hash-link" aria-label="Enlace directo al Docusaurus" title="Enlace directo al Docusaurus" translate="no">​</a></h2>
<p>Since this was so much of an issue with Nextra, this time I started with styling and building.</p>
<p>Starting with Docusaurus ended up being much easier than the others. This was the only command I needed to scaffold the project with full TypeScript support.</p>
<div class="language-cmd codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cmd codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">npx create-docusaurus@latest my-docs-site-name classic --typescript</span><br></div></code></pre></div></div>
<p>Styling came just as easy, the template had a custom css file all ready for me to add styles, there were examples on the docs and plenty of css variables to edit out of the box. In just a handful of minutes I had it styled the way I wanted, something that took hours or days on the previous attempts.</p>
<p>I was pleasantly suprised when it got time to compile the project. When I ran <code>npm run build</code>, docuaurus exported my site structure to pure html/css and also preserved JS/SPA nav. The way it worked is clever, Say you had the files <code>intro.md</code> and <code>guide.md</code>, it will generate html files for both of these so a static file server (like GitHub Actions) will also serve the files correctly. Once the page has loaded, following links will use JS/SPA style nav avoiding page re-loads. It's really slick.</p>
<p>At this point I was sold. I started moving all my markdown into my docusarus project.</p>
<p>For compiling references for language libraries, I had to use several strategies:</p>
<ul>
<li class="">C# using <code>docfx metadata</code> and <code>dfmg</code> to convert xmldoc to markdown</li>
<li class="">JS using <a href="https://typedoc.org/" target="_blank" rel="noopener noreferrer" class="">TypeDoc</a></li>
<li class="">C++ using doxygen followed by moxygen to convert C++ headers to markdown</li>
<li class="">For Rust, I didn't bother, since the <a href="https://docs.rs/velopack" target="_blank" rel="noopener noreferrer" class="">default docs.rs</a> page was good already.</li>
</ul>
<p>Everything just worked perfectly. It was easy to start embedding custom React components into the docs too. Each Velopack docs page has an indicator at the top showing what operating systems are supported. In previous iterations this was just text, but in Docusarus it was easy to spruce up:</p>
<p><img decoding="async" loading="lazy" alt="applies to image" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXUAAACJCAIAAABcuD9JAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAACUzSURBVHhe7Z0PWBTV/v/PeFOwvoFPuvg8sai56I1VwSX/LGUsXZU0+XNVtAL8KmIlinWtVLRQFEuUysw/WLqYX4VSIFPRBPTG+idWKVYwlq6xprLc5ycrPUH3Fmg5vzOzh91ZdmZ3dtnBZTmvZx89Z2d2mDlzzns+n885Zw5BkiTAYDAYAeiD/sdgMBhXg/UFg8EIBdYXDAYjFFhfMBiMUGB9wWAwQoH1BYPBCAXWFwwGIxRYXzAYjFBgfcFgMEKB9QWDwQgF1hcMBiMUWF8wGIxQYH3BYDBCgfUFg8EIBdYXRNOxBQFDh1t9MqvQdk+kSX1gzayIcdSVhv39lZ0l2ha0oYfToi3Z9UrMU9R1hf5t1uqD6ia0AdPdYH3prTQULn0ufk3eZZ2Byuk1ZVkvR83bpWmjN/Zg2jQ750ct2lym0VM5g+7ywbfip6UWNtAbMd2Mi94v1aavVaur1GfLNbpWg06tu4O+B/0kcokIiEdFTpRJ5KFyaYA32uBuQPvliWVnUcZM0tEb6aEo7Wa0Geq16irNRXWppsGizIFIEgQLPUCqkMkmhspkkgAfq1JvLV8zdl4eyjDwX3fy3KJRKNMTqVU+PW1DI8owSNx/eVOED8pguouu6ktTVWFB7hbl8dv0U9A+YkXmgf9LCEQ5N6IH6UtL/fGDH2byL3Mgmrr35MfP+qEcjWbn0NlZKG1B5PaLyhgRyvQ8DEdfmphaijIWrCpqWCJDaUx34bx/1FJfmPH840/MXJnFv6JDO1x1rRUlMY7Tpju6fsYzk19zqMyBob3Hez2Ynolz+tJaq5z1zOSVSrXZJscITptm5wtTU3PrHFAWTiSjEvqhpAXDI6Q913iBiEYphqOkBf0SpRKUxHQjTuiL/ugb0MW97IpajuGP/uibL2ZpUKbL+ESkbLR2g2Srsue4oe/qCIFx2WlWbpAoeuMSHHy5HziqL/qjqVNSC39FOUx30XTs7dTjLrUWA+J2nsl/N2GshFYZsWxq2idlh5fI3DX+zhtv2dLPy/aumioTUzmRZGziO/lf74gLoDdiuhmH4rvtVbtmxG6+hnLsPCyTy0MjJfTNpTDoNFVqDaN3w017ZNw7vqvdOz1qvRZlLHk4clX60uhIKbOTqK21xaDXaIpLCgtLVLcNIHxH5aexFvFdDKY7cEBfWspffWZ+MadbJJ647p2NcyIkvihvQVuLTn18284Pi9UGrC+O05A3Z1K6GmUYiMJ3HPk01vajuUVXXpjfHp1u2X+EwXQHvP2jNtXWN7nEpZ88Zd93Fz5bxCEuEG9fSUTiRwVnincs9PdC32H40qavYxEXAKQpK+2ICwSWfDIWF8z9ga/90lAw68k3L6OMBf1itp/eGWPyh1wANHY0KlW5uqxKp9OpOzpiRYPkEkmgLCoiWqEYJXY4TNCmr1WpCkrzq9R1xpGdIkmQTK6IiUuKDaUiEF2xX1rqVSWFRSUarVZ9jT42PcJNJotRRIUp5IFcossbjnMDkdvPKp0tefZjRm75bk+cbS2iLjYvv0CrQbcG3heZ/NnopJgYGf1D9pE1LMNqqjIDZu5DaTPMAm9tKD+uPG6+ZWJZUJgsPiYhOiKQO1hr/7AIHiVgqDq2r+C4qkJTR49y7ieRy8IiZ8+Jjg714/2UbNNXlebDg9RqLa9iYXREAHUVbm04dxme9ou2JJdVXIBs1Wfvu05cWuqP73wpZETw1LnLNu7Ku6g2iQvEcFutvngwJ33Rc+Ejxk1YquQ/qaS19uCCiEnh015OVxaiewwx6OpK83anzpwY+r85tc5OvGmqyFn6t8dHT056I6e4tENcIPDg6sL8NcvinwkOSVxfWC/M+JPSQlV3Dntvo0c8URebW2a+NfC+lBavXzb7iadePFDrsrFNbfV5rz819sn5FrdMr6kryE2fN3ls2Bt5AhWpiZaKzDnjJsYu232w1CgukDs6WAM3rIwdHzInS8WjyhiqlC+G/TXceJDOVzFpwpz1xz1+1gI/fakq2sUaXBTFr17oqh4HfYlx5Fgpj84pw+1jG+KfeOqVw/Xt6Bsu2nSHUydMe+tsRxVhwaDKnjZ/i8bekaygTnjaC9nHGAPz2fhVlbvymcmvlHShKvmJOcZuqNKXrummOtpQvmKu7RFP+otrnpu1s8oFEtNS8fbcyekFJrW2Ql+YPvdN4aYUtdcXLHjmhX1qzjpzR52TZGeuVpt27/8+HbvhIvdF3FHnvhabWsi9gyfAS19qNaWsRS3/R1KYS9SFuhlTFjk6ckxf9sbkGTurbAiD/uibM97g062r2b16M2uIgwNKthw5YX3ZopkLjjrdICQTE1GqM5q81578+ysHKhwrOUdpKHll7vwiHoNvrmW9/IoSpZ2lIW/pC/l2/5bh+MqMY4JcdWtF5tw3z9o9tGbzq0quukfNsZy1XmW/4sGrWLTBkYrX0+CjL/p6NcuEMQCC5ihcMiYSqgCvm8EGVaE52m171a4F/MeMGAz8T8BQwlO2mBjOrt/s7CPXVxGTwjrclkZTtuaFiaHPv3qgXCfICxYaCrPeKuP7mDXc6VqjV2UsS1ehtB1KN+x2/dsz9LtfX5bP7xIas3KOsznp7VW5K7J4D213pOL1PPjoi0HPOmEMyANdMWipwdbIsYdl8qnJaxcnxwXJJRwNzHA29a08lnZbm5vBOVSnn0Q+MTGFOqxxFJZDtJRnrmY54X7ylG1f11xruAE/dd+f3JIs73zChuNvKyscdsNovMIWZtuedWhQF6+ZP3X0U7NWH1Q1uFJmWstz3uY0FMTD5XHx61KiIuWDbJ4df65pkOlivPXxc2wc2ZBX4XKB0V7TGC9WNEgeGbUEXprsYTrPRmlxhbXACFbxeiI89KVJx34TI4NcUERt6oMbWHpG4J1QrMr/7kb1sUMfZySvzHj/RME/f/j+zJZE1hmwqkyrdttakpvNamOLFCuO1vxQfuizTWnUYY9duPz19tkOzKtt0xzczNJPH/ne6YK06I6uIi/fUXEZ+z9dIjVmTdxR5rI+8XjgF532Ho/z1F8++FbSk8EhybuO17tEZWrzNuWxqv/wxO3F3184XfD+xkVpHykPXaqqzE9TcBtZjiCSJx2oNN76jR/AI5/fxn7fwZ1ynQ4lXYo4LvPrM5cK9ny0Gl7al9Xfn1yhYBe5sxod/4q3+HBlFypez4RffFcwWlT7drE9GyO3nz64RN6po9Q3MG7T9i1sj/E7ysJSi9bUoiopREkLFJlH/y8l1KLD2CcwJvvw5/E8H78t6n1Z1qFuRWbGHCux9ZYnLgxCaROlxRpnX6YWEJG9cz/PGvlr6ebXnpk8I6Okq9HDWnU+W2S/X8z2TzfFSC0K0k++9JPPrOf+OIwofuf+9AjmvQ+IXrc2qbNW06htxO2dRpF5+P0E5qgC31EpH6wNRxlLGgyWJ8BV8WRJez9ZGWZRoamKt3N7uIvsPjfl/upLq0ZVhpJMZCte5+rzDohLWzUWpZkUlmkYAtOiKStASSb+61YlsLp03mErN8WhtE1aNaXFKMkgcWE062EDpNaPvbNVXWjyUGKOnd9m7XmxY6hTvhwew6snlQttRSFb6C0u+13WG+QtS17FV6m5UKxabN1p4B0anyxHaQt0emflmot+S1JYJiv5RSYlo6QFpXoLfeGseO+kh7L1hATEbExToLRHcn/1RVvB8go1oEiItvEGtQB5fCRKMimuZVjKOi2LCgD54mc5j+sjj45CSVvoallCUeFyKcdwL9Fw68d5vWWNdJiA6IxDl77ZvyKGKyBlicZuT6oNmnQaNuslMVrBNWbQOyxqDko6R1CMnPXRIgnsJl8iLkLGNnbOWyJjq3ad0GvZQpXS+DDOiicOi5uIkp5IF/RF38k0dJwmfT1KMekXJrUZ2AmQsI5rrDK3W0MDqweskNqIR/v68HjuNumqWK75bOp40/vALT/jV1pXN42+6yMefAIiUnb+s/q7I1vSou0HVjWbX1xf7tSwFP3lYyjFZKJcYuNdBxIpj3bIjSyA43q8RP4oJSjyII6x4T6+9iuIoV7DFqtSyGw9L8Wsnp+HwENffETszVJ7sb6Ltqm+jk3t5WI7N1IktlODDQa2JhwptilbfGA/sGN0VZTNePmFxi3dcamqpnjvqok2r+3Owc15tSjtAC2trCcrDbCh013Fy4tjRJVI1C0viPLx4hj57+Njv/pwVLxe/GorHvriLeJQ2LMqzX1516XdqR/t7eyvMugy7bcFOnCX8JU+u+SzipriHQuDOJVZu63ccYFpb8XvMnUIwSpej4WPfyQZxRpaA6Agx5mnYpdxhRXhefhKY9edOMrZH3GnSoiuFgzGJnz0xUuq4Ih9arI/ONaFti4OYnN0dPbiOq0GtqdEgMgUFPDyYjO4WtttPY3b2nmMfBMNZ1Na/5iUxevW8v4I+YLbgJiPdy5kj/uWOhH3YbcU222+Lrx3qz/bvbVd8TicUA+BV3zXVxbFNf+ldNkCmzOAbMIe2WmssP2kbWAd7+cv9jG1BpGIzVVWa2wNn9dpeYxK9/LpNCTHiCx65aJk3p+ILoeBbOEVFp2Akl3Gjz3koWJ21XWmSVvRe30EsZitk8texWMfHe8Z8NIX4KuYs4oren8ta+aM1TzHcbVoj67PNbtU3lLWPr/SwlIb83RqS3ezvcktMtQcoxcFsPZl5hWpue5zm6ogh3WOlSV+EhmLZdRYrhX4kV1buJf3DMYWDvtBbrbveCNiNTAbC9ScEtKgyvfk5mIHUQCrINuseMdye/v8I4hXaNxK7vkv1w6+HB72UmZJrYHDcG5vqVcdWDMrLDgqNbeRYe2IQiPZBsupMrO43K6Gwl1sQiCKm8ps+BIpq0NX9kGOmu0M26tyM5W82q80NJrF+1Bt3l3h5AgTfrTXrX9hYthLOeX19gKuLeqDOWxDFgEIFDnulwVIw9g8Te2Gtw+zPgEaCrM2s78nqJcgkbNXvNUfqrpW8XoqPPWFnv+y1tZYZn3pvkXPTRwxbsKcl17dpNyyF33efv35KWFDg0ZPTlqTd9laMwIik9iGY905tmzB6mOdl1tvqc17/YWVbHPthi+JljO7NX1lU1lHeWlzFszLUjVZ3GpDedasRXZeWm4mVPEaS4sz5C+dn1luq7e+tb48Z2dJl6qSvjR73uSx1ILtysLyWn1Li4Vb2takqyh4O/G5eI41TLgHAdpCGhbHardefmPmgsOWYsd9d3oRXBXPkJs0F1Y8lKNp0ztU8XooDq0fQC9O4uh7CTrT+cV/tcop0zZwlDJ6J6bMy6Cq1VgsscxEtHDfN+sUlsMm2ivWh8zltDyNixyI29XqjlcfcmH9mkLuFUjBw4qEhDmR4QFiiUTkBTVFr9UbDNpyVVG5ivorzi+9yv7ORwewLiK+78dsyEucxPnCBJEkKEKhkAJdiUrFdXeMOPV+TAv4nrAr349pQdWu4bGbUdpM52Vn2yuyQubmcFe8SEWYXNSqVpWXmt92yEbvej+mEXHsjtM72ByErjAq+aN1XEO/0TsxdysL6zirryxp76pO4gLxCluYzj2x41eNuky5YR/j1Yf8EcWuZZ1jCflVlbc7dX587OSJo4PHjg4On/ZC/LxlG+HJ3+euYVH4phTrIuJHQNzrKZwDZw26uoLc3etzy2yLS2/CKyxhI/fwz181pcW7qIpnW1w8B4f0BUJJzIEE1iU4nUa6aH++k/NuxVP3bmefOQYCEjbxn5wqCk9L4T0NJCDu/U+SnDvf+4AoKO2TTovbO4RX6D8+4n93ZKsWs84D7EUExGU4VPFWsc/M9gwc1ReIOOLd0999viLShd2svvKlnxe/G8n9Ih82xJFvnzr58bPcY9UDYj4+sHYsjzs9PO2Tj2KkdocFm/EOTT/A+U4QN0Ikn73j8y+WhjpwaSx4y5Zu383xBhYLxHHbdi6Z6valIjh8Kx4t/dYv9vAknNAXCr+wFOWFi0e3J/GcxUvTTxKdtOPIYnav0ls6b081lC0+BxRJwtftLzu1Z+Eormm8CK9RyV98fcSmFIqnvn/mxNJQ8+AZnviOSjlILec0ll/1gNe+YpHciQgrjTTpwDtRCkcqIiyitE+Kvz6UHRvYNXExEhC5ab/N+Qfg4ch3ik69z/6eCoi3K86i50BVvFM2n8FQ+vcegRWPo1xEXNOgehgOxXfZaWvQqjXqCmq5olbokDNiDQ/L5GIvsexZaVCATC6XSnz5xQBa6jVqTXF5qbpeZ47pUisKSSShivAIeWSYjeVv2GmtLz9eUFpsWqkWLX4UPTsiDK0J5/wyNPTKShXqsyVanZ6xRIlYFgQvflRkeJgj124bWNQaraZWc7FCo2tt16s1jLUWxMPlYlGgDDI1VC4N9LVTPx2Nbhppa9KUHN93rNS00hMdKY+LT4xUdLyQSb1paPwuY5JB2pFrSzuVo2fGdztBVbyDx/NNvRMdq27FPxuK5mk3HHvxyWUX6SQDezeip+ACfcFgzLAvZYsXwOaivWJ90NxclDFjR7Z6DE76RxgMK+yjq6UTA7G4sNJSWmAtLgAkesorHbC+YFwHx+hqaZzCxguWejHtVXnb2N6nOTVC5myozs3A+oKxR21uhtVYahZa1DuXsY+uniNnm2XgsRhKduWwrFtiRcOxV1jH74oSZsvtdFz0GLC+YOzR3qhcFvXM3xbsLde1sE+zam+qyEnmmJogSlg5p5dZL22a7LnjQxLX51U1cLxagJroOyN2GesqkcOXJER6irzg+C7GLhY9MsYR7mKJODzAp71Jd1Gr1VSoLpoWb++MKHzvyU+7MLqvJ2IxgwRNoZAMD5SIvVp1tfo6bWlpufo214hu2aqiw0tctab7/QfrC8Ye7D2+fBieZmOIh8diY4aaHUTRW47uYFkdpeeC/SOMQAxf8vlnvU9cnEcUnXn4PY8SFwjWF4zroQannj+9OgxPFeAJNfr56x0JgR7jF3WA9QVjD1EQ/1kgYkXUu/vLvj6UbWNemKfj5SfjOWsElu2gmFVbjlZWKxNlHhPTZYLjLxhetDVoVeriCrWqVt/OnAZBz0vwCpAq5HJe8xJ6C22Geo2qQnW2XEPNmmG8v6KfRC4R+VAzXaiJI6M4VnPzFLC+YDAYocD+EQaDEQqsLxgMRiiwvmAwGKHA+oLBYIQC6wsGgxEKrC8YDEYosL5gMBihwPqCwWCEAusLBoMRCqwvGAxGKLC+YDAYocD6gsFghALrCwaDEQqsLxgMRiiwvmAwGKHA+oLBYIQC6wsGgxEKrC8YDEYosL5gMBihwPqCwWCEAusLBoMRCqwvGAxGKLC+YDAYoXB4/aP29vY7d0yLRfVSvLy8+vVDSxqu+oLMUfX2NaQ2zSSWRhDGtEcWCPMCIe7fCphV9D7imP0Cxeju3bso04t54IEHjIm7f5KHv+3t4vJAH/D8OJS++yfwvAKhL9AsLj2iFZiq6P3FMX35888/8XqP8M716YPKraSWaP6vMdl7iRwFBv0Pan4ltcDzCoS+QJSGuH8rYFbR+4tjJ4GNF0jfvn1RCoDCqt6utpC4UPOz3SMLhHmBEPdvBcwqen9xQF+gZv/xxx8o04v5y1/+Ykz8p50sqe3t+vJQPzBtFEr/px3aL55WIPQFWjhH7t8KTFX0vuOAvmBxgcAnA0Gg2vblZfDf3h7pBrFjif/xMhUI6XkFQl8gSkPcvxUwq+h9xwF9wc4RhGl55l3EzhFImGCuyh5ZIMwLhGDnyCH46su9e/f+/PNPlOmtwMeCKWx2vZm8oDMmey9DHwGTApGmXG8Gnlcg9AWiNMT9WwGziroDfE8FO0cQpuX5RZXx/17NTBksD1OBeKDxQl8gSkOwc+QofPUFO0cQpuWJe44gcU+Yq7Jn9hwxLhCCnSNH4aUv0CyEoExvBZqdJsuzphF8/29jsvcy+lEQ7I/SHlkgzAuEuH8rYFZRN4HX2WDjBcJ8MuDILiRhovnZ7pmRXcYFQrDx4gT29aX7R0NX791SjZJuhBBzAibFE03b+txMRVkHiCdanfuhi8BzAtwQN5kTwMS+vvAcDW34KkW6twZlXET13pDUr26jzH2F55yAnDV9YLP/Nh5lKaIpBWndRuQ8gr6AFGVS3xTJULa9B4bOHZgTQEsh9VlBDEFfdfAIcd64aRORgr5yHH+Qk0rcfI8+Dn2o8/PBGLSN5hGQtZixwzbiSjLaYgNH5gQ019U1o6SZ5rrD527+jjLdgPvMCWBi/4T4yfbtysbHlteccq3dEbKoesf0QSjjJDV7XKF6PCO7ebeoTSP9zc+9lKHAm/qfGKOg85BAYqQPAL+B0xpwPp/0e+3eiN1oSw/CmTkBYpDB6OuFTIoGwSjpLI8T3y7vkzCCGNCXvHWLvNpMtj1IBIf2ObOWMIl8zmJiSRAxAJBX4Q7UPsCbhxvR5TkBA4PmPj2kP8p0A27oHEHs6Avf0dC3LzT6L/z79J8uuaFj4wp4zgk4XwVuwf8eAaan8ZTBBLhLtgEwxBQpHAOGAtDWBHJQvufhxJyAX36D+xDjTSJLszyQAL+Rv6CcM+TPJUb2Bb/8eO+p18gR75LjNpB+6+8VN5PeA4n1i+k9ZAR1C1rJxW+S4+AO9D52BR3PCXAVdvSFZ7FWf3nKf/wg0fQUoDxqQN9R0JGU2ydfDZGOpj+vmrfa2GSmesses2DV7DHuOdrSaarewnUEymUbPW/rh/OYW+kvO/4oP9MGPhlMYwrszAnQkFd/A+BBMMXo+9Cmyi/XwU0ABgwmZtPfpdBCc/U63SaZYRSUJrJSjS5Vn6a1RIrJq3oEbF3e8X0mkWX5YBwiI4rWoK3Q/v9xBbGQ/iHtrxEnOlp1/loqeybamCPOQJchkz6rxxk/f484Mdm4AyfOzAloBLCshw4zmxVgAhHsA27dAE0oTzFJQZzP7PCn3iO+nQ9MLhW8xhNrzSd5ZiYACmLSQAC1I20HuIL2AuBnEJ8PbgAwOJDIgNlfARR30B+MZPindnHJnIDmusvIa2q+DP2n5rqCQ4fpz4XrHW5TZ8equY52qX6/ft68D/XzQyz+lwXMKupW2NEXfmZhzaWaaeMpPyZ4QvCpSouAyU97Xk0Ha6u131Mf1fRTCrMK2Nhkxe2jqaNPTaD3hJ91IB3pDvy+cprxS+3ax/5tGasRTc/Rfn9g+T8OUFs/ihVRohaiaExB+8M/6p/DR2KYlqfdjpLKJupBPZK2+4dMgKYK+eMNyiYHPmA27R1Qj1NAXlFRaWsGDANQGk7XkDd+A9RDeD76PiuZSB5GeP9GnqshK38HS4IZlelx4osEYupg0KInoatS0woGi4msxcQU5K8RI4Po3QKJMbA1AgJZUk+CEfDJf4ssAqCI/vmtH6mfn4M/H0zvwI1TcwLIIiipPiC5Q7yWPwUGA/LcaZQ1MmYMGHIXlFWRhTXkLXjmocQ+4/4K4swC4umBoOUWWQxP8mfg1Z8aWTsAgFuNZD69i5l68gos8L5gDFT5evKEngR9idfXUHGZSfxUxuVzApp/OFf3UNTzc+fAT0xAw3e2AzP9h016/JeOfZrrfhgQE0TdORu4p3MEsaUv93iOhq4+VT39Kdh6ISHjHztpITDfhCTnPNcRQoEN/jOzANnY1JnqL//10vcrQ1AO7tzZUKIYFBxiO1Zz++iemg2qRWaXn/qjIOckxx81Ah8LprAZnzkBGdepf4f6URV0CR2IqTwOimjRGTKGimhSwZdmkPcztRsLrSB+AxmvJMecohwH70do+yKQmCGm/KwPsskZSnLGu+QHRvOHZvl0AH2EGzXkiGxy4X5yUjpZ1gq8B4PlCnBeRT/J/ajAqlHsbkH58CMmQUshCDZO8sc6eABiKDylu+DEEernMzaQs04ZD8yO03MCtl6AziMxPpSO8sLrGkYAPcioN25EnMgnh2wgZ+8nFyrJpDq60EZQ3+cqCChGVy9STlA8PMl3yUn5YAxtxLW0Uv92ooU2OLzhdQGQlk3+o4r8pS8Vlzm5jjg/12wTsSLEnIDGR6STOoIx/YdIBzbcsikwAAz865CGf0GRbK7TPhQ6zHYYh1lF3Q1bp8UzsntS+dNztPVCETItZEUuIwiTMMGkCjSP+j+GUrY2deJ2Y03eiyanhvrM22rcMih2HbRBRvPrz278F+jQQROP+oPGRpRmhWl55l8y/m+TI5QjQIdgiPHQEGgGu6CBUAegWIyELUpBBV9uNZHnjTtb8cvPJHqiq2jH4QHgB/+lpAH6WWRGhyplUGEexBRKy8jKIygLOU2bLYOhnVJPXoXNbyBYYhQ7qGtw00AQBUufCgyBc2fg7mQxVKu+xJKVxM01RM6T4CaX9tG8OAGWh6lAzDJnn0vkOdhi6CgvHdklK6tI6DlaMJTIX05c2UQ0vdfnJG2jeVFdrsRI+Py+C4otDZUmWkR8aRHphC/dUdvScWdz95NDttz7oAZKNhH8FPEFs4PPCvoCURrSdeMFEuxnxwCxov+Q0AF1F841PTTObpDYbZ0jiC194RnZPfnPb96MYLb8PAGivAmfdTg16EP7OxDaCZp2Cf5pV/eOG2FankW8OkrIK7DxPwimzKQcECglVBNSgR/vAm8/kEP5JuRVymroJmitAWMUlNjdaCQz6CY3Ppqg4hG3ABWhgGq1lXzuC/LcLSpIlPA8YdG/bgWzY4VfgZjJ+IESvvEKOrLbCpSUujEIpBy9KH/QcgMUX7qXVGM+ONUHd5eOnTMo+pGKrUBzDHqCFjxOe4K/gXNM46gRZCjJITnkDahWY2x1h3fqObpvkd3+Dw9s/H/gIXvq4sbOEYRTX+jB0PZHQxsqT4XkWbb8vIStlaam3klrbld+BfyRrWNjUycG+Qf/1GjLiwl+iQ6mMILBbPj/FXx1oZNX9e9G4G/q2bECmp0my7OmEfzIDEVyY4x6BIdSDkiHlJCVtOjMgEbEXVDJEXzh5Dpl/sDGb2r4Wxld4Fcoc4MYj6K2FE/TIZ4bdOvKuQEbITFyAhQ78moVpXRXodMRCIb0BVcbUQMe4w89KcrpGH2IjnoEoVC0NaMfBSM7ojP8C8TEzcNk5V0wNIh42gfcqLeKm0ygHD1opk3aTS48DPzMLYu8Aa2wB0Ec4xopzlDRIjCQyE1lDHjxB/lzKXMPHp/qoVMQZ5IZW5tAC/y3L+AKMTEvEMKzFTjPz78yHKXf/8uwHCnPKDrqoR86gsQcMKuoG8J5Zjwju1+ueKyTmwNCFr5nHgjzZLUyxRTgqN47+eT0hR2729jUmZC/TzsZwXSCbp/8ipaw2zXVHUfgVIqan5CmDIp9KXitgmHmGL5KeRGkmGJA1jCfDPyHwBt7qQf7WEjJLqoxEwMeNFsNDvANWQkbkg/xYSZRNJ/qRpk92HwyaSooCmBoKNVtlDuf6n+J8gFterDc6M0dB1fuUhHfAfSIG/AzFWwePIwKZ1SiOAuxbzlxfjH1260RVMNrawVFxi1WdH1OgLKe8sW84V+/gL4xQze1AcOIE/MpL2n1MPpLmuVVJFTJ8VPQNZ5ZS5yntXZ2Hnn1Lhgwos+F94gra4hv1xJNK/tEDSTabpHLlfQvARgRTG39Fm5dQ9xcRwTTnmYu2tiZ7p0TMNDvkcrrHfrx+81vK0yuevPlOsozor0km51H7my8QNj1he9o6OpT1dnWojBo/PSf9qAu5Mde+iilscN72uN/hjFezsYmKwbF7ij/q6l/Wjo6HYynw7SDHm3cYDpCJptSBE+AmgJ3oDunQhbRfUYdx1kPMrWMcK81Ts4JMPZSQxhScvMSFWqFmKwGh4AN6Vwz6e1DTA0lxvwBMsz9sVRcY/Ih1G0Ebfvg/uBqHRmfbQpt0KYTY8QNHWxmxpjJG7+D4CDqt1Qvkp5MU7KfoUvmBOSfpsvBKrJLcYTcdZ1s60s8HUpMeRhsYlzjzSNkfDlVqsZrHNMf3DQ2xR/IcVvvFeqpwMrQwcTIgdSAmpqqe5Pf7QhjXSFP01tHwq2DqQ44uHXGDmrEgDXOzwm48k/U90x9HBi2OzDob+AM+uF3YNwUo6H1+/XzPwx4whh36T/siYe057mP6IZzApiwr38Efc7ff+ddSNxU790CFpn7fZjY2OQmwDvXvz+y0YtrQLyyt88gf24M+HwReiB5ZIEwLxDiqlYgHMwq6p6w2y8Cm4U9A6blefBSbxcXSOIEc23xyAJhXiDE/VuBmztHEBZ96RGjobsB5pyA0lpjsvfyUD/w7Chk6v6nHXhegdAXiNIQPCfAJbDoCxYXCHwymMYUfHkZ/NHrzZfYsUTfv5gKhPS8AqEvEKUh7t8KmFXUbWHRFxeahSHcERYbm9wBpuXpXEeJh4HXCXA33N85gnTWl3t4nQDg8JwAjwevE+BuMKuoO9P5FHFkF8K0PHnNCfB0nJ8T0EMQYk6AoPQI5wjSWV9w8AXCtDwdHQLvkXRlTkCPwF3mBPCmRzhHEAt9oQdD9/ZIJj3eGhWLE0PgPY8uzglwf7p7TkCXYVZRN8fiLLFzBGE+GXBkF4LXCXA3eorxAjHriwOjoT0aJ+cEeCh4nQA3xM3nBDAx64vNN6T3FuCdM1meNtYJ6D04sE5Az8SRdQLcAmYVdX/Y5x9hMBhM1+kxQojBYHocWF8wGIxQYH3BYDBCgfUFg8EIBdYXDAYjFFhfMBiMUGB9wWAwQoH1BYPBCAXWFwwGIxRYXzAYjFBgfcFgMEKB9QWDwQgF1hcMBiMUWF8wGIwwAPD/AdWLQQR7yZ9UAAAAAElFTkSuQmCC" width="373" height="137" class="img_ev3q"></p>
<p>This was super simple. Just create a <code>src/components/AppliesTo.tsx</code>, and I also wrapped MDXComponents so I my component was pre-loaded (eg. did not need to <code>import</code> it at the top of the markdown page):</p>
<div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class="codeBlockTitle_OeMC">/src/theme/MDXComponents.js</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">MDXComponents</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">'@theme-original/MDXComponents'</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">AppliesTo</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">'@site/src/components/AppliesTo'</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">default</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token spread operator" style="color:hsl(221, 87%, 60%)">...</span><span class="token maybe-class-name">MDXComponents</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">    </span><span class="token maybe-class-name">AppliesTo</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><br></div></code></pre></div></div>
<p>And then in each markdown file I can just add the component directly, for example:</p>
<div class="language-md codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class="codeBlockTitle_OeMC">/docs/MyPage.md</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-md codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token title important punctuation" style="color:hsl(119, 34%, 47%);font-weight:bold">#</span><span class="token title important" style="color:hsl(230, 8%, 24%);font-weight:bold"> My Page Title</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">&lt;</span><span class="token tag" style="color:hsl(5, 74%, 59%)">AppliesTo</span><span class="token tag" style="color:hsl(5, 74%, 59%)"> </span><span class="token tag attr-name" style="color:hsl(35, 99%, 36%)">win</span><span class="token tag" style="color:hsl(5, 74%, 59%)"> </span><span class="token tag attr-name" style="color:hsl(35, 99%, 36%)">mac</span><span class="token tag" style="color:hsl(5, 74%, 59%)"> </span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)">/&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:hsl(230, 8%, 24%)"><span class="token plain">This page applies to only windows and mac...</span><br></div></code></pre></div></div>
<p>In the end, I can't recommend Docusaurus enough. It is extremely easy to use/get started, and provides plenty of extensibility in all areas.</p>
<p>And the fact that it comes out of the box with a Blog is the reason I'm writing this post!</p>]]></content:encoded>
            <category>nextra</category>
            <category>docfx</category>
            <category>docusaurus</category>
            <category>documentation</category>
        </item>
    </channel>
</rss>