g | x | w | all
Bytes Lang Time Link
441Uiua240721T100812ZEurope20
668JavaScript ES6131018T120523ZDom Hast
675Tcl131004T183445ZJohannes
183Tcl131004T123311ZJohannes

Uiua, 441

utf₈≡(⊡:⊂"\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼"⊂+@ ⇡95"⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσμτΦΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ")

The reason why this is so long is because I don't think there's any other shorter way to build this specific string.

JavaScript (ES6), 668 bytes

console.log(prompt()[p='replace'](/[\S\s]/g,s=>String.fromCharCode(...(z=`BjuBjvBl1Bl2BkzBkwAciBh4BgrBh5Bk2Bk0Bl6Bl7BjwBgaBgkAmtAd8D2CnBfwAncAmpAmrAmqAmoAqnAmsBg2Bgc${','.repeat(96)}DjB0AhAaAcA8AdAfAiAjAgAnAmAkDgDhDlAeDiAsAuAqAzAxB3DyA4CiCjClAg7,b6A9AlArAyApDtCqD6DbAxcCsD9D8ChCrD7Bf5Bf6Bf7Bb6Bc4GtGuGiGhGvGdGjGpGoGnBbkBboBckBccBbwBb4BcsGqGrGmGgBe1GyGsGcBe4GzBe0GwGxGlGkGeGfBe3Be2BbsBbgBewBesBf0Bf4BeoE9A7FfEoFvErD1EsFyFkE1EcAqmEuEdAqxAshCxAslAskAxsAxtAvArsCwAqhD3AqiAf3CyBfkCg`[p](/G/g,'Bd')[p](/[A-F]/g,s=>','+'745qp6'[s[o='charCodeAt']()%6]).split`,`.map(i=>parseInt(i,36))[s=s[o]()]||s)<(x=128)?[z]:z<2048?[0|192+z/64,x+z%64]:[0|224+z/4096,0|x+z%4096/64,x+z%64])))

prompt()s for input and console.log()s the result. Tested in Firefox, utilises ES6 features of arrow functions, template strings and the spread operator (...). The bulk of the data here is the string which is a comma separated list of base36 numbers that equate to the UTF-8 code points of the characters to update (1-31, 127-255) and pads the other points with empty space/NaNs. The code iterates around each char in the source string, replacing it if necessary. I'm sure it should be possible to shave off more bytes, but I'm done for now! Here's a function for easier testing:

c=t=>t[p='replace'](/[\S\s]/g,s=>String.fromCharCode(...(z=(`BjuBjvBl1Bl2BkzBkwAciBh4BgrBh5Bk2Bk0Bl6Bl7BjwBgaBgkAmtAd8D2CnBfwAncAmpAmrAmqAmoAqnAmsBg2Bgc${','.repeat(96)}DjB0AhAaAcA8AdAfAiAjAgAnAmAkDgDhDlAeDiAsAuAqAzAxB3DyA4CiCjClAg7,b6A9AlArAyApDtCqD6DbAxcCsD9D8ChCrD7Bf5Bf6Bf7Bb6Bc4GtGuGiGhGvGdGjGpGoGnBbkBboBckBccBbwBb4BcsGqGrGmGgBe1GyGsGcBe4GzBe0GwGxGlGkGeGfBe3Be2BbsBbgBewBesBf0Bf4BeoE9A7FfEoFvErD1EsFyFkE1EcAqmEuEdAqxAshCxAslAskAxsAxtAvArsCwAqhD3AqiAf3CyBfkCg`[p](/G/g,'Bd')[p](/[A-F]/g,s=>','+'745qp6'[s[o='charCodeAt']()%6])).split`,`.map(i=>parseInt(i,36))[s=s[o]()]||s)<(x=128)?[z]:z<2048?[0|192+z/64,x+z%64]:[0|224+z/4096,0|x+z%4096/64,x+z%64]))

Run the above and call c() to extract data:

c('\x0d').split('').map(s=>`\\x${s.charCodeAt(0).toString(16)}`).join``
"\xe2\x99\xaa"

JavaScript (ES6), 618 bytes

There is a method in JavaScript for easily converting to source bytes for Unicode chars (that was shared to me by Mathias Bynens on a conversion tool I'd written!) that involves URL encoding and decoding the string which saves bytes, but I feel isn't in the spirit of the original challenge:

console.log(unescape(encodeURIComponent(prompt()[p='replace'](/[\S\s]/g,s=>String.fromCharCode((`BjuBjvBl1Bl2BkzBkwAciBh4BgrBh5Bk2Bk0Bl6Bl7BjwBgaBgkAmtAd8D2CnBfwAncAmpAmrAmqAmoAqnAmsBg2Bgc${','.repeat(96)}DjB0AhAaAcA8AdAfAiAjAgAnAmAkDgDhDlAeDiAsAuAqAzAxB3DyA4CiCjClAg7,b6A9AlArAyApDtCqD6DbAxcCsD9D8ChCrD7Bf5Bf6Bf7Bb6Bc4GtGuGiGhGvGdGjGpGoGnBbkBboBckBccBbwBb4BcsGqGrGmGgBe1GyGsGcBe4GzBe0GwGxGlGkGeGfBe3Be2BbsBbgBewBesBf0Bf4BeoE9A7FfEoFvErD1EsFyFkE1EcAqmEuEdAqxAshCxAslAskAxsAxtAvArsCwAqhD3AqiAf3CyBfkCg`[p](/G/g,'Bd')[p](/[A-F]/g,s=>','+'745qp6'[s[o='charCodeAt']()%6])).split`,`.map(i=>parseInt(i,36))[s=s[o]()]||s)))))

and as a function:

c=t=>unescape(encodeURIComponent(t[p='replace'](/[\S\s]/g,s=>String.fromCharCode(z=(`BjuBjvBl1Bl2BkzBkwAciBh4BgrBh5Bk2Bk0Bl6Bl7BjwBgaBgkAmtAd8D2CnBfwAncAmpAmrAmqAmoAqnAmsBg2Bgc${','.repeat(96)}DjB0AhAaAcA8AdAfAiAjAgAnAmAkDgDhDlAeDiAsAuAqAzAxB3DyA4CiCjClAg7,b6A9AlArAyApDtCqD6DbAxcCsD9D8ChCrD7Bf5Bf6Bf7Bb6Bc4GtGuGiGhGvGdGjGpGoGnBbkBboBckBccBbwBb4BcsGqGrGmGgBe1GyGsGcBe4GzBe0GwGxGlGkGeGfBe3Be2BbsBbgBewBesBf0Bf4BeoE9A7FfEoFvErD1EsFyFkE1EcAqmEuEdAqxAshCxAslAskAxsAxtAvArsCwAqhD3AqiAf3CyBfkCg`[p](/G/g,'Bd')[p](/[A-F]/g,s=>','+'745qp6'[s[o='charCodeAt']()%6])).split`,`.map(i=>parseInt(i,36))[s=s[o]()]||s))))

Tcl, 675

eval [zlib i Ò×sgÆáB\nPÃïÿòpÁ\f0\fv®4\fBc!j¶%cluYbãdÃw¨)+½MB()zàõÍóÝ=\{vÏì®ÿ¢­Ö¶\rk×­áóUë\tÌÀOÖ)'*ð,ò¦Ì1\[¦y\v?e~oÀÛ\;¼3)ï*S!ïMgÀÜé¬0OVy_sÌÇ侀@ýa>ÀoïæCMl°7ÎG¸«£Æ'º6Ä\"e±³DÆX*#,Ãïd¹êª²Á&ü®Al±!¬Ì,K˳KÓØèÀ*tbU¶cCìÀöÓíc'VcæKl+¬(V\$µÇFI`ãtc#ô`ôbHbS¤°ú°~vã²ôãrìÁÀäD4!í%\$ÕÉcð(E\\®În²vPÁÕ¨âSÃ5ØË°We?nÚ>ʰ1\"ãÄOyÆð»3Ë,²¯d7dº2)\{iÈ=ý|-w3¥\tÈGå(NÖ0ÙÏ1ä¸lpBý\}\t¾e¾E¾i¾<Y£)KCy~ÎÉçe\v2ÆEç¬rYV¸¢ç&¹*»¸¦­\;¸.ÃÜ\]ÜnÉ\ ·ñùÄÇóÍ\ ?ãåøæîàÆøf»xEîá%¹WæÞ(¿é_àwíü7Æ:.ó¿3Ã_¸a©,ð·Ìó>Veÿ°\tëtOpxªS<ÃMð\\e/ð7Oñ7ÂÿzÍ4¯pé´lølÕjZÛV¯\]·råk]

Just a simple mapping between input and output. Decompressed it looks like

puts [string map { ⺠ â»  ⥠ ⦠ ⣠ â   ⢠ â {  } â {
} â {} â {} â {
} ⪠ â«  â¼  ⺠ â  â  â¼  ¶  §  ⬠ ⨠ â  â  â  â  â  â  â²  â¼  â  Ã  ü  é  â  ä  à  Ã¥  ç  ê  ë  è  ï  î  ì  à  à  à  æ  à  ô  ö  ò  û  ù  ÿ  à  à  ¢  £  Â¥  â§  Æ   á ¡ í ¢ ó £ ú ¤ ñ ¥ à ¦ ª § º ¨ ¿ © â ª ¬ « ½ ¬ ¼ ­ ¡ ® « ¯ » ° â ± â ² â ³ â ´ ⤠µ â¡ ¶ ⢠· â ¸ â ¹ ⣠º â » â ¼ â ½ â ¾ â ¿ â À â Á ⴠ ⬠à â Ä â Å â¼ Æ â Ç â È â É â Ê â© Ë â¦ Ì â  Í â Î â¬ Ï â§ Ð â¨ Ñ â¤ Ò â¥ Ó â Ô â Õ â Ö â × â« Ø âª Ù â Ú â Û â Ü â Ý â Þ â ß â à α á à â Î ã Ï ä Σ å Ï æ µ ç Ï è Φ é Î ê Ω ë δ ì â í Ï î ε ï â© ð â¡ ñ ± ò ⥠ó ⤠ô â  õ â¡ ö ÷ ÷ â ø ° ù â ú · û â ü â¿ ý ² þ â  ÿ  } [read stdin]]

Tcl, 183

chan con stdin -en cp437
chan con stdout -en utf-8
puts [string map [concat {*}[lmap c [split {☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼} {}] {list [format %c [incr i]] $c}]  ⌂] [read stdin]]

You probably have to setup the input/output in your shell to binary, so it does not mangle the input/output.