Zerowidth CleanerAll measured guides

CLAUDE WATERMARK REMOVER · PRACTICAL TEST

Why does lastIndexOf miss a cleaned match when position is zero?

In our repeated-word control, lastIndexOf("AB") returns 3, while position zero returns 0. In the marked fixture, cleanup creates a match at 3 that position zero still excludes. The argument limits where backward search begins.

Tested October 23, 2026 · v24.19.0 · 4 measured runs

Open the Claude text cleaner · Full measured data

Code-point comparison for Marked last occurrence

Measured inputs and outputs

These are locally constructed test strings, not evidence that Claude inserts these characters. We executed the saved homepage script snapshot with a minimal DOM harness and compared exact strings. The invisible-checkbox state and dash mode appear in each row. The observations below test this page's specific question. Destination observations run independently on the exact input and cleaned strings in the recorded Node runtime. We make no detector-score or statistical-watermark removal claim.

Before and after observations; full code points and strings are in the JSON download.
Fixture and modeInput string and code pointsOutput and cleaner statusObserved before / after
Marked last occurrence
direct string / keep / invisible true
"A BA​B"
U+0041 U+0020 U+0042 U+0041 U+200B U+0042
"A BAB"
Removed 1 invisible character
{"defaultPosition":-1,"fromZero":-1,"fromTwo":-1,"fromNegative":-1}
{"defaultPosition":3,"fromZero":-1,"fromTwo":-1,"fromNegative":-1}
Plain repeated word
direct string / keep / invisible true
"AB AB"
U+0041 U+0042 U+0020 U+0041 U+0042
"AB AB"
No selected invisible characters found
{"defaultPosition":3,"fromZero":0,"fromTwo":0,"fromNegative":0}
{"defaultPosition":3,"fromZero":0,"fromTwo":0,"fromNegative":0}
One occurrence
direct string / keep / invisible true
"AB"
U+0041 U+0042
"AB"
No selected invisible characters found
{"defaultPosition":0,"fromZero":0,"fromTwo":0,"fromNegative":0}
{"defaultPosition":0,"fromZero":0,"fromTwo":0,"fromNegative":0}
Absent target
direct string / keep / invisible true
"CD"
U+0043 U+0044
"CD"
No selected invisible characters found
{"defaultPosition":-1,"fromZero":-1,"fromTwo":-1,"fromNegative":-1}
{"defaultPosition":-1,"fromZero":-1,"fromTwo":-1,"fromNegative":-1}

The new match lies outside the chosen start

The first source contains A, a space, B, A, a selected marker and B. Before deletion it has no contiguous AB. After deletion its exact spelling is A BAB and the final AB starts at index three. Our default lastIndexOf call returns three; the calls starting at zero, two and negative one all return minus one. Those results coexist on the same cleaned string, demonstrating that a negative result can come from the caller restricting the search. The cleaner successfully repaired adjacency and did not select the starting position used by the observer.

Repeated text distinguishes a cursor from a match count

The plain AB AB control reports three by default and zero with each explicit start in this matrix. A negative start does not mean count backward from the end here: our negative-one call still finds the initial occurrence. The single AB reference gives zero in every branch, so that small control alone would conceal the distinction. CD supplies the absent-target result of minus one throughout. Together the four strings separate search range, duplicate occurrences and true absence without relying on a visual screenshot of hidden characters or a word-count estimate.

Keep the search contract beside the returned index

Record the exact cleaned string, needle and position when a backward search appears to lose text. Decide whether your destination needs the last occurrence in the whole string or the last occurrence starting no later than a specified index. This experiment uses a fixed two-letter needle and JavaScript code-unit indices; it does not define grapheme offsets, editor selections or another language search API. Every result is a local Node observation. The synthetic strings are not Claude samples, and matching the letters after cleanup does not identify an author, detect a watermark or establish anything about a classifier.

Reproduce this test

Save reproduce.cjs and tested-app.js in the same folder. Run the command below with Node.js. The harness prints its runtime, script SHA-256 and every measured row. Compare those rows with the original record. Using a newer script or runtime creates a new experiment; retain the version information with your rerun.

node reproduce.cjs

Reference and next check

ECMAScript String.prototype.lastIndexOf provides the relevant primary definition. The table and fixture analysis are original measurements. For broader inspection, use our Unicode inspector. Read the scope distinction before interpreting cleanup as a watermark result.