ErrorView.psm1

#Region './prefix.ps1' -1

param(
    $ErrorViewArgument
)

# We need to _overwrite_ the ErrorView, so we must use -PrependPath
Update-FormatData -PrependPath $PSScriptRoot\ErrorView.format.ps1xml

Set-StrictMode -Off
$ErrorActionPreference = 'Stop'
trap { 'Error found in error view definition: ' + $_.Exception.Message }

$script:ellipsis = [char]0x2026
$script:newline = [Environment]::Newline
$script:LineColors = @(
    "`e[38;2;255;255;255m"
    "`e[38;2;179;179;179m"
)

$Escapes = @(
    '\u001B'
    '\u009B'
)

# From https://github.com/chalk/wrap-ansi

# $AnsiEnd = 39
$AnsiBell = '\u0007'
$AnsiCSI = '['
$AnsiOsc = ']'
$AnsiSgrTerminator = 'm'
$AnsiEscapeLink = "${AnsiOsc}8;;"

function wrapAnsiCsiCode($code) { "$(${Escapes}[0])${AnsiCsi}${code}${AnsiSgrTerminator}" }
function wrapAnsiHyperlink($url) { "$(${Escapes}[0])${AnsiEscapeLink}${url}${AnsiBell}" }


# https://github.com/chalk/ansi-regex
# Valid string terminator sequences are BEL, ESC\, and 0x9c
$ST = '(?:\u0007|\u001b\u005c|\u009c)'
$script:AnsiPattern = @(
    "[\u001b\u009b][[\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\d\/#&.:=?%@~_]+)*"
    "[a-zA-Z\d]+(?:;[-a-zA-Z\d\/#&.:=?%@~_]*)*)?${ST})"
    '(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PR-TZcf-nq-uy=><~]))'
    ) -join '|'
$script:AnsiRegex = [Regex]::new($AnsiPattern, "Compiled");
# $script:WordBoundaryRegex = [Regex]::new("((?:$AnsiPattern)*[^ -,.?!:;=\n\r\t\\\|\/]+?(?:$AnsiPattern)*)", "Compiled")
$script:WordBoundaryRegex = [Regex]::new("((?:(?:$AnsiPattern)*[^ -,.?!:;=\n\r\t\\\|\/]+?(?:$AnsiPattern)*)|[ -,.?!:;=\n\r\t\\\|\/])", "Compiled")
#$script:AnsiSplitRegex = [Regex]::new(, "Compiled")

# https://github.com/mathiasbynens/emoji-regex
$script:EmojiPattern = "[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE])))?))?|\uDC6F(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE89\uDE8F-\uDEC2\uDEC6\uDECE-\uDEDC\uDEDF-\uDEE9]|\uDD3C(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF])?|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)"


$script:EmojiPattern = "\uD83D(?:\uDC68(?:\uD83C(?:\uDFFB(?:\u200D(?:\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))?|\uDFFC(?:\u200D(?:\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))?|\uDFFD(?:\u200D(?:\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))?|\uDFFE(?:\u200D(?:\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))?|\uDFFF(?:\u200D(?:\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83E(?:\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))?)|\u200D(?:\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83D(?:(?:[\uDC68\uDC69]\u200D\uD83D)?(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]))?|\uDC69(?:\uD83C(?:\uDFFB(?:\u200D(?:\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D[\uDC68\uDC69]|[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83E(?:\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))?|\uDFFC(?:\u200D(?:\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D[\uDC68\uDC69]|[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83E(?:\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))?|\uDFFD(?:\u200D(?:\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D[\uDC68\uDC69]|[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83E(?:\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))?|\uDFFE(?:\u200D(?:\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D[\uDC68\uDC69]|[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83E(?:\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))?|\uDFFF(?:\u200D(?:\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D[\uDC68\uDC69]|[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83E(?:\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))?)|\u200D(?:\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D[\uDC68\uDC69]|[\uDC68\uDC69])|\uD83D(?:(?:\uDC69\u200D\uD83D)?(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]))?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF](?:\u200D(?:[\u2640\u2642]\uFE0F(?:\u200D\u27A1\uFE0F?)?|(?:[\u2640\u2642]\u200D)?\u27A1\uFE0F?|[\u2640\u2642]))?|\u200D(?:[\u2640\u2642]\uFE0F(?:\u200D\u27A1\uFE0F?)?|(?:[\u2640\u2642]\u200D)?\u27A1\uFE0F?|[\u2640\u2642]))?|(?:\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|\uDC6F)(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?|\u200D[\u2640\u2642]\uFE0F?)?|\uDC41(?:\uFE0F(?:\u200D\uD83D\uDDE8\uFE0F?)?|\u200D\uD83D\uDDE8\uFE0F?)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\uD83D\uDD25|\u2B1B))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD74\uDD90]\uD83C[\uDFFB-\uDFFF]|\uDC08(?:\u200D\u2B1B)?|[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD74\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDD90\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0])|\uD83E(?:\uDDD1(?:\uD83C(?:\uDFFB(?:\u200D(?:\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83E(?:\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))?|\uDFFC(?:\u200D(?:\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83E(?:\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))?|\uDFFD(?:\u200D(?:\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83E(?:\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))?|\uDFFE(?:\u200D(?:\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83E(?:\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))?|\uDFFF(?:\u200D(?:\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83E(?:\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))?)|\u200D(?:\uD83E(?:(?:\uDDD1\u200D\uD83E)?\uDDD2(?:\u200D\uD83E\uDDD2)?|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|\uDD1D\u200D\uD83E\uDDD1|[\uDDB0-\uDDB3])|[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))?|\uDDCE(?:\uD83C[\uDFFB-\uDFFF](?:\u200D(?:[\u2640\u2642]\uFE0F(?:\u200D\u27A1\uFE0F?)?|(?:[\u2640\u2642]\u200D)?\u27A1\uFE0F?|[\u2640\u2642]))?|\u200D(?:[\u2640\u2642]\uFE0F(?:\u200D\u27A1\uFE0F?)?|(?:[\u2640\u2642]\u200D)?\u27A1\uFE0F?|[\u2640\u2642]))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?|[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?|\u200D[\u2640\u2642]\uFE0F?)?|[\uDD3C\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE89\uDE8F-\uDEC2\uDEC6\uDECE-\uDEDC\uDEDF-\uDEE9])|\uD83C(?:\uDFF4(?:\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\u200D\u2620\uFE0F?)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF](?:\u200D(?:[\u2640\u2642]\uFE0F(?:\u200D\u27A1\uFE0F?)?|(?:[\u2640\u2642]\u200D)?\u27A1\uFE0F?|[\u2640\u2642]))?|\u200D(?:[\u2640\u2642]\uFE0F(?:\u200D\u27A1\uFE0F?)?|(?:[\u2640\u2642]\u200D)?\u27A1\uFE0F?|[\u2640\u2642]))?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF](?:\u200D[\u2640\u2642]\uFE0F?)?|\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDFF3(?:\uFE0F(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|(?:[\uDFCB\uDFCC]\u200D[\u2640\u2642]|[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7])\uFE0F?|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCB\uDFCC\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF])|\u26F9(?:(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)(?:\u200D[\u2640\u2642]\uFE0F?)?|\u200D[\u2640\u2642]\uFE0F?)?|\u26D3(?:\uFE0F(?:\u200D\uD83D\uDCA5)?|\u200D\uD83D\uDCA5)?|\u2764(?:\uFE0F(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|[\#\*0-9]\uFE0F?\u20E3|[\u261D\u270C\u270D]\uD83C[\uDFFB-\uDFFF]|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u00A9\u00AE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270C\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]\uFE0F?|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]"

$script:EmojiRegex = [Regex]::new($EmojiPattern, "Compiled");
#EndRegion './prefix.ps1' 57
#Region './private/GetAzurePipelinePositionMessage.ps1' -1

filter GetGooglePositionMessage {
    [CmdletBinding()]
    [OUtputType([string])]
    param(
        [Parameter(ValueFromPipeline)]
        [System.Management.Automation.ErrorRecord]
        $InputObject
    )
    $InvocationInfo = $InputObject.InvocationInfo
    # Handle case where there is a TargetObject from a Pester `Should` assertion failure and we can show the error at the target rather than the script source
    # Note that in some versions, this is a Dictionary<,> and in others it's a hashtable. So we explicitly cast to a shared interface in the method invocation
    # to force using `IDictionary.Contains`. Hashtable does have it's own `ContainKeys` as well, but if they ever opt to use a custom `IDictionary`, that may not.
    $useTargetObject = $null -ne $InputObject.TargetObject -and
                    $InputObject.TargetObject -is [System.Collections.IDictionary] -and
                    ([System.Collections.IDictionary]$InputObject.TargetObject).Contains('Line') -and
                    ([System.Collections.IDictionary]$InputObject.TargetObject).Contains('LineText')

    $file = if ($useTargetObject) {
        "$($InputObject.TargetObject.File)"
    } elseif (.ScriptName) {
        "$($InvocationInfo.ScriptName)"
    }

    $line = if ($useTargetObject) {
        $InputObject.TargetObject.Line
    } else {
        $InvocationInfo.ScriptLineNumber
    }

    if ($useTargetObject) {
        "sourcepath=$file;linenumber=$line"
    } else {
        $column = $InvocationInfo.OffsetInLine
        "sourcepath=$file;linenumber=$line,columnnumber=$column"
    }
}
#EndRegion './private/GetAzurePipelinePositionMessage.ps1' 37
#Region './private/GetConciseMessage.ps1' -1

filter GetConciseMessage {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline)]
        [System.Management.Automation.ErrorRecord]
        $InputObject
    )
    $posmsg = ''
    $headerWhitespace = ''
    $message = ''
    $prefix = ''

    # Handle case where there is a TargetObject from a Pester `Should` assertion failure and we can show the error at the target rather than the script source
    # Note that in some versions, this is a Dictionary&lt;,&gt; and in others it's a hashtable. So we explicitly cast to a shared interface in the method invocation
    # to force using `IDictionary.Contains`. Hashtable does have it's own `ContainKeys` as well, but if they ever opt to use a custom `IDictionary`, that may not.
    $useTargetObject = $null -ne $InputObject.TargetObject -and
    $InputObject.TargetObject -is [System.Collections.IDictionary] -and
        ([System.Collections.IDictionary]$InputObject.TargetObject).Contains('Line') -and
        ([System.Collections.IDictionary]$InputObject.TargetObject).Contains('LineText')

    # The checks here determine if we show line detailed error information:
    # - check if `ParserError` and comes from PowerShell which eventually results in a ParseException, but during this execution it's an ErrorRecord
    $isParseError = $InputObject.CategoryInfo.Category -eq 'ParserError' -and
    $InputObject.Exception -is [System.Management.Automation.ParentContainsErrorRecordException]

    # - check if invocation is a script or multiple lines in the console
    $Invocation = $InputObject.InvocationInfo
    $isMultiLineOrExternal = $Invocation.ScriptName -or $Invocation.ScriptLineNumber -gt 1

    # - check that it's not a script module as expectation is that users don't want to see the line of error within a module
    $shouldShowLineDetail = ($isParseError -or $isMultiLineOrExternal) -and
    $Invocation.ScriptName -notmatch '\.psm1$'

    if ($useTargetObject -or $shouldShowLineDetail) {

        if ($useTargetObject) {
            $posmsg = "${resetcolor}$($InputObject.TargetObject.File)${newline}"
        } elseif ($Invocation.ScriptName) {
            if ($env:TERM_PROGRAM -eq 'vscode') {
                # If we are running in vscode, we know the file:line:col links are clickable so we use this format
                $posmsg = "${resetcolor}$($Invocation.ScriptName):$($Invocation.ScriptLineNumber):$($Invocation.OffsetInLine)${newline}"
            } else {
                $posmsg = "${resetcolor}$($Invocation.ScriptName):$($Invocation.ScriptLineNumber)${newline}"
            }
        } else {
            $posmsg = "${newline}"
        }

        if ($useTargetObject) {
            $scriptLineNumber = $InputObject.TargetObject.Line
            $scriptLineNumberLength = $InputObject.TargetObject.Line.ToString().Length
        } else {
            $scriptLineNumber = $Invocation.ScriptLineNumber
            $scriptLineNumberLength = $Invocation.ScriptLineNumber.ToString().Length
        }

        if ($scriptLineNumberLength -gt 4) {
            $headerWhitespace = ' ' * ($scriptLineNumberLength - 4)
        }

        $lineWhitespace = ''
        if ($scriptLineNumberLength -lt 4) {
            $lineWhitespace = ' ' * (4 - $scriptLineNumberLength)
        }

        $verticalBar = '|'
        $posmsg += "${accentColor}${headerWhitespace}Line ${verticalBar}${newline}"

        $highlightLine = ''
        if ($useTargetObject) {
            $line = $_.TargetObject.LineText.Trim()
            $offsetLength = 0
            $offsetInLine = 0
        } else {
            $positionMessage = $Invocation.PositionMessage.Split($newline)
            $line = $positionMessage[1].Substring(1) # skip the '+' at the start
            $highlightLine = $positionMessage[$positionMessage.Count - 1].Substring(1)
            $offsetLength = $highlightLine.Trim().Length
            $offsetInLine = $highlightLine.IndexOf('~')
        }

        if (-not $line.EndsWith($newline)) {
            $line += $newline
        }

        # don't color the whole line
        if ($offsetLength -lt $line.Length - 1) {
            $line = $line.Insert($offsetInLine + $offsetLength, $resetColor).Insert($offsetInLine, $accentColor)
        }

        $posmsg += "${accentColor}${lineWhitespace}${ScriptLineNumber} ${verticalBar} ${resetcolor}${line}"
        $prefix = "${accentColor}${headerWhitespace} ${verticalBar} ${errorColor}"
        if ($highlightLine -ne '') {
            $posMsg += "${prefix}${highlightLine}${newline}"
        }
        $message = "${prefix}"
    }

    if (! $InputObject.ErrorDetails -or ! $InputObject.ErrorDetails.Message) {
        if ($InputObject.CategoryInfo.Category -eq 'ParserError' -and $InputObject.Exception.Message.Contains("~$newline")) {
            # need to parse out the relevant part of the pre-rendered positionmessage
            $message += $InputObject.Exception.Message.split("~$newline")[1].split("${newline}${newline}")[0]
        } elseif ($InputObject.Exception) {
            $message += $InputObject.Exception.Message
        } elseif ($InputObject.Message) {
            $message += $InputObject.Message
        } else {
            $message += $InputObject.ToString()
        }
    } else {
        $message += $InputObject.ErrorDetails.Message
    }

    # if rendering line information, break up the message if it's wider than the console
    if ($Invocation -and $Invocation.ScriptName -or $InputObject.CategoryInfo.Category -eq 'ParserError') {
        $prefixLength = [System.Management.Automation.Internal.StringDecorated]::new($prefix).ContentLength
        $prefixVtLength = $prefix.Length - $prefixLength

        # replace newlines in message so it lines up correct
        $message = $message.Replace($newline, ' ').Replace("`n", ' ').Replace("`t", ' ')

        $windowWidth = 120
        if ($null -ne $Host.UI.RawUI) {
            $windowWidth = $Host.UI.RawUI.WindowSize.Width
        }

        if ($windowWidth -gt 0 -and ($message.Length - $prefixVTLength) -gt $windowWidth) {
            $sb = [Text.StringBuilder]::new()
            $substring = TruncateString -InputObject $message -length ($windowWidth + $prefixVTLength)
            $null = $sb.Append($substring)
            $remainingMessage = $message.Substring($substring.Length).Trim()
            $null = $sb.Append($newline)
            while (($remainingMessage.Length + $prefixLength) -gt $windowWidth) {
                $subMessage = $prefix + $remainingMessage
                $substring = TruncateString -InputObject $subMessage -length ($windowWidth + $prefixVtLength)

                if ($substring.Length - $prefix.Length -gt 0) {
                    $null = $sb.Append($substring)
                    $null = $sb.Append($newline)
                    $remainingMessage = $remainingMessage.Substring($substring.Length - $prefix.Length).Trim()
                } else {
                    break
                }
            }
            $null = $sb.Append($prefix + $remainingMessage.Trim())
            $message = $sb.ToString()
        }

        $message += $newline
    }

    $posmsg += "${errorColor}" + $message

    $reason = 'Error'
    if ($InputObject.Exception -and $InputObject.Exception.WasThrownFromThrowStatement) {
        $reason = 'Exception'
        # MyCommand can be the script block, so we don't want to show that so check if it's an actual command
    } elseif ($Invocation.MyCommand -and $Invocation.MyCommand.Name -and (Get-Command -Name $Invocation.MyCommand -ErrorAction Ignore)) {
        $reason = $Invocation.MyCommand
    } elseif ($InputObject.CategoryInfo.Activity) {
        # If it's a scriptblock, better to show the command in the scriptblock that had the error
        $reason = $InputObject.CategoryInfo.Activity
    } elseif ($Invocation.MyCommand) {
        $reason = $Invocation.MyCommand
    } elseif ($Invocation.InvocationName) {
        $reason = $Invocation.InvocationName
    } elseif ($InputObject.CategoryInfo.Category) {
        $reason = $InputObject.CategoryInfo.Category
    } elseif ($InputObject.CategoryInfo.Reason) {
        $reason = $InputObject.CategoryInfo.Reason
    }

    "${errorColor}${reason}: ${posmsg}${resetcolor}"
}
#EndRegion './private/GetConciseMessage.ps1' 175
#Region './private/GetErrorMessage.ps1' -1

filter GetErrorTitle {
    [CmdletBinding()]
    [OUtputType([string])]
    param(
        [Parameter(ValueFromPipeline)]
        [System.Management.Automation.ErrorRecord]
        $InputObject
    )
    if ($InputObject.ErrorDetails -and $InputObject.ErrorDetails.Message) {
        $InputObject.ErrorDetails.Message
    } else {
        if ($InputObject.CategoryInfo.Category -eq 'ParserError' -and $InputObject.Exception.Message.Contains("~$newline")) {
            # need to parse out the relevant part of the pre-rendered positionmessage
            $InputObject.Exception.Message.split("~$newline")[1].split("${newline}${newline}")[0]
        } elseif ($InputObject.Exception) {
            $InputObject.Exception.Message
        } elseif ($InputObject.Message) {
            $InputObject.Message
        } else {
            $InputObject.ToString()
        }
    }
}
#EndRegion './private/GetErrorMessage.ps1' 24
#Region './private/GetErrorPrefix.ps1' -1

filter GetErrorPrefix {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline)]
        $InputObject
    )
    if (@('NativeCommandErrorMessage', 'NativeCommandError') -notcontains $_.FullyQualifiedErrorId) {
        if ($InputObject -is [System.Exception]) {
            $InputObject.GetType().FullName + ' : '
        } else {
            $myinv = $InputObject.InvocationInfo
            if ($myinv -and $myinv.MyCommand) {
                switch -regex ( $myinv.MyCommand.CommandType ) {
                    ([System.Management.Automation.CommandTypes]::ExternalScript) {
                        if ($myinv.MyCommand.Path) {
                            $myinv.MyCommand.Path + ' : '
                        }
                        break
                    }

                    ([System.Management.Automation.CommandTypes]::Script) {
                        if ($myinv.MyCommand.ScriptBlock) {
                            $myinv.MyCommand.ScriptBlock.ToString() + ' : '
                        }
                        break
                    }
                    default {
                        if ($myinv.InvocationName -match '^[&amp;\.]?$') {
                            if ($myinv.MyCommand.Name) {
                                $myinv.MyCommand.Name + ' : '
                            }
                        } else {
                            $myinv.InvocationName + ' : '
                        }
                        break
                    }
                }
            } elseif ($myinv -and $myinv.InvocationName) {
                $myinv.InvocationName + ' : '
            }
        }
    }
}
#EndRegion './private/GetErrorPrefix.ps1' 44
#Region './private/GetErrorTitle.ps1' -1

filter GetErrorTitle {
    [CmdletBinding()]
    [OUtputType([string])]
    param(
        [Parameter(ValueFromPipeline)]
        [System.Management.Automation.ErrorRecord]
        $InputObject
    )

    if ($InputObject.Exception -and $InputObject.Exception.WasThrownFromThrowStatement) {
        'Exception'
        # MyCommand can be the script block, so we don't want to show that so check if it's an actual command
    } elseif ($InputObject.InvocationInfo.MyCommand -and $InputObject.InvocationInfo.MyCommand.Name -and (Get-Command -Name $InputObject.InvocationInfo.MyCommand -ErrorAction Ignore)) {
        $InputObject.InvocationInfo.MyCommand
    } elseif ($InputObject.CategoryInfo.Activity) {
        # If it's a scriptblock, better to show the command in the scriptblock that had the error
        $InputObject.CategoryInfo.Activity
    } elseif ($InputObject.InvocationInfo.MyCommand) {
        $InputObject.InvocationInfo.MyCommand
    } elseif ($InputObject.InvocationInfo.InvocationName) {
        $InputObject.InvocationInfo.InvocationName
    } elseif ($InputObject.CategoryInfo.Category) {
        $InputObject.CategoryInfo.Category
    } elseif ($InputObject.CategoryInfo.Reason) {
        $InputObject.CategoryInfo.Reason
    } else {
        'Error'
    }
}
#EndRegion './private/GetErrorTitle.ps1' 30
#Region './private/GetGoogleWorkflowPositionMessage.ps1' -1

filter GetGoogleWorkflowPositionMessage {
    [CmdletBinding()]
    [OUtputType([string])]
    param(
        [Parameter(ValueFromPipeline)]
        [System.Management.Automation.ErrorRecord]
        $InputObject
    )
    $InvocationInfo = $InputObject.InvocationInfo
    # Handle case where there is a TargetObject from a Pester `Should` assertion failure and we can show the error at the target rather than the script source
    # Note that in some versions, this is a Dictionary<,> and in others it's a hashtable. So we explicitly cast to a shared interface in the method invocation
    # to force using `IDictionary.Contains`. Hashtable does have it's own `ContainKeys` as well, but if they ever opt to use a custom `IDictionary`, that may not.
    $useTargetObject = $null -ne $InputObject.TargetObject -and
                    $InputObject.TargetObject -is [System.Collections.IDictionary] -and
                    ([System.Collections.IDictionary]$InputObject.TargetObject).Contains('Line') -and
                    ([System.Collections.IDictionary]$InputObject.TargetObject).Contains('LineText')

    $file = if ($useTargetObject) {
        "$($InputObject.TargetObject.File)"
    } elseif (.ScriptName) {
        "$($InvocationInfo.ScriptName)"
    }

    $line = if ($useTargetObject) {
        $InputObject.TargetObject.Line
    } else {
        $InvocationInfo.ScriptLineNumber
    }

    if ($useTargetObject) {
        "file=$file,line=$line"
    } else {
        $column = $InvocationInfo.OffsetInLine

        $Length = $InvocationInfo.PositionMessage.Split($newline)[-1].Substring(1).Trim().Length
        $endColumn = $column + $Length
        "file=$file,line=$line,col=$column,endColumn=$endColumn"
    }
}
#EndRegion './private/GetGoogleWorkflowPositionMessage.ps1' 40
#Region './private/GetListRecursive.ps1' -1

function GetListRecursive {
    <#
        .SYNOPSIS
            Internal implementation of the Detailed error view to support recursion and indentation
    #>

    [CmdletBinding()]
    param(
        $InputObject,
        [int]$indent = 0,
        [int]$depth = 1
    )
    $output = [System.Text.StringBuilder]::new()
    $padding = ' ' * $indent

    $expandTypes = @(
        'Microsoft.Rest.HttpRequestMessageWrapper'
        'Microsoft.Rest.HttpResponseMessageWrapper'
        'System.Management.Automation.InvocationInfo'
    )

    # The built-in DetailedView aligns all the ":" characters, but it's awful

    $addedProperty = $false
    foreach ($prop in $InputObject.PSObject.Properties) {
        # PowerShell creates an ErrorRecord property on Exceptions that points back to the parent ErrorRecord.
        # This is basically a circular reference that causes repeated informtion, so we're going to skip them
        if ($prop.Value -is [System.Management.Automation.ErrorRecord] -and $depth -ge 2) {
            continue
        }
        # don't show empty properties or our added property for $error[index]
        if ($null -ne $prop.Value -and $prop.Value -ne [string]::Empty -and $prop.Value.count -gt 0 -and $prop.Name -ne 'PSErrorIndex') {
            $addedProperty = $true
            $null = $output.Append($padding)
            $null = $output.Append($accentColor)
            $null = $output.Append($prop.Name)
            $null = $output.Append(': ')
            $null = $output.Append($resetColor)

            [int]$nextIndent = $indent + 2
            [int]$nextDepth = $depth + 1
            $nextPadding = ' ' * $nextIndent

            # only show nested objects that are Exceptions, ErrorRecords, or types defined in $expandTypes
            if ($prop.Value -is [Exception] -or
                $prop.Value -is [System.Management.Automation.ErrorRecord] -or
                $expandTypes -contains $prop.TypeNameOfValue -or
                        ($null -ne $prop.TypeNames -and $expandTypes -contains $prop.TypeNames[0])) {

                if ($depth -ge $maxDepth) {
                    $null = $output.Append($ellipsis)
                } else {
                    # For Exceptions, add a fake "Type" property
                    if ($prop.Value -is [Exception]) {
                        $null = $output.Append(( $accentColor + "[" + $prop.Value.GetType().FullName + "]" + $resetColor))
                    }
                    $null = $output.Append($newline)
                    $null = $output.Append((GetListRecursive $prop.Value $nextIndent $nextDepth))
                }
            } elseif ($prop.Name -eq 'TargetSite' -and $prop.Value.GetType().Name -eq 'RuntimeMethodInfo') {
                # `TargetSite` has many members that are not useful visually, so we have a reduced view of the relevant members
                if ($depth -ge $maxDepth) {
                    $null = $output.Append($ellipsis)
                } else {
                    $targetSite = [PSCustomObject]@{
                        Name          = $prop.Value.Name
                        DeclaringType = $prop.Value.DeclaringType
                        MemberType    = $prop.Value.MemberType
                        Module        = $prop.Value.Module
                    }

                    $null = $output.Append($newline)
                    $null = $output.Append((GetListRecursive $targetSite $nextIndent $nextDepth))
                }
            } elseif ($prop.Name -eq 'StackTrace') {
                # StackTrace is handled specifically because the lines are typically long but we can't trucate them, so we don't indent it any more
                $null = $output.Append($newline)
                # $null = $output.Append($prop.Value)
                $Wrap = @{
                    Width = $Host.UI.RawUI.BufferSize.Width - 2
                    IndentPadding = ""
                    WrappedIndent = " "
                    Colors        = $LineColors
                }
                $null = $output.Append(($prop.Value | WrapString @Wrap))
            } elseif ($prop.Name -eq 'HResult') {
                # `HResult` is handled specifically so we can format it in hex
                # $null = $output.Append($newline)
                $null = $output.Append("0x{0:x} ({0})" -f $prop.Value)
            } elseif ($prop.Name -eq 'PipelineIterationInfo') {
                # I literally have no idea what use this is
                $null = $output.Append($prop.Value -join ', ')
            } elseif ($prop.Value.GetType().Name.StartsWith('Dictionary') -or $prop.Value.GetType().Name -eq 'Hashtable') {
                # Dictionary and Hashtable we want to show as Key/Value pairs
                $null = $output.Append($newline)
                foreach ($key in $prop.Value.Keys) {
                    if ($key -eq 'Authorization') {
                        $null = $output.Append("${nextPadding}${accentColor}${key}: ${resetColor}${ellipsis}${newline}")
                    } else {
                        $null = $output.Append("${nextPadding}${accentColor}${key}: ${resetColor}$($prop.Value[$key])${newline}")
                    }
                }
            } elseif (!($prop.Value -is [System.String]) -and $null -ne $prop.Value.GetType().GetInterface('IEnumerable') -and $prop.Name -ne 'Data') {
                # if the object implements IEnumerable and not a string, we try to show each object
                # We ignore the `Data` property as it can contain lots of type information by the interpreter that isn't useful here

                if ($depth -ge $maxDepth) {
                    $null = $output.Append($ellipsis)
                } else {
                    $isFirstElement = $true
                    foreach ($value in $prop.Value) {
                        $null = $output.Append($newline)

                        if ($value -is [Type]) {
                            # Just show the typename instead of it as an object
                            $null = $output.Append("[$($value.ToString())]")
                        } elseif ($value -is [string] -or $value.GetType().IsPrimitive) {
                            $null = $output.Append("${value}")
                        } else {
                            if (!$isFirstElement) {
                                $null = $output.Append($newline)
                            }
                            $null = $output.Append((GetListRecursive $value $nextIndent $nextDepth))
                        }
                        $isFirstElement = $false
                    }
                }
            }  elseif ($prop.Value -is [Type]) {
                # Just show the typename instead of it as an object
                $null = $output.Append("[$($prop.Value.ToString())]")
            } else {
                # Anything else, we convert to string.
                # ToString() can throw so we use LanguagePrimitives.TryConvertTo() to hide a convert error
                $value = $null
                if ([System.Management.Automation.LanguagePrimitives]::TryConvertTo($prop.Value, [string], [ref]$value) -and $null -ne $value) {
                    $value = $value.Trim()
                    if ($InputObject -is [System.Management.Automation.InvocationInfo] -and $prop.Name -eq 'PositionMessage') {
                        # Make the underline red
                        $value = $value.Insert($value.IndexOf('~'), $errorColor)
                    } elseif ( ($InputObject -is [System.Management.Automation.ErrorRecord] -or
                                $InputObject -is [System.Exception]) -and $prop.Name -in 'Message', 'FullyQualifiedErrorId', 'CategoryInfo') {
                        $value = $errorColor + $value
                    }
                    $Wrap = @{
                        Width = $Host.UI.RawUI.BufferSize.Width - 2
                        # Because the first line contains the property name, we don't want to indent it
                        FirstLineIndent = ''
                        # But all other lines (including wrapped lines) should be indented to align
                        IndentPadding = " " * ($nextIndent + $prop.Name.Length)
                        Colors = $LineColors
                    }

                    $null = $output.Append(($value | WrapString @Wrap))
                }
            }

            $null = $output.Append($newline)
        }
    }

    # if we had added nested properties, we need to remove the last newline
    if ($addedProperty) {
        $null = $output.Remove($output.Length - $newline.Length, $newline.Length)
    }

    $output.ToString()
}
#EndRegion './private/GetListRecursive.ps1' 167
#Region './private/GetYamlRecursive.ps1' -1

function GetYamlRecursive {
    <#
        .SYNOPSIS
            Creates a description of an ErrorRecord that looks like valid Yaml
        .DESCRIPTION
            This produces valid Yaml output from ErrorRecord you pass to it, recursively.
    #>

    [CmdletBinding()]
    param(
        # The object that you want to convert to YAML
        [Parameter(Mandatory, ValueFromPipeline)]
        $InputObject,

        # Optionally, a limit on the depth to recurse properties (defaults to 16)
        [parameter()]
        [int]$depth = 1,

        # If set, include empty and null properties in the output
        [switch]$IncludeEmpty,

        # Recursive use only. Handles indentation for formatting
        [parameter(DontShow)]
        [int]$NestingLevel = 0,

        # use OuterXml instead of treating XmlDocuments like objects
        [parameter(DontShow)]
        [switch]$XmlAsXml
    )
    process {
        $Width = $Host.UI.RawUI.BufferSize.Width - 1 - ($NestingLevel * 2)
        $__hasoutput = $true
        $padding = ' ' * $NestingLevel # # lets just create our left-padding for the block
        $Recurse = @{
            'Depth'        = $depth + 1
            'NestingLevel' = $NestingLevel + 1
            'XmlAsXml'     = $XmlAsXml
        }
        $Wrap = @{
            Width         = $Host.UI.RawUI.BufferSize.Width - 2
            IndentPadding = $padding
            Colors        = $LineColors
        }

        @(
            if ($Null -eq $InputObject) { return 'null' } # if it is null return null
            if ($NestingLevel -eq 0 -and $local:__hasoutput) { '---' } # if we have output before, add a yaml separator

            try {
                switch ($InputObject) {
                    # prevent these values being expanded
                    <# if ($Type -in @( 'guid',
                            , 'datatable', 'List`1','SqlDataReader', 'datarow', 'type',
                            'MemberTypes', 'RuntimeModule', 'RuntimeType', 'ErrorCategoryInfo', 'CommandInfo', 'CmdletInfo' )) {
                    #>

                    { $InputObject -is [scriptblock] } {
                        "{$($InputObject.ToString())}"
                        break
                    }
                    { $InputObject -is [type] } {
                        "'[$($InputObject.FullName)]'"
                        break
                    }
                    { $InputObject -is [System.Xml.XmlDocument] -or $InputObject -is [System.Xml.XmlElement] } {
                        "|"
                        $InputObject.OuterXml | WrapString @Wrap
                        break
                    }
                    { $InputObject -is [datetime] -or $InputObject -is [datetimeoffset] } {
                        # s=SortableDateTimePattern (based on ISO 8601) using local time
                        $InputObject.ToString('s')
                        break
                    }
                    { $InputObject -is [timespan] -or $InputObject -is [version] -or $InputObject -is [uri] } {
                        # s=SortableDateTimePattern (based on ISO 8601) using local time
                        "'$InputObject'"
                        break
                    }
                    # yaml case for booleans
                    { $InputObject -is [bool] } {
                        if ($InputObject) { 'true' } else { 'false' }
                        break
                    }
                    # If we're going to go over our depth, just output like it's a value type
                    # ValueTypes are just output with no possibility of wrapping or recursion
                    { $InputObject -is [Enum] -or $InputObject.GetType().BaseType -eq [ValueType] -or $depth -gt $maxDepth } {
                        "$InputObject"
                        break
                    }
                    # 'PSNoteProperty' {
                    # # Write-Verbose "$($padding)Show $($property.Name)"
                    # GetYamlRecursive -InputObject $InputObject.Value @Recurse }
                    { $InputObject -is [System.Collections.IDictionary] } {
                        foreach ($kvp in  $InputObject.GetEnumerator()) {
                            # Write-Verbose "$($padding)Enumerate $($property.Name)"
                            "$newline$padding$accentColor$($kvp.Name):$resetColor " +
                            (GetYamlRecursive -InputObject $kvp.Value @Recurse)
                        }
                        break
                    }

                    { $InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string] } {
                        foreach ($item in $InputObject) {
                            # Write-Verbose "$($padding)Enumerate $($property.Name)"
                            $Value = GetYamlRecursive -InputObject $item @Recurse
                            # if ($Value -ne 'null' -or $IncludeEmpty) {
                            "$newline$accentColor$padding$resetColor- $Value"
                            # }
                        }
                        break
                    }

                    # Limit recursive enumeration to specific types:
                    { $InputObject -is [Exception] -or ($InputObject -is [System.Management.Automation.ErrorRecord] -and $depth -lt 2) -or
                        $InputObject.PSTypeNames[0] -in @(
                            # 'System.Exception'
                            # 'System.Management.Automation.ErrorRecord'
                            'Microsoft.Rest.HttpRequestMessageWrapper'
                            'Microsoft.Rest.HttpResponseMessageWrapper'
                            'System.Management.Automation.InvocationInfo'
                        ) } {
                        if ($depth -ge $maxDepth) {
                            $null = $output.Append($ellipsis)
                        }
                        # For exceptions, output a fake property for the exception type
                        if ($InputObject -is [Exception]) {
                            "$newline$padding${accentColor}#Type:$resetColor ${accentColor}" + $InputObject.GetType().FullName + $resetColor
                        }
                        foreach ($property in $InputObject.PSObject.Properties) {
                            if ($property.Value) {
                                $Value = GetYamlRecursive -InputObject $property.Value @Recurse
                                # For special cases, add some color:
                                if ($property.Name -eq "PositionMessage") {
                                    $Value = $Value -replace "(\+\s+)(~+)", "`$1$errorColor`$2$resetColor"
                                }
                                if ($InputObject -is [Exception] -and $property.Name -eq "Message") {
                                    $Value = "$errorColor$Value$resetColor"
                                }
                                if ((-not [string]::IsNullOrEmpty($Value) -and $Value -ne 'null' -and $Value.Count -gt 0) -or $IncludeEmpty) {
                                    "$newline$padding$accentColor$($property.Name):$resetColor " + $Value
                                }
                            }
                        }
                        break
                    }
                    # 'generic' {
                    # foreach($key in $InputObject.Keys) {
                    # # Write-Verbose "$($padding)Enumerate $($key)"
                    # $Value = GetYamlRecursive -InputObject $InputObject.$key @Recurse
                    # if ((-not [string]::IsNullOrEmpty($Value) -and $Value -ne 'null') -or $IncludeEmpty) {
                    # "$padding$accentColor$($key):$resetColor " + $Value
                    # }
                    # }
                    # }
                    default {
                        # Treat anything else as a string
                        $StringValue = $null
                        if ([System.Management.Automation.LanguagePrimitives]::TryConvertTo($InputObject, [string], [ref]$StringValue) -and $null -ne $StringValue) {
                            $StringValue = $StringValue.Trim()
                            if ($StringValue -match '[\r\n]' -or $StringValue.Length -gt $Width) {
                                ">$newline" # signal that we are going to use the readable 'newlines-folded' format
                                $StringValue | WrapString @Wrap -EmphasizeOriginalNewlines
                            } elseif ($StringValue.Contains(":")) {
                                "'$($StringValue -replace '''', '''''')'" # single quote it
                            } else {
                                "$($StringValue -replace '''', '''''')"
                            }
                        } else {
                            Write-Warning "Unable to convert $($InputObject.GetType().FullName) to string"
                        }
                    }
                }
            } catch {
                "Error formatting error ($($_)) in script $($_.InvocationInfo.ScriptName) $($_.InvocationInfo.Line.Trim()) (line $($_.InvocationInfo.ScriptLineNumber)) char $($_.InvocationInfo.OffsetInLine) executing $($_.InvocationInfo.MyCommand) on $type object '$($InputObject)' Class: $($InputObject.GetType().Name) BaseClass: $($InputObject.GetType().BaseType.Name) "
            }
        ) -join ""
    }
}
#EndRegion './private/GetYamlRecursive.ps1' 178
#Region './private/Graphemes.ps1' -1

# https://github.com/sindresorhus/get-east-asian-width
function Test-Ambiguous([int]$x) {
    return $x -eq 0xA1 -or $x -eq 0xA4 -or $x -eq 0xA7 -or $x -eq 0xA8 -or $x -eq 0xAA -or $x -eq 0xAD -or $x -eq 0xAE -or $x -ge 0xB0 -and $x -le 0xB4 -or $x -ge 0xB6 -and $x -le 0xBA -or $x -ge 0xBC -and $x -le 0xBF -or $x -eq 0xC6 -or $x -eq 0xD0 -or $x -eq 0xD7 -or $x -eq 0xD8 -or $x -ge 0xDE -and $x -le 0xE1 -or $x -eq 0xE6 -or $x -ge 0xE8 -and $x -le 0xEA -or $x -eq 0xEC -or $x -eq 0xED -or $x -eq 0xF0 -or $x -eq 0xF2 -or $x -eq 0xF3 -or $x -ge 0xF7 -and $x -le 0xFA -or $x -eq 0xFC -or $x -eq 0xFE -or $x -eq 0x101 -or $x -eq 0x111 -or $x -eq 0x113 -or $x -eq 0x11B -or $x -eq 0x126 -or $x -eq 0x127 -or $x -eq 0x12B -or $x -ge 0x131 -and $x -le 0x133 -or $x -eq 0x138 -or $x -ge 0x13F -and $x -le 0x142 -or $x -eq 0x144 -or $x -ge 0x148 -and $x -le 0x14B -or $x -eq 0x14D -or $x -eq 0x152 -or $x -eq 0x153 -or $x -eq 0x166 -or $x -eq 0x167 -or $x -eq 0x16B -or $x -eq 0x1CE -or $x -eq 0x1D0 -or $x -eq 0x1D2 -or $x -eq 0x1D4 -or $x -eq 0x1D6 -or $x -eq 0x1D8 -or $x -eq 0x1DA -or $x -eq 0x1DC -or $x -eq 0x251 -or $x -eq 0x261 -or $x -eq 0x2C4 -or $x -eq 0x2C7 -or $x -ge 0x2C9 -and $x -le 0x2CB -or $x -eq 0x2CD -or $x -eq 0x2D0 -or $x -ge 0x2D8 -and $x -le 0x2DB -or $x -eq 0x2DD -or $x -eq 0x2DF -or $x -ge 0x300 -and $x -le 0x36F -or $x -ge 0x391 -and $x -le 0x3A1 -or $x -ge 0x3A3 -and $x -le 0x3A9 -or $x -ge 0x3B1 -and $x -le 0x3C1 -or $x -ge 0x3C3 -and $x -le 0x3C9 -or $x -eq 0x401 -or $x -ge 0x410 -and $x -le 0x44F -or $x -eq 0x451 -or $x -eq 0x2010 -or $x -ge 0x2013 -and $x -le 0x2016 -or $x -eq 0x2018 -or $x -eq 0x2019 -or $x -eq 0x201C -or $x -eq 0x201D -or $x -ge 0x2020 -and $x -le 0x2022 -or $x -ge 0x2024 -and $x -le 0x2027 -or $x -eq 0x2030 -or $x -eq 0x2032 -or $x -eq 0x2033 -or $x -eq 0x2035 -or $x -eq 0x203B -or $x -eq 0x203E -or $x -eq 0x2074 -or $x -eq 0x207F -or $x -ge 0x2081 -and $x -le 0x2084 -or $x -eq 0x20AC -or $x -eq 0x2103 -or $x -eq 0x2105 -or $x -eq 0x2109 -or $x -eq 0x2113 -or $x -eq 0x2116 -or $x -eq 0x2121 -or $x -eq 0x2122 -or $x -eq 0x2126 -or $x -eq 0x212B -or $x -eq 0x2153 -or $x -eq 0x2154 -or $x -ge 0x215B -and $x -le 0x215E -or $x -ge 0x2160 -and $x -le 0x216B -or $x -ge 0x2170 -and $x -le 0x2179 -or $x -eq 0x2189 -or $x -ge 0x2190 -and $x -le 0x2199 -or $x -eq 0x21B8 -or $x -eq 0x21B9 -or $x -eq 0x21D2 -or $x -eq 0x21D4 -or $x -eq 0x21E7 -or $x -eq 0x2200 -or $x -eq 0x2202 -or $x -eq 0x2203 -or $x -eq 0x2207 -or $x -eq 0x2208 -or $x -eq 0x220B -or $x -eq 0x220F -or $x -eq 0x2211 -or $x -eq 0x2215 -or $x -eq 0x221A -or $x -ge 0x221D -and $x -le 0x2220 -or $x -eq 0x2223 -or $x -eq 0x2225 -or $x -ge 0x2227 -and $x -le 0x222C -or $x -eq 0x222E -or $x -ge 0x2234 -and $x -le 0x2237 -or $x -eq 0x223C -or $x -eq 0x223D -or $x -eq 0x2248 -or $x -eq 0x224C -or $x -eq 0x2252 -or $x -eq 0x2260 -or $x -eq 0x2261 -or $x -ge 0x2264 -and $x -le 0x2267 -or $x -eq 0x226A -or $x -eq 0x226B -or $x -eq 0x226E -or $x -eq 0x226F -or $x -eq 0x2282 -or $x -eq 0x2283 -or $x -eq 0x2286 -or $x -eq 0x2287 -or $x -eq 0x2295 -or $x -eq 0x2299 -or $x -eq 0x22A5 -or $x -eq 0x22BF -or $x -eq 0x2312 -or $x -ge 0x2460 -and $x -le 0x24E9 -or $x -ge 0x24EB -and $x -le 0x254B -or $x -ge 0x2550 -and $x -le 0x2573 -or $x -ge 0x2580 -and $x -le 0x258F -or $x -ge 0x2592 -and $x -le 0x2595 -or $x -eq 0x25A0 -or $x -eq 0x25A1 -or $x -ge 0x25A3 -and $x -le 0x25A9 -or $x -eq 0x25B2 -or $x -eq 0x25B3 -or $x -eq 0x25B6 -or $x -eq 0x25B7 -or $x -eq 0x25BC -or $x -eq 0x25BD -or $x -eq 0x25C0 -or $x -eq 0x25C1 -or $x -ge 0x25C6 -and $x -le 0x25C8 -or $x -eq 0x25CB -or $x -ge 0x25CE -and $x -le 0x25D1 -or $x -ge 0x25E2 -and $x -le 0x25E5 -or $x -eq 0x25EF -or $x -eq 0x2605 -or $x -eq 0x2606 -or $x -eq 0x2609 -or $x -eq 0x260E -or $x -eq 0x260F -or $x -eq 0x261C -or $x -eq 0x261E -or $x -eq 0x2640 -or $x -eq 0x2642 -or $x -eq 0x2660 -or $x -eq 0x2661 -or $x -ge 0x2663 -and $x -le 0x2665 -or $x -ge 0x2667 -and $x -le 0x266A -or $x -eq 0x266C -or $x -eq 0x266D -or $x -eq 0x266F -or $x -eq 0x269E -or $x -eq 0x269F -or $x -eq 0x26BF -or $x -ge 0x26C6 -and $x -le 0x26CD -or $x -ge 0x26CF -and $x -le 0x26D3 -or $x -ge 0x26D5 -and $x -le 0x26E1 -or $x -eq 0x26E3 -or $x -eq 0x26E8 -or $x -eq 0x26E9 -or $x -ge 0x26EB -and $x -le 0x26F1 -or $x -eq 0x26F4 -or $x -ge 0x26F6 -and $x -le 0x26F9 -or $x -eq 0x26FB -or $x -eq 0x26FC -or $x -eq 0x26FE -or $x -eq 0x26FF -or $x -eq 0x273D -or $x -ge 0x2776 -and $x -le 0x277F -or $x -ge 0x2B56 -and $x -le 0x2B59 -or $x -ge 0x3248 -and $x -le 0x324F -or $x -ge 0xE000 -and $x -le 0xF8FF -or $x -ge 0xFE00 -and $x -le 0xFE0F -or $x -eq 0xFFFD -or $x -ge 0x1F100 -and $x -le 0x1F10A -or $x -ge 0x1F110 -and $x -le 0x1F12D -or $x -ge 0x1F130 -and $x -le 0x1F169 -or $x -ge 0x1F170 -and $x -le 0x1F18D -or $x -eq 0x1F18F -or $x -eq 0x1F190 -or $x -ge 0x1F19B -and $x -le 0x1F1AC -or $x -ge 0xE0100 -and $x -le 0xE01EF -or $x -ge 0xF0000 -and $x -le 0xFFFFD -or $x -ge 0x100000 -and $x -le 0x10FFFD
}

function Test-FullWidth([int]$x) {
    return $x -eq 0x3000 -or $x -ge 0xFF01 -and $x -le 0xFF60 -or $x -ge 0xFFE0 -and $x -le 0xFFE6
}

function Test-Wide([int]$x) {
    return $x -ge 0x1100 -and $x -le 0x115F -or $x -eq 0x231A -or $x -eq 0x231B -or $x -eq 0x2329 -or $x -eq 0x232A -or $x -ge 0x23E9 -and $x -le 0x23EC -or $x -eq 0x23F0 -or $x -eq 0x23F3 -or $x -eq 0x25FD -or $x -eq 0x25FE -or $x -eq 0x2614 -or $x -eq 0x2615 -or $x -ge 0x2630 -and $x -le 0x2637 -or $x -ge 0x2648 -and $x -le 0x2653 -or $x -eq 0x267F -or $x -ge 0x268A -and $x -le 0x268F -or $x -eq 0x2693 -or $x -eq 0x26A1 -or $x -eq 0x26AA -or $x -eq 0x26AB -or $x -eq 0x26BD -or $x -eq 0x26BE -or $x -eq 0x26C4 -or $x -eq 0x26C5 -or $x -eq 0x26CE -or $x -eq 0x26D4 -or $x -eq 0x26EA -or $x -eq 0x26F2 -or $x -eq 0x26F3 -or $x -eq 0x26F5 -or $x -eq 0x26FA -or $x -eq 0x26FD -or $x -eq 0x2705 -or $x -eq 0x270A -or $x -eq 0x270B -or $x -eq 0x2728 -or $x -eq 0x274C -or $x -eq 0x274E -or $x -ge 0x2753 -and $x -le 0x2755 -or $x -eq 0x2757 -or $x -ge 0x2795 -and $x -le 0x2797 -or $x -eq 0x27B0 -or $x -eq 0x27BF -or $x -eq 0x2B1B -or $x -eq 0x2B1C -or $x -eq 0x2B50 -or $x -eq 0x2B55 -or $x -ge 0x2E80 -and $x -le 0x2E99 -or $x -ge 0x2E9B -and $x -le 0x2EF3 -or $x -ge 0x2F00 -and $x -le 0x2FD5 -or $x -ge 0x2FF0 -and $x -le 0x2FFF -or $x -ge 0x3001 -and $x -le 0x303E -or $x -ge 0x3041 -and $x -le 0x3096 -or $x -ge 0x3099 -and $x -le 0x30FF -or $x -ge 0x3105 -and $x -le 0x312F -or $x -ge 0x3131 -and $x -le 0x318E -or $x -ge 0x3190 -and $x -le 0x31E5 -or $x -ge 0x31EF -and $x -le 0x321E -or $x -ge 0x3220 -and $x -le 0x3247 -or $x -ge 0x3250 -and $x -le 0xA48C -or $x -ge 0xA490 -and $x -le 0xA4C6 -or $x -ge 0xA960 -and $x -le 0xA97C -or $x -ge 0xAC00 -and $x -le 0xD7A3 -or $x -ge 0xF900 -and $x -le 0xFAFF -or $x -ge 0xFE10 -and $x -le 0xFE19 -or $x -ge 0xFE30 -and $x -le 0xFE52 -or $x -ge 0xFE54 -and $x -le 0xFE66 -or $x -ge 0xFE68 -and $x -le 0xFE6B -or $x -ge 0x16FE0 -and $x -le 0x16FE4 -or $x -eq 0x16FF0 -or $x -eq 0x16FF1 -or $x -ge 0x17000 -and $x -le 0x187F7 -or $x -ge 0x18800 -and $x -le 0x18CD5 -or $x -ge 0x18CFF -and $x -le 0x18D08 -or $x -ge 0x1AFF0 -and $x -le 0x1AFF3 -or $x -ge 0x1AFF5 -and $x -le 0x1AFFB -or $x -eq 0x1AFFD -or $x -eq 0x1AFFE -or $x -ge 0x1B000 -and $x -le 0x1B122 -or $x -eq 0x1B132 -or $x -ge 0x1B150 -and $x -le 0x1B152 -or $x -eq 0x1B155 -or $x -ge 0x1B164 -and $x -le 0x1B167 -or $x -ge 0x1B170 -and $x -le 0x1B2FB -or $x -ge 0x1D300 -and $x -le 0x1D356 -or $x -ge 0x1D360 -and $x -le 0x1D376 -or $x -eq 0x1F004 -or $x -eq 0x1F0CF -or $x -eq 0x1F18E -or $x -ge 0x1F191 -and $x -le 0x1F19A -or $x -ge 0x1F200 -and $x -le 0x1F202 -or $x -ge 0x1F210 -and $x -le 0x1F23B -or $x -ge 0x1F240 -and $x -le 0x1F248 -or $x -eq 0x1F250 -or $x -eq 0x1F251 -or $x -ge 0x1F260 -and $x -le 0x1F265 -or $x -ge 0x1F300 -and $x -le 0x1F320 -or $x -ge 0x1F32D -and $x -le 0x1F335 -or $x -ge 0x1F337 -and $x -le 0x1F37C -or $x -ge 0x1F37E -and $x -le 0x1F393 -or $x -ge 0x1F3A0 -and $x -le 0x1F3CA -or $x -ge 0x1F3CF -and $x -le 0x1F3D3 -or $x -ge 0x1F3E0 -and $x -le 0x1F3F0 -or $x -eq 0x1F3F4 -or $x -ge 0x1F3F8 -and $x -le 0x1F43E -or $x -eq 0x1F440 -or $x -ge 0x1F442 -and $x -le 0x1F4FC -or $x -ge 0x1F4FF -and $x -le 0x1F53D -or $x -ge 0x1F54B -and $x -le 0x1F54E -or $x -ge 0x1F550 -and $x -le 0x1F567 -or $x -eq 0x1F57A -or $x -eq 0x1F595 -or $x -eq 0x1F596 -or $x -eq 0x1F5A4 -or $x -ge 0x1F5FB -and $x -le 0x1F64F -or $x -ge 0x1F680 -and $x -le 0x1F6C5 -or $x -eq 0x1F6CC -or $x -ge 0x1F6D0 -and $x -le 0x1F6D2 -or $x -ge 0x1F6D5 -and $x -le 0x1F6D7 -or $x -ge 0x1F6DC -and $x -le 0x1F6DF -or $x -eq 0x1F6EB -or $x -eq 0x1F6EC -or $x -ge 0x1F6F4 -and $x -le 0x1F6FC -or $x -ge 0x1F7E0 -and $x -le 0x1F7EB -or $x -eq 0x1F7F0 -or $x -ge 0x1F90C -and $x -le 0x1F93A -or $x -ge 0x1F93C -and $x -le 0x1F945 -or $x -ge 0x1F947 -and $x -le 0x1F9FF -or $x -ge 0x1FA70 -and $x -le 0x1FA7C -or $x -ge 0x1FA80 -and $x -le 0x1FA89 -or $x -ge 0x1FA8F -and $x -le 0x1FAC6 -or $x -ge 0x1FACE -and $x -le 0x1FADC -or $x -ge 0x1FADF -and $x -le 0x1FAE9 -or $x -ge 0x1FAF0 -and $x -le 0x1FAF8 -or $x -ge 0x20000 -and $x -le 0x2FFFD -or $x -ge 0x30000 -and $x -le 0x3FFFD;
}

function Get-Category([int]$x) {
    if (Test-Ambiguous $x) { return 'ambiguous' }

    if (Test-FullWidth $x) { return 'fullwidth' }

    if ($x -eq 0x20A9 -or $x -ge 0xFF61 -and $x -le 0xFFBE -or $x -ge 0xFFC2 -and $x -le 0xFFC7 -or $x -ge 0xFFCA -and $x -le 0xFFCF -or $x -ge 0xFFD2 -and $x -le 0xFFD7 -or $x -ge 0xFFDA -and $x -le 0xFFDC -or $x -ge 0xFFE8 -and $x -le 0xFFEE) {
        return 'halfwidth'
    }

    if ($x -ge 0x20 -and $x -le 0x7E -or $x -eq 0xA2 -or $x -eq 0xA3 -or $x -eq 0xA5 -or $x -eq 0xA6 -or $x -eq 0xAC -or $x -eq 0xAF -or $x -ge 0x27E6 -and $x -le 0x27ED -or $x -eq 0x2985 -or $x -eq 0x2986) {
        return 'narrow'
    }

    if (Test-Wide $x) { return 'wide' }

    return 'neutral'
}
function Get-EastAsianWidthType([char]$codePoint) {
    Get-Category $codePoint
}

function Measure-EastAsianWidth([char]$codePoint, [switch]$AmbiguousAsWide) {
    if ( (Test-FullWidth $codePoint) -or (Test-Wide $codePoint) -or ($AmbiguousAsWide -and (Test-Ambiguous $codePoint)) ) {
        return 2;
    }

    return 1;
}

# For Prettier. This doesn't count "ambiguous" characters or check for valid input.
function Test-NarrowWidth([char]$codePoint) { !(Test-FullWidth $codePoint) -or (Test-Wide $codePoint) }
#EndRegion './private/Graphemes.ps1' 45
#Region './private/ResetColor.ps1' -1

function ResetColor {
    $script:resetColor = ''
    $script:errorColor = ''
    $script:accentColor = ''

    if ($Host.UI.SupportsVirtualTerminal -and ([string]::IsNullOrEmpty($env:__SuppressAnsiEscapeSequences))) {
        $script:resetColor = "$([char]27)[0m"
        $script:errorColor = if ($null -ne $PSStyle.Formatting.Error) { $PSStyle.Formatting.Error } else { "`e[1;31m" }
        $script:accentColor = if ($null -ne $PSStyle.Formatting.ErrorAccent) { $PSStyle.Formatting.ErrorAccent } else { "`e[1;36m" }
    }
}
#EndRegion './private/ResetColor.ps1' 12
#Region './private/TruncateString.ps1' -1

filter TruncateString {
    [CmdletBinding()]
    param(
        # The input string will be wrapped to a certain length, with optional padding on the front
        [Parameter(ValueFromPipeline)]
        [string]$InputObject,

        [Parameter(Position = 0)]
        [Alias('Length')]
        [int]$Width = ($Host.UI.RawUI.BufferSize.Width)
    )
    # $wrappableChars = [char[]]" ,.?!:;-`n`r`t"
    # $maxLength = $width - $IndentPadding.Length -1
    $wrapper = [Regex]::new("((?:$AnsiPattern)*[^-=,.?!:;\s\r\n\t\\\/\|]+(?:$AnsiPattern)*)", "Compiled")

    if ($InputObject.Length -le $Width) {
        return $InputObject
    }

    ($InputObject.Substring(0,$length) -split $wrapper,-2)[0]
}

function TrimAnsi($string) {
    $words = $string -split ' '
    $last = $words.length;

    while ($last > 0) {
        if ((Measure-String $words[$last - 1]) -gt 0) {
            break
        }

        $last--
    }

    if ($last -ne $words.length) {
        return $string
    }

    ($words[0..$last] -join ' ') + ($words[$last..$words.length] -join '')
}
#EndRegion './private/TruncateString.ps1' 41
#Region './public/ConvertTo-CategoryErrorView.ps1' -1

filter ConvertTo-CategoryErrorView {
    <#
        .SYNOPSIS
            Converts an ErrorRecord to a CategoryInfo message string
        .DESCRIPTION
            The default PowerShell "CategoryView" ErrorView
            Copied directly from the PowerShellCore.format.ps1xml
        .LINK
            https://github.com/PowerShell/PowerShell/blob/c444645b0941d73dc769f0bba6ab70d317bd51a9/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs#L1302
    #>

    [CmdletBinding()]
    param(
        # The ErrorRecord to display
        [Parameter(ValueFromPipeline)]
        [System.Management.Automation.ErrorRecord]
        $InputObject
    )
    $resetColor = ''
    $errorColor = ''

    if ($Host.UI.SupportsVirtualTerminal -and ([string]::IsNullOrEmpty($env:__SuppressAnsiEscapeSequences))) {
        $resetColor = "$([char]0x1b)[0m"
        $errorColor = if ($PSStyle.Formatting.Error) { $PSStyle.Formatting.Error } else { "`e[1;31m" }
    }
    $errorColor + $InputObject.CategoryInfo.GetMessage() + $resetColor
}
#EndRegion './public/ConvertTo-CategoryErrorView.ps1' 27
#Region './public/ConvertTo-ConciseErrorView.ps1' -1

function ConvertTo-ConciseErrorView {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline)]
        [System.Management.Automation.ErrorRecord]
        $InputObject
    )
    begin { ResetColor }
    process {
        if ($InputObject.FullyQualifiedErrorId -in 'NativeCommandErrorMessage','NativeCommandError') {
            "${errorColor}$($InputObject.Exception.Message)${resetColor}"
        } else {
            if (!"$accentColor".Length) {
                $local:accentColor = ">>>"
                $local:resetColor = "<<<"
            }

            $message = GetConciseMessage -InputObject $InputObject

            if ($InputObject.PSMessageDetails) {
                $message = $errorColor + ' : ' + $InputObject.PSMessageDetails + $message
            }

            $recommendedAction = $InputObject.ErrorDetails.RecommendedAction
            if (-not [String]::IsNullOrWhiteSpace($recommendedAction)) {
                $message = $message + $newline + ${errorColor} + ' Recommendation: ' + $recommendedAction + ${resetcolor}
            }

            $message
        }
    }
}
#EndRegion './public/ConvertTo-ConciseErrorView.ps1' 33
#Region './public/ConvertTo-DetailedErrorView.ps1' -1

filter ConvertTo-DetailedErrorView {
    <#
        .SYNOPSIS
            Converts an ErrorRecord to a detailed error string
        .DESCRIPTION
            An "improved" version of the PowerShell "DetailedView" ErrorView
            Originally copied from the PowerShellCore.format.ps1xml
        .LINK
            https://github.com/PowerShell/PowerShell/blob/c444645b0941d73dc769f0bba6ab70d317bd51a9/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs#L903
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'maxDepth')]
    [CmdletBinding()]
    param(
        # The ErrorRecord to display
        [Parameter(ValueFromPipeline)]
        [System.Management.Automation.ErrorRecord]
        $InputObject,

        # The maximum depth to recurse into the object
        [int]$maxDepth = 10
    )
    begin { ResetColor }
    process {
        $newline + (GetListRecursive $InputObject) + $newline
        if ($Env:GITHUB_ACTIONS) {
            "::error $(GetGoogleWorkflowPositionMesage),title=$(GetErrorTitle $InputObject)::$(GetErrorMessage $InputObject)"
        } elseif ($Env:TF_BUILD) {
            "##vso[task.logissue type=error;$(GetAzurePipelinesPositionMesage)]$(GetErrorTitle $InputObject): $(GetErrorMessage $InputObject)"
        }
    }
}
#EndRegion './public/ConvertTo-DetailedErrorView.ps1' 32
#Region './public/ConvertTo-FullErrorView.ps1' -1

filter ConvertTo-FullErrorView {
    <#
        .SYNOPSIS
            Converts an ErrorRecord to a full error view
        .DESCRIPTION
            A simple, verbose error view that just shows everything, recursing forever.
    #>

    [CmdletBinding()]
    param(
        # The ErrorRecord to display
        [Parameter(ValueFromPipeline)]
        [System.Management.Automation.ErrorRecord]
        $InputObject
    )
    $resetColor = ''
    $errorColor = ''
    #$accentColor = ''

    if ($Host.UI.SupportsVirtualTerminal -and ([string]::IsNullOrEmpty($env:__SuppressAnsiEscapeSequences))) {
        # For Format-List to use color when piped to Out-String, OutputRendering needs to be Ansi
        $PSStyle.OutputRendering, $Rendering = "Ansi", $PSStyle.OutputRendering

        $resetColor = "$([char]0x1b)[0m"
        $errorColor = if ($PSStyle.Formatting.Error) { $PSStyle.Formatting.Error } else { "`e[1;31m" }
    }

    $Detail = $InputObject | Format-List * -Force | Out-String -Width 120

    # NOTE: ErrorViewRecurse is normally false, and only set temporarily by Format-Error -Recurse
    if ($ErrorViewRecurse) {
        $Count = 1
        $Exception = $InputObject.Exception
        while ($Exception = $Exception.InnerException) {
            $Detail += $errorColor + "`nINNER EXCEPTION $($Count): $resetColor$($Exception.GetType().FullName)`n`n"
            $Detail += $Exception | Format-List * -Force | Out-String -Width 120
            $Count++
        }
    }
    if ($resetColor) {
        $PSStyle.OutputRendering = $Rendering
    }
    $Detail
}
#EndRegion './public/ConvertTo-FullErrorView.ps1' 44
#Region './public/ConvertTo-NormalErrorView.ps1' -1

filter ConvertTo-NormalErrorView {
    <#
        .SYNOPSIS
            Converts an ErrorRecord to a NormalView message string
        .DESCRIPTION
            The original default PowerShell ErrorView
    #>

    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline)]
        [System.Management.Automation.ErrorRecord]
        $InputObject
    )
    begin { ResetColor }
    process {
        if ($InputObject.FullyQualifiedErrorId -in 'NativeCommandErrorMessage','NativeCommandError') {
            "${errorColor}$($InputObject.Exception.Message)${resetColor}"
        } else {
            $myinv = $InputObject.InvocationInfo
            $posmsg = ''

            if ($myinv -and ($myinv.MyCommand -or ($InputObject.CategoryInfo.Category -ne 'ParserError')) -and $myinv.PositionMessage) {
                $posmsg = $newline + $myinv.PositionMessage
            }

            if ($err.PSMessageDetails) {
                $posmsg = ' : ' + $err.PSMessageDetails + $posmsg
            }

            $Wrap = @{
                Width = $host.UI.RawUI.BufferSize.Width - 2
                IndentPadding = " "
                FirstLineIndent = ""
            }

            $errorCategoryMsg = $InputObject.ErrorCategory_Message
            [string]$line = if ($null -ne $errorCategoryMsg) {
                $accentColor + "+ CategoryInfo : " + $errorColor + $InputObject.ErrorCategory_Message | WrapString @Wrap
            } else {
                $accentColor + "+ CategoryInfo : " + $errorColor + $InputObject.CategoryInfo | WrapString @Wrap
            }
            $posmsg += $newline + $line

            $line = $accentColor + "+ FullyQualifiedErrorId : " + $errorColor + $InputObject.FullyQualifiedErrorId | WrapString @Wrap
            $posmsg += $newline + $line

            $originInfo = $InputObject.OriginInfo
            if (($null -ne $originInfo) -and ($null -ne $originInfo.PSComputerName)) {
                $line = $accentColor + "+ PSComputerName : " + $errorColor + $originInfo.PSComputerName | WrapString @Wrap
                $posmsg += $newline + $line
            }

            if (!$InputObject.ErrorDetails -or !$InputObject.ErrorDetails.Message) {
                $errorColor + (GetErrorPrefix -InputObject $InputObject) + $InputObject.Exception.Message + $posmsg + $resetColor
            } else {
                $errorColor + (GetErrorPrefix -InputObject $InputObject) + $InputObject.ErrorDetails.Message + $posmsg + $resetColor
            }
        }
    }
}
#EndRegion './public/ConvertTo-NormalErrorView.ps1' 61
#Region './public/ConvertTo-NormalExceptionView.ps1' -1

filter ConvertTo-NormalExceptionView {
    <#
        .SYNOPSIS
            Converts an Exception to a NormalView message string
        .DESCRIPTION
            The original default PowerShell ErrorView, updated for VT100
    #>

    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline)]
        [System.Exception]
        $InputObject
    )
    begin { ResetColor }
    process {
        $errorColor + $InputObject.Message + $resetColor
    }
}
#EndRegion './public/ConvertTo-NormalExceptionView.ps1' 19
#Region './public/ConvertTo-SimpleErrorView.ps1' -1

function ConvertTo-SimpleErrorView {
    [CmdletBinding()]
    param(
        [System.Management.Automation.ErrorRecord]
        $InputObject
    )
    $resetColor = ''
    $errorColor = ''
    #$accentColor = ''

    if ($Host.UI.SupportsVirtualTerminal -and ([string]::IsNullOrEmpty($env:__SuppressAnsiEscapeSequences))) {
        $resetColor = "$([char]0x1b)[0m"
        $errorColor = if ($PSStyle.Formatting.Error) { $PSStyle.Formatting.Error } else { "`e[1;31m" }
        #$accentColor = if ($PSStyle.Formatting.ErrorAccent) { $PSStyle.Formatting.ErrorAccent } else { "`e[1;36m" }
    }

    if ($InputObject.FullyQualifiedErrorId -in 'NativeCommandErrorMessage','NativeCommandError') {
        $InputObject.Exception.Message
    } else {
        $myinv = $InputObject.InvocationInfo
        if ($myinv -and ($myinv.MyCommand -or ($InputObject.CategoryInfo.Category -ne 'ParserError'))) {
            # rip off lines that say "At line:1 char:1" (hopefully, in a language agnostic way)
            $posmsg = "`n" + $myinv.PositionMessage -replace "^At line:1 .*[\r\n]+"
        } else {
            $posmsg = ""
        }

        if ( & { Set-StrictMode -Version 1; $InputObject.PSMessageDetails } ) {
            $posmsg = " : " + $InputObject.PSMessageDetails + $posmsg
        }

        $indent = 4
        $width = $host.UI.RawUI.BufferSize.Width - $indent - 2

        $originInfo = & { Set-StrictMode -Version 1; $InputObject.OriginInfo }
        if (($null -ne $originInfo) -and ($null -ne $originInfo.PSComputerName)) {
            $indentString = "+ PSComputerName : " + $originInfo.PSComputerName
            $posmsg += "`n"
            foreach ($line in @($indentString -split "(.{$width})")) {
                if ($line) {
                    $posmsg += (" " * $indent + $line)
                }
            }
        }

        if (!$InputObject.ErrorDetails -or !$InputObject.ErrorDetails.Message) {
            $errorColor + $InputObject.Exception.Message + $posmsg + $resetColor + "`n "
        } else {
            $errorColor + $InputObject.ErrorDetails.Message + $posmsg + $resetColor
        }
    }
}
#EndRegion './public/ConvertTo-SimpleErrorView.ps1' 53
#Region './public/ConvertTo-YamlErrorView.ps1' -1

function ConvertTo-YamlErrorView {
    <#
        .SYNOPSIS
            Creates a description of an ErrorRecord that looks like valid Yaml
        .DESCRIPTION
            This produces valid Yaml output from ErrorRecord you pass to it, recursively.
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'maxDepth')]
    [CmdletBinding()]
    param(
        # The object that you want to convert to YAML
        [Parameter(Mandatory, ValueFromPipeline)]
        [System.Management.Automation.ErrorRecord]
        $InputObject,

        # The maximum depth to recurse into the object
        [int]$maxDepth = 10,

        # If set, include empty and null properties in the output
        [switch]$IncludeEmpty
    )
    begin { ResetColor }
    process {
        GetYamlRecursive -InputObject $InputObject -IncludeEmpty:$IncludeEmpty
    }
}
#EndRegion './public/ConvertTo-YamlErrorView.ps1' 27
#Region './public/Format-Error.ps1' -1

filter Format-Error {
    <#
        .SYNOPSIS
            Formats an error (or exception) for the screen using a specified error view
        .DESCRIPTION
            Temporarily switches the error view and outputs the errors
        .EXAMPLE
            Format-Error

            Shows the Detailed error view for the most recent error (changed to be compatible with Get-Error)
        .EXAMPLE
            $error[0..4] | Format-Error Full

            Shows the full error view (like using | Format-List * -Force) for the most recent 5 errors
        .EXAMPLE
            $error[3] | Format-Error Full -Recurse

            Shows the full error view of the specific error, recursing into the inner exceptions (if that's supported by the view)
    #>

    [CmdletBinding(DefaultParameterSetName = "Count")]
    [Alias("fe"<#, "Get-Error"#>)]
    [OutputType([System.Management.Automation.ErrorRecord])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'The ArgumentCompleter parameters are the required method signature')]

    param(
        # The name of the ErrorView you want to use (there must a matching ConvertTo-${View}ErrorView function)
        [Parameter(Position=0, ValueFromPipelineByPropertyName)]
        [ArgumentCompleter({
            param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
            [System.Management.Automation.CompletionResult[]]((
            Get-Command ConvertTo-*ErrorView -ListImported -ParameterName InputObject -ParameterType [System.Management.Automation.ErrorRecord], [System.Exception]
            ).Name -replace "ConvertTo-(.*)ErrorView",'$1' -like "*$($wordToComplete)*")
        })]
        $View = $global:ErrorView,

        [Parameter(ParameterSetName="Count")]
        [int]$Newest = 1,

        # Error records (e.g. from $Error). Defaults to the most recent error: $Error[0]
        [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName, ParameterSetName="InputObject", Mandatory)]
        [Alias("ErrorRecord")]
        [PSObject]$InputObject = $(
            if ($global:Error.Count -eq 0) {
                Write-Warning "The global `$Error collection is empty"
            } else {
                $global:Error[0..($Newest-1)]
            }
        ),

        # Encourages ErrorView functions to recurse InnerException properties
        [switch]$Recurse
    )
    Set-StrictMode -Off
    $ErrorActionPreference = 'Stop'
    trap { 'Error found in error view definition: ' + $_.Exception.Message }
    if ($InputObject.ErrorRecord) {
        $InputObject = $InputObject.ErrorRecord
    }

    $Views = @{
        ListImported = $true
        ErrorAction = "Ignore"
        ParameterName = "InputObject"
    }

    if ($InputObject -is [System.Management.Automation.ErrorRecord]) {
        if (($formatter = @(Get-Command "ConvertTo-$($View -replace "View$")ErrorView" @Views -ParameterType [System.Management.Automation.ErrorRecord]))) {
            . ($formatter[0]) -InputObject $InputObject
        } else {
            ConvertTo-NormalErrorView $InputObject
        }
    } else {
        if (($formatter = @(Get-Command "ConvertTo-$($View -replace "View$")ExceptionView" @Views -ParameterType [System.Exception]))) {
            . ($formatter[0]) -InputObject $InputObject
        } else {
            ConvertTo-NormalExceptionView $InputObject
        }
    }
}
#EndRegion './public/Format-Error.ps1' 80
#Region './public/Format-String.ps1' -1


filter Format-String {
    <#
        .SYNOPSIS
            Formats a string to fit within a certain width, with optional indentation and alternating colors
        .DESCRIPTION
            Wraps a string on word breaks to fit within a certain width.
            Preserves virtual terminal escape sequences, and supports indenting,
            including different indents for the first line and others.

            Ignores ANSI escape sequences when measuring the length,
            and handles wide characters (including treating emoji as 2 characters wide).
        .LINK
            Measure-String
    #>

    [Alias("WrapString")]
    [CmdletBinding()]
    param(
        # The input string will be wrapped to a certain length, with optional padding on the front
        [Parameter(ValueFromPipeline)]
        [string]$InputObject,

        # The maximum length of a line. Defaults to [Console]::BufferWidth - 1
        [Parameter(Position=0)]
        [int]$Width = ($Host.UI.RawUI.BufferSize.Width),

        # The padding for each line defaults to an empty string.
        # If set, whitespace on the front of each line is replaced with this string.
        [string]$IndentPadding = ([string]::Empty),

        # If set, this will be used only for the first line (defaults to IndentPadding)
        [string]$FirstLineIndent = $IndentPadding,

        # If set, wrapped lines use this instead of IndentPadding to create a hanging indent
        [Alias("HangingIndent")]
        [string]$WrappedIndent  = $IndentPadding,


        # If set, colors to use for alternating lines
        [string[]]$Colors = @(''),

        # If set, will output empty lines for each original new line
        [switch]$EmphasizeOriginalNewlines
    )
    begin {
        $FirstLine = $true
        $color = 0;
        Write-Debug "Colors: $($Colors -replace "`e(.+)", "`e`$1``e`$1")"
        $output = [System.Text.StringBuilder]::new()
        $buffer = [System.Text.StringBuilder]::new()
        $lineLength = 0
        if ($Width -lt $IndentPadding.Length) {
            Write-Warning "Width $Width is less than IndentPadding length $($IndentPadding.Length). Setting Width to BufferWidth ($($Host.UI.RawUI.BufferSize.Width))"
        }
    }
    process {
        $output = [System.Text.StringBuilder]::new()
        foreach($line in $InputObject -split "(\r?\n)") {
            if ($FirstLine -and $PSBoundParameters.ContainsKey('FirstLineIndent')) {
                $IndentPadding, $FirstLineIndent = $FirstLineIndent, $IndentPadding
            }
            # Don't bother trying to split empty lines
            if ([String]::IsNullOrWhiteSpace($AnsiRegex.Replace($line, ''))) {
                Write-Debug "Empty String ($($line.Length))"
                if ($EmphasizeOriginalNewlines) {
                    $null = $output.Append($newline)
                }
                continue
            }

            $slices = $line -split $WordBoundaryRegex | Where-Object { $_.Length } | ForEach-Object { @{ Text = $_; Length = Measure-String $_ -EmojiAsWide } }
            Write-Debug "$($line.Length) characters in line in $($slices.Count) words. $($AnsiRegex.Replace($line, ''))"
            $lineLength = $IndentPadding.Length
            foreach($slice in $slices) {
                $lineLength = $lineLength + $slice.Length
                Write-Verbose "+ $($slice.Length) = $lineLength <= $Width '$($slice.Text -replace "`e","``e")'"
                if ($lineLength -le $Width) {
                    if ($lineLength -eq $slice.Length -and [string]::IsNullOrWhitespace($slice.Text)) {
                        Write-Debug "Skip whitespace '$($slice.Text)'"
                        $lineLength = $lineLength - $slice.Length
                        continue
                    }
                    $null = $buffer.Append($slice.Text)
                } elseif ($slice.Length -gt $Width) {
                    Write-Debug "Slice too long $($slice.Length) > $Width"
                    $needLength = $Width - ($lineLength - $slice.Length)

                    $remains = $slice
                    # If the slice is too long for a line, it's going to wrap anyway, so do it ourselves
                    while($remains.Length -gt $needLength) {
                        $next, $remains = $remains.Text -split "((?:(?:$AnsiPattern)*.(?:$AnsiPattern)*){1,$needLength})", 2 | Where-Object { $_.Length } | ForEach-Object { @{ Text = $_; Length = Measure-String $_ -EmojiAsWide } }
                        $null = $buffer.Append($next.Text).Append($newline).Append($WrappedIndent)
                        $lineLength = $WrappedIndent.Length
                        $needLength = $Width - $lineLength
                    }

                    # Don't start a line with whitespace
                    if (![string]::IsNullOrWhitespace($remains.Text)) {
                        Write-Debug "Output $($lineLength) not whitespace '$($remains.Text)'"
                        $null = $buffer.Append($remains.Text)
                        $lineLength = $lineLength + $remains.Length
                    }

                } else {
                    Write-Verbose "Output $($lineLength - $slice.Length)"
                    $null = $buffer.Append($newline).Append($WrappedIndent)
                    $lineLength = $WrappedIndent.Length
                    # Don't start a line with whitespace
                    if (![string]::IsNullOrWhitespace($slice.Text)) {
                        Write-Debug "Output $($lineLength) not whitespace '$($slice.Text)'"
                        $null = $buffer.Append($slice.Text)
                        $lineLength = $WrappedIndent.Length + $slice.Length
                    }
                }
            }
            if (!$FirstLine) {
                $null = $output.Append($newline)
            }
            if ($PSBoundParameters.ContainsKey("IndentPadding")) {
                $null = $output.Append($Colors[$color] + $IndentPadding + (<# TrimAnsi #> $buffer.ToString().TrimStart()))
            } else {
                $null = $output.Append($Colors[$color] + (<# TrimAnsi #> $buffer.ToString()))
            }
            $color = ($color + 1) % $Colors.Length
            $null = $buffer.Clear() #.Append($Colors[$color]).Append($IndentPadding)
            $lineLength = $IndentPadding.Length
            $FirstLine = $false
            $IndentPadding = $FirstLineIndent
        }
        $output.ToString() -replace "\s(?=$newline)" # trim trailing whitespace from each line
    }
}
#EndRegion './public/Format-String.ps1' 133
#Region './public/Measure-String.ps1' -1


# https://github.com/sindresorhus/string-width

# import stripAnsi from 'strip-ansi';
# import {eastAsianWidth} from 'get-east-asian-width';
# import emojiRegex from 'emoji-regex';

# const segmenter = new Intl.Segmenter();

# const defaultIgnorableCodePointRegex = /^\p{Default_Ignorable_Code_Point}$/u;

filter Measure-String {
    <#
        .SYNOPSIS
            Measures the length of a string with support for escape sequences and wide characters
        .DESCRIPTION
            By default, ignores ANSI escape sequences when measuring the length
            Optionally can treat ambiguous characters as wide
            Optionally can treat emoji characters wide
        .LINK
            Measure-String
    #>

    param(
        [ValidateNotNull()]
        [Parameter(ValueFromPipeline)]
        [string]$string,

        [switch]$AmbiguousAsWide,

        [switch]$EmojiAsWide,

        [switch]$countAnsiEscapeCodes
    )
    if ($string.length -eq 0) {
        return 0;
    }

    if (!$countAnsiEscapeCodes) {
        $string = $string -replace $AnsiRegex
    }

    if ($string.length -eq 0) {
        return 0;
    }

    # PowerShell 5 (.NET 4) isn't UAX 29 compliant
    $width = 0;
    foreach ($character in $string.GetEnumerator()) {
        $codePoint = [int]$character;

        # Ignore control characters
        if ($codePoint -le 0x1F -or ($codePoint -ge 0x7F -and $codePoint -le 0x9F)) {
            continue
        }

        # Ignore zero-width characters
        if (($codePoint -ge 0x200B -and $codePoint -le 0x200F) -or # Zero-width space, non-joiner, joiner, left-to-right mark, right-to-left mark
            $codePoint -eq 0xFEFF ) {
            # Zero-width no-break space# Zero-width no-break space
            continue
        }

        # Ignore combining characters
        if (($codePoint -ge 0x300 -and $codePoint -le 0x36F) -or # Combining diacritical marks
            ($codePoint -ge 0x1AB0 -and $codePoint -le 0x1AFF) -or # Combining diacritical marks extended
            ($codePoint -ge 0x1DC0 -and $codePoint -le 0x1DFF) -or # Combining diacritical marks supplement
            ($codePoint -ge 0x20D0 -and $codePoint -le 0x20FF) -or # Combining diacritical marks for symbols
            ($codePoint -ge 0xFE20 -and $codePoint -le 0xFE2F)) {
            # Combining half marks
            continue
        }

        # Ignore surrogate pairs
        if ($codePoint -ge 0xD800 -and $codePoint -le 0xDFFF) {
            continue
        }

        # Ignore variation selectors
        if ($codePoint -ge 0xFE00 -and $codePoint -le 0xFE0F) {
            continue
        }

        # This covers some of the above cases, but we still keep them for performance reasons.
        if ([Char]::GetUnicodeCategory($character) -in 'NonSpacingMark', 'SpacingCombiningMark', 'EnclosingMark', 'Format') {
            continue
        }

        if ($character -match $EmojiRegex) {
            if ($EmojiAsWide) {
                $width += 2 # Treat emojis as double width
            } else {
                $width += 1 # Treat emojis as single width
            }
            continue
        }

        $width += Measure-EastAsianWidth $codePoint -AmbiguousAsWide:$AmbiguousAsWide
    }

    return $width;
}
#EndRegion './public/Measure-String.ps1' 102
#Region './public/Set-ErrorView.ps1' -1

filter Set-ErrorView {
    <#
        .SYNOPSIS
            A helper function to provide tab-completion for error view names
    #>

    [CmdletBinding()]
    [Alias("sev")]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification='The ArgumentCompleter parameters are the required method signature')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidGlobalVars', '', Justification = 'ErrorView is all about the ErrorView global variable')]
    [OutputType([System.Management.Automation.ErrorRecord])]
    param(
        # The name of the ErrorView you want to use (there must a matching ConvertTo-${View}ErrorView function)
        [Parameter(Position = 0, ValueFromPipelineByPropertyName)]
        [ArgumentCompleter({
                param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
                [System.Management.Automation.CompletionResult[]]((
                        Get-Command ConvertTo-*ErrorView -ListImported -ParameterName InputObject -ParameterType [System.Management.Automation.ErrorRecord]
                    ).Name -replace "ConvertTo-(.*)ErrorView", '$1' -like "*$($wordToComplete)*")
            })]
        $View = "Normal"
    )

    # Re-create an update the enum every time, because how often do you change the error view?
    $Names = [System.Management.Automation.ErrorView].GetEnumNames() + @(
        Get-Command ConvertTo-*ErrorView -ListImported -ParameterName InputObject -ParameterType [System.Management.Automation.ErrorRecord]
    ).Name -replace "ConvertTo-(\w+)ErrorView", '$1View' | Select-Object -Unique

    $ofs = ';'
    . ([ScriptBlock]::Create("enum ErrorView { $Names }"))

    [ErrorView]$global:ErrorView = $View
}
#EndRegion './public/Set-ErrorView.ps1' 35
#Region './postfix.ps1' -1

if ($ErrorViewArgument) {
    Set-ErrorView $ErrorViewArgument
} elseif ($Env:GITHUB_ACTIONS -or $Env:TF_BUILD) {
    Set-ErrorView "DetailedErrorView"
} else {
    Set-ErrorView "ConciseView"
}
#EndRegion './postfix.ps1' 8