+'Chappe semaphore' => [
+ map {
+ my ($r, $pr, $pl) = split //, $_;
+ !$_ ? '-' : sprintf(
+ join('',
+ '<svg width="20" height="20" viewBox="0 0 10 15">',
+ '<path d="M5,6 v7"/>',
+ '<path d="M0,%s h10 %s" transform="rotate(%d 5 6)"/>',
+ '</svg>',
+ ),
+ ['6', '3v3', '9v-3']->[$pl],
+ [ '', 'v3', 'v-3']->[$pr],
+ $r * 45,
+ );
+ }
+ # 360° rotation (0-7) and position state (0-2) of left and right bars
+ qw(
+ 021 121 221 321 421 521 621 721
+ 022 022 122 222 322 011 111 211 311
+ 001 101 201 301 401 501 601 701 020
+ )
+],
+'Prussian semaphore' => [
+ map { !$_ ? '-' : sprintf
+ join('',
+ '<svg width="20" height="20" viewBox="0 0 8 18">',
+ '<path d="M4,1 v18"/>',
+ (map {(
+ qq(<path d="M0 $_ h4" transform="rotate(%d 4 $_)"/>),
+ qq(<path d="M4 $_ h4" transform="rotate(-%d 4 $_)"/>),
+ )} 3, 7, 14),
+ '</svg>',
+ ),
+ map { ($_ - 2) * 45 % 360 } split //, $_
+ }
+ # rotation state (0-3) for left and right bar of 3 rows
+ qw(
+ 003000 000200 203300 000030 033030 000130 000330 032330 031330 031330
+ 022020 130120 001320 233010 030210 022310 203001 233001
+ 131001 231301 000202 023302 230003 032003 201003 101003
+ )
+],
+'Code 39' => [
+ # ISO/IEC 16388
+ map { tr/012/ ❘❙/r } qw(
+ 211012 121012 221011 112012 212011 122011 111022 211021 121021 112021
+ 211102 121102 221101 112102 212101 122101 111202 211201 121201 112201
+ 201112 102112 202111 101212 201211 102211
+ )
+],
+'Code 128' => [
+ map { tr/1-3-/❘❙❚ /r }
+ # bar widths (1-3) followed by space of width 1 (implied) or 3 (-)
+ qw(
+ 11-2 1-12 1-1-2 12-1 1-21 1-2-1 21-1 2-11 2-1-1 123 12-3 1-23 132
+ 13-2 1-32 332 21-3 2-13 231 23-1 233 312 31-2 3-12 321 32-1
+ )
+],
+'<abbr title="Royal Mail 4-State Customer Code">RM4SCC</abbr>' => [