+$L ($L | $V | $LV | $LVT);
+($LV | $V) ($V | $T);
+($LVT | $T) $T;
+
+$RI $RI $Extend* / $RI;
+$RI $RI $Extend*;
+
+[^$Control $CR $LF] $Extend;
+
+[^$Control $CR $LF] $SpacingMark;
+# TODO: Restore if the Prepend set becomes non-empty again: $Prepend [^$Control $CR $LF];
+
+# Special forward rules for people & body part emoji:
+# don't break $ZWJ from subsequent $EmojiForSeqs; don't break between relevant emoji and $EmojiMods
+$ZWJ $EmojiForSeqs;
+$EmojiForMods $EmojiVar? $EmojiMods;
+
+
+## -------------------------------------------------
+
+!!reverse;
+$LF $CR;
+($L | $V | $LV | $LVT) $L;
+($V | $T) ($LV | $V);
+$T ($LVT | $T);
+
+$Extend* $RI $RI / $Extend* $RI $RI;
+$Extend* $RI $RI;
+
+$Extend [^$Control $CR $LF];
+$SpacingMark [^$Control $CR $LF];
+# TODO: Restore if the Prepend set becomes non-empty again: [^$Control $CR $LF] $Prepend;
+
+# Special reverse rules for people & body part emoji:
+# don't break $ZWJ from subsequent $EmojiForSeqs; don't break between relevant emoji and $EmojiMods
+$EmojiForSeqs $ZWJ;
+$EmojiMods $EmojiVar? $EmojiForMods;
+
+## -------------------------------------------------
+# We don't logically need safe char break rules, but if we don't provide any at all
+# the engine for preceding() and following() will fall back to the
+# old style inefficient algorithm.
+
+!!safe_reverse;
+$LF $CR;
+$RI $RI+;
+[$EmojiVar $EmojiMods]+ $EmojiForMods;
+
+## -------------------------------------------------
+
+!!safe_forward;
+$CR $LF;
+$RI $RI+;
+$EmojiForMods [$EmojiVar $EmojiMods]+;