FPF5NAZAGWBPY3QJBMUSOI27OZUJIAWISNDCCIIXGRJH7X7AKUFAC RENZHUTVG7GX4GR4NBYUTRU66PKF4FWTZHX6FVUK5RTCYP356R7AC J6JU7YCTREG6VFRUVHXYCN2O5IIO66BXFPN25HGTRMSDCMIDBS3QC 2FYBDR6GR6TE4GVP6IGBATBP3LC6WR2TVHNNXAMB2QNXY3TC2YNAC VC3YS42DKQ5PVDV3YJEBWIMOUN6DVZK3C2WOJMCM5SDIH4WNJMDQC 6KTVGEGU4CQFGRKKQC2N6Q46TUEWEK5GVQYKQY5JINDCAIBUP2UAC B4USRORMW7EQXOV4TOHRCMMWUURWAMJRDITEKA3YAV2SFUIFBXLQC F4RUTONDM6GET6RT6ZBJKHJWJZWHJLCI2NM5ZMOFJGWAOEUCBDQQC DSLD74DK3P6J2VAFCYF5BGTHZ637QTW3PDHOUHFACDZU66YNM3IAC GLYCXWBJBU7DOX5IYFZHT3ITXLLVKN5QK7W3QNHKW2EKRMFIUYLAC LXTTOB33N2HCUZFIUDRQGGBVHK2HODRG4NBLH6RXRQZDCHF27BSAC HTWAM4NZFOY463TNSKYIM2EWB7QNBGDRRTTGHF5N3Z4TGC7Q3SFAC NZKYPBSKYJ7NQU7ABRHLYZ2P2P5V2UF76OLRURGTGRUB54R4SPBQC 4PWZSWW46E3PVL2LIO7PZLAJVIOJ4CY5HZ5VHUWLBZPEKTGZHN4AC BULPIBEGL7TMK6CVIE7IS7WGAHGOSUJBGJSFQK542MOWGHP2ADQQC PLKNHYZ4KXWWKC2DHXCI4WVO23I7VMEVYT5H2J6JDE4S3D3CHDJQC RLCO2SNKO5OJBEQFRXTB7TCAES6KML4IBOCW5SA7Q24RALW6JCWQC T42Y5MLOV7WMURTBEZTUVMYEVG72UMN6BPG2QHOYW7G2CC75ZNGQC -- create a new iterator for s which provides the index and UTF-8 bytes corresponding to each codepointfunction utf8chars(s, startpos)local next_pos = startpos or 1 -- in code pointslocal next_offset = utf8.offset(s, next_pos) -- in bytesreturn function()assert(next_offset) -- never call the iterator after it returns nillocal curr_pos = next_posnext_pos = next_pos+1local curr_offset = next_offsetnext_offset = utf8.offset(s, 2, next_offset)if next_offset == nil then return endlocal curr_char = s:sub(curr_offset, next_offset-1)return curr_pos, curr_charendend