NSDataDetector and android.util.Patterns occasionally drag invisible
chars inside a URL when the source text uses them as soft separators —
tab / LF / CR / NBSP / zero-width markers / BOM / word joiner. The OS
URL parser then refuses the result and the tap silently fails.
`_sanitizeUrl` strips that fixed set on the Dart side as matches come
out of `_decode`, so the persisted V17 spans only carry openable bytes.
Bidi controls (U+202A..E, U+2066..9) are left in — they're a spoofing
primitive, not noise, and `_isLaunchable` rejects them outright. LRM /
RLM (U+200E/F) are added to the same launch reject set so a legacy
persisted URL that escaped the strip can't reach the OS handler.