On Friday, January 31, 2014 1:54:30 PM UTC-6, Daniel "paradigm" Thau wrote: > On Thursday, January 30, 2014 9:07:19 PM UTC-5, Daniel "paradigm" Thau wrote: > > On Thursday, January 30, 2014 8:07:04 PM UTC-5, Marcin Szamotulski wrote: > > > On 16:45 Wed 29 Jan , Daniel "paradigm" Thau wrote: > > > > > > > Apologies for the delay. > > > > > > > > > > > > > > Review for those who have forgotten and/or don't care to backread: > > > > > > > > > > > > > > This patch adds a new text object, "m", which will take one more > > > > character as input. That character will be used as bounds to the left > > > > and right for the object. For example, "cim$" will change between > > > > dollar signs. This supports multi-line objects, so one could do "cim'" > > > > which, unlike "ci'", will search across lines; this way users have both. > > > > > > > > > > Thanks I'm really happy to see this patch. I compiled it now and there > > > > > > is one thing that does not work: the "." command. For example di< or ci< > > > > > > can be repeated with . but dim, or cim, cannot. > > > > > > > > > > > > Best regards, > > > > > > Marcin Szamotulski > > > > Good catch. I can replicate that on my end. Will fix. > > Should be fixed in the attachment. As a bonus, it now supports things such > as digraphs.
I tried updating this patch for 7-4-220 and mostly succeeded, just by applying a couple hundred lines of fuzz, but visual mode is not selecting the full text inside the matched pairs. I don't have time to try to fix it further. I'm attaching the updated patch in case I just did something wrong. I know there have been some visual mode changes outside of this patch between now and the time the patch was created. -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
diff -ur vim-7-4-220/runtime/doc/motion.txt vim-7-4-220_patched/runtime/doc/motion.txt --- vim-7-4-220/runtime/doc/motion.txt Thu Mar 27 06:40:30 2014 +++ vim-7-4-220_patched/runtime/doc/motion.txt Thu Mar 27 11:27:22 2014 @@ -662,6 +662,14 @@ Special case: With a count of 2 the quotes are included, but no extra white space as with a"/a'/a`. +am{char} *v_am* *am* + "a matched {char}". Selects the text from the + previous {char} until the next {char}. A count is + currently not used. + +im{char} *v_im* *im* + Like am{char} but exclude the {char}. + When used after an operator: For non-block objects: For the "a" commands: The operator applies to the object and the white diff -ur vim-7-4-220/runtime/doc/tags vim-7-4-220_patched/runtime/doc/tags --- vim-7-4-220/runtime/doc/tags Thu Mar 27 06:40:30 2014 +++ vim-7-4-220_patched/runtime/doc/tags Thu Mar 27 11:27:22 2014 @@ -4763,6 +4763,7 @@ alt intro.txt /*alt* alt-input debugger.txt /*alt-input* alternate-file editing.txt /*alternate-file* +am motion.txt /*am* amiga-window starting.txt /*amiga-window* and() eval.txt /*and()* anonymous-function eval.txt /*anonymous-function* @@ -6538,6 +6539,7 @@ if_sniff.txt if_sniff.txt /*if_sniff.txt* if_tcl.txt if_tcl.txt /*if_tcl.txt* ignore-errors eval.txt /*ignore-errors* +im motion.txt /*im* improved-autocmds-5.4 version5.txt /*improved-autocmds-5.4* improved-quickfix version5.txt /*improved-quickfix* improved-sessions version5.txt /*improved-sessions* @@ -8473,6 +8475,7 @@ v_a] motion.txt /*v_a]* v_a` motion.txt /*v_a`* v_ab motion.txt /*v_ab* +v_am motion.txt /*v_am* v_ap motion.txt /*v_ap* v_aquote motion.txt /*v_aquote* v_as motion.txt /*v_as* @@ -8520,6 +8523,7 @@ v_i] motion.txt /*v_i]* v_i` motion.txt /*v_i`* v_ib motion.txt /*v_ib* +v_im motion.txt /*v_im* v_ip motion.txt /*v_ip* v_iquote motion.txt /*v_iquote* v_is motion.txt /*v_is* diff -ur vim-7-4-220/src/normal.c vim-7-4-220_patched/src/normal.c --- vim-7-4-220/src/normal.c Thu Mar 27 06:40:30 2014 +++ vim-7-4-220_patched/src/normal.c Thu Mar 27 11:27:22 2014 @@ -942,7 +942,7 @@ cp = &ca.nchar; } lang = (repl || (nv_cmds[idx].cmd_flags & NV_LANG)); - +getchar: /* * Get a second or third character. */ @@ -1093,6 +1093,18 @@ } #endif } +#ifdef FEAT_TEXTOBJ + /* + * The im/am text object needs one more character to use as left/right + * bounds. + */ + if ((ca.cmdchar == 'a' || ca.cmdchar == 'i') && ca.nchar == 'm' + && ca.extra_char == NUL) + { + cp = &ca.extra_char; + goto getchar; + } +#endif --no_mapping; --allow_keys; } @@ -1455,6 +1467,16 @@ prep_redo(oap->regname, cap->count0, get_op_char(oap->op_type), get_extra_op_char(oap->op_type), oap->motion_force, cap->cmdchar, cap->nchar); +#ifdef FEAT_TEXTOBJ + /* + * If using the am/im text object, there is one additional + * character used as left/right bounds which needs to be added to + * the redo buffer. + */ + if ((cap->cmdchar == 'a' || cap->cmdchar == 'i') + && cap->nchar == 'm' && cap->extra_char != NUL) + AppendCharToRedobuff(cap->extra_char); +#endif if (cap->cmdchar == '/' || cap->cmdchar == '?') /* was a search */ { /* @@ -9123,6 +9145,10 @@ case '`': /* "a`" = a backtick quoted string */ flag = current_quote(cap->oap, cap->count1, include, cap->nchar); + break; + case 'm': /* "am{char}" = a matched pair of characters */ + flag = current_match(cap->oap, cap->count1, include, + cap->extra_char); break; #if 0 /* TODO */ case 'S': /* "aS" = a section */ diff -ur vim-7-4-220/src/proto/search.pro vim-7-4-220_patched/src/proto/search.pro --- vim-7-4-220/src/proto/search.pro Thu Mar 27 06:40:30 2014 +++ vim-7-4-220_patched/src/proto/search.pro Thu Mar 27 11:27:23 2014 @@ -32,6 +32,7 @@ int current_tagblock __ARGS((oparg_T *oap, long count_arg, int include)); int current_par __ARGS((oparg_T *oap, long count, int include, int type)); int current_quote __ARGS((oparg_T *oap, long count, int include, int quotechar)); +int current_match __ARGS((oparg_T *oap, long count, int include, int matchchar)); int current_search __ARGS((long count, int forward)); int linewhite __ARGS((linenr_T lnum)); void find_pattern_in_path __ARGS((char_u *ptr, int dir, int len, int whole, int skip_comments, int type, long count, int action, linenr_T start_lnum, linenr_T end_lnum)); diff -ur vim-7-4-220/src/search.c vim-7-4-220_patched/src/search.c --- vim-7-4-220/src/search.c Thu Mar 27 06:40:30 2014 +++ vim-7-4-220_patched/src/search.c Thu Mar 27 11:27:23 2014 @@ -4437,6 +4437,147 @@ return OK; } + /* + * Find matching {char} on each side of cursor/visually selected range. + * Returns TRUE if found, else FALSE. + */ + int +current_match(oap, count, include, matchchar) + oparg_T *oap; /* used to set operator range, mode, etc */ + long count; /* not currently used */ + int include; /* TRUE == include bounding char */ + int matchchar; /* char to match on both sides */ +{ + pos_T old_pos; /* initial cursor position (to restore) */ + pos_T start_pos; /* left bound */ + pos_T end_pos; /* right bound */ + int ret; /* temp holder for return values */ +#ifdef FEAT_VISUAL + int vis_bef_curs; /* store visual mode direction */ + + /* + * Store visual mode direction so we can be sure it is set the same + * direction when we're done. + */ + vis_bef_curs = ltoreq(VIsual, curwin->w_cursor); +#endif + + /* + * Remember starting position so we can restore if we cannot find the + * requested object. + */ + old_pos = curwin->w_cursor; + + /* + * If there is a visually selected range, use its bounds as the starting + * bounds. Otherwise, have both bounds start under the cursor. + */ +#ifdef FEAT_VISUAL + if (VIsual_active && lt(VIsual, curwin->w_cursor)) + { + start_pos = VIsual; + end_pos = curwin->w_cursor; + } + else if (VIsual_active && lt(curwin->w_cursor, VIsual)) + { + start_pos = curwin->w_cursor; + end_pos = VIsual; + } + else +#endif + { + start_pos = curwin->w_cursor; + end_pos = curwin->w_cursor; + } + + /* + * Search for the left bound. It can be under or behind the starting + * position of the cursor position/visually selected range. + */ + curwin->w_cursor = start_pos; + while (gchar_cursor() != matchchar && dec_cursor() != -1) + ; + if (gchar_cursor() != matchchar) + { + /* Failed to find left bound, abort. */ + curwin->w_cursor = old_pos; + return FAIL; + } + start_pos = curwin->w_cursor; + + /* + * Search for the right bound. It has to be to the right of the starting + * cursor position/visually selected range. + */ + curwin->w_cursor = end_pos; + while (inc_cursor() != -1 && gchar_cursor() != matchchar) + ; + if (gchar_cursor() != matchchar) + { + /* Failed to find right bound, abort. */ + curwin->w_cursor = old_pos; + return FAIL; + } + end_pos = curwin->w_cursor; + + /* + * If not include (i.e.: o_i was used), try to move the bounds inward, but + * be sure they don't overlap or switch sides. + */ + if (!include) + { + /* try moving in right bound */ + curwin->w_cursor = end_pos; + ret = dec_cursor(); + if (ret == 2) + ret = dec_cursor(); + if (ret != -1 && !ltoreq(curwin->w_cursor, start_pos)) + { + end_pos = curwin->w_cursor; + } + + /* try moving in left bound */ + curwin->w_cursor = start_pos; + ret = inc_cursor(); + if (ret == 2) + ret = inc_cursor(); + if (ret != -1 && !ltoreq(end_pos, curwin->w_cursor)) + { + start_pos = curwin->w_cursor; + } + } + + /* + * We've found the new bounds. Set it in the appropriate places before + * returning. + */ +#ifdef FEAT_VISUAL + if (VIsual_active) + { + /* Retain direction we had when starting. */ + if (vis_bef_curs) + { + VIsual = start_pos; + curwin->w_cursor = end_pos; + } + else + { + curwin->w_cursor = start_pos; + VIsual = end_pos; + } + redraw_curbuf_later(INVERTED); /* update the inversion */ + } + else +#endif + { + oap->start = start_pos; + curwin->w_cursor = end_pos; + oap->motion_type = MCHAR; + oap->inclusive = TRUE; + } + return OK; +} + #endif /* FEAT_TEXTOBJ */ static int is_one_char __ARGS((char_u *pattern)); diff -ur vim-7-4-220/src/testdir/Makefile vim-7-4-220_patched/src/testdir/Makefile --- vim-7-4-220/src/testdir/Makefile Thu Mar 27 06:40:30 2014 +++ vim-7-4-220_patched/src/testdir/Makefile Thu Mar 27 11:27:23 2014 @@ -31,7 +31,7 @@ test89.out test90.out test91.out test92.out test93.out \ test94.out test95.out test96.out test97.out test98.out \ test99.out test100.out test101.out test102.out test103.out \ - test104.out test105.out test106.out + test104.out test105.out test106.out test107.out SCRIPTS_GUI = test16.out diff --git a/src/testdir/test107.in b/src/testdir/test107.in new file mode 100644 --- /dev/null +++ b/src/testdir/test107.in @@ -0,0 +1,62 @@ +Test for im/am text object + +Tests every combination of the following: +- every non-whitespace printable ASCII character (bang/33 to tilde/126) +- im (i) or am (a) +- in-line (l) or entire-line (L) +- single line (s) or multiple line (S) +- that . will properly repeat + +STARTTEST +:so small.vim +:enew +: +:" add all of the non-whitespace printable ASCII characters +:let objs = [] +::for nr in range(33,126) +:: let objs += [nr2char(nr)] +::endfor +:" spaces are characters that we aren't using as bounds +:let diffchars = " " + +:" Generate lines with im/am objects in them +:for char in objs +: for ia in ["i", "a"] +: for lL in ["l", "L"] +: for sS in ["s", "S"] +: if sS == "s" +: let lines = diffchars +: else +: let lines = diffchars . "\<cr>" . diffchars +: endif +: execute "normal o" . char . ia . lL . sS . "X" . char . lines . char . "X\<esc>" +: execute "normal oX" . char . lines . char . "X\<esc>" +: endfor +: endfor +: endfor +:endfor +: +:" Apply im/am to every created object, both directly and with . +: +:for char in objs +: for ia in ["i", "a"] +: for lL in ["l", "L"] +: for sS in ["s", "S"] +: execute "normal /^\\V" . escape(char,"\\") . ia . lL . sS . "\<cr>4x" +: if lL == "L" +: if sS == "s" +: execute "normal $x0x" +: else +: execute "normal j$xk0x" +: endif +: endif +: execute "normal lc" . ia . "m" . char . "OK\<esc>j03l." +: endfor +: endfor +: endfor +:endfor +: +:w! test.out +:qa! +ENDTEST + diff --git a/src/testdir/test107.ok b/src/testdir/test107.ok new file mode 100644 --- /dev/null +++ b/src/testdir/test107.ok @@ -0,0 +1,1505 @@ + +X!OK!X +X!OK!X +X!OK!X +X!OK!X +!OK! +X!OK!X +!OK! +X!OK!X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X"OK"X +X"OK"X +X"OK"X +X"OK"X +"OK" +X"OK"X +"OK" +X"OK"X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X#OK#X +X#OK#X +X#OK#X +X#OK#X +#OK# +X#OK#X +#OK# +X#OK#X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X$OK$X +X$OK$X +X$OK$X +X$OK$X +$OK$ +X$OK$X +$OK$ +X$OK$X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X%OK%X +X%OK%X +X%OK%X +X%OK%X +%OK% +X%OK%X +%OK% +X%OK%X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X&OK&X +X&OK&X +X&OK&X +X&OK&X +&OK& +X&OK&X +&OK& +X&OK&X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X'OK'X +X'OK'X +X'OK'X +X'OK'X +'OK' +X'OK'X +'OK' +X'OK'X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X(OK(X +X(OK(X +X(OK(X +X(OK(X +(OK( +X(OK(X +(OK( +X(OK(X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X)OK)X +X)OK)X +X)OK)X +X)OK)X +)OK) +X)OK)X +)OK) +X)OK)X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X*OK*X +X*OK*X +X*OK*X +X*OK*X +*OK* +X*OK*X +*OK* +X*OK*X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X+OK+X +X+OK+X +X+OK+X +X+OK+X ++OK+ +X+OK+X ++OK+ +X+OK+X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X,OK,X +X,OK,X +X,OK,X +X,OK,X +,OK, +X,OK,X +,OK, +X,OK,X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X-OK-X +X-OK-X +X-OK-X +X-OK-X +-OK- +X-OK-X +-OK- +X-OK-X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X.OK.X +X.OK.X +X.OK.X +X.OK.X +.OK. +X.OK.X +.OK. +X.OK.X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X/OK/X +X/OK/X +X/OK/X +X/OK/X +/OK/ +X/OK/X +/OK/ +X/OK/X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X0OK0X +X0OK0X +X0OK0X +X0OK0X +0OK0 +X0OK0X +0OK0 +X0OK0X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X1OK1X +X1OK1X +X1OK1X +X1OK1X +1OK1 +X1OK1X +1OK1 +X1OK1X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X2OK2X +X2OK2X +X2OK2X +X2OK2X +2OK2 +X2OK2X +2OK2 +X2OK2X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X3OK3X +X3OK3X +X3OK3X +X3OK3X +3OK3 +X3OK3X +3OK3 +X3OK3X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X4OK4X +X4OK4X +X4OK4X +X4OK4X +4OK4 +X4OK4X +4OK4 +X4OK4X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X5OK5X +X5OK5X +X5OK5X +X5OK5X +5OK5 +X5OK5X +5OK5 +X5OK5X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X6OK6X +X6OK6X +X6OK6X +X6OK6X +6OK6 +X6OK6X +6OK6 +X6OK6X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X7OK7X +X7OK7X +X7OK7X +X7OK7X +7OK7 +X7OK7X +7OK7 +X7OK7X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X8OK8X +X8OK8X +X8OK8X +X8OK8X +8OK8 +X8OK8X +8OK8 +X8OK8X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X9OK9X +X9OK9X +X9OK9X +X9OK9X +9OK9 +X9OK9X +9OK9 +X9OK9X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X:OK:X +X:OK:X +X:OK:X +X:OK:X +:OK: +X:OK:X +:OK: +X:OK:X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X;OK;X +X;OK;X +X;OK;X +X;OK;X +;OK; +X;OK;X +;OK; +X;OK;X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X<OK<X +X<OK<X +X<OK<X +X<OK<X +<OK< +X<OK<X +<OK< +X<OK<X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X=OK=X +X=OK=X +X=OK=X +X=OK=X +=OK= +X=OK=X +=OK= +X=OK=X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X>OK>X +X>OK>X +X>OK>X +X>OK>X +>OK> +X>OK>X +>OK> +X>OK>X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X?OK?X +X?OK?X +X?OK?X +X?OK?X +?OK? +X?OK?X +?OK? +X?OK?X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X@OK@X +X@OK@X +X@OK@X +X@OK@X +@OK@ +X@OK@X +@OK@ +X@OK@X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XAOKAX +XAOKAX +XAOKAX +XAOKAX +AOKA +XAOKAX +AOKA +XAOKAX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XBOKBX +XBOKBX +XBOKBX +XBOKBX +BOKB +XBOKBX +BOKB +XBOKBX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XCOKCX +XCOKCX +XCOKCX +XCOKCX +COKC +XCOKCX +COKC +XCOKCX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XDOKDX +XDOKDX +XDOKDX +XDOKDX +DOKD +XDOKDX +DOKD +XDOKDX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XEOKEX +XEOKEX +XEOKEX +XEOKEX +EOKE +XEOKEX +EOKE +XEOKEX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XFOKFX +XFOKFX +XFOKFX +XFOKFX +FOKF +XFOKFX +FOKF +XFOKFX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XGOKGX +XGOKGX +XGOKGX +XGOKGX +GOKG +XGOKGX +GOKG +XGOKGX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XHOKHX +XHOKHX +XHOKHX +XHOKHX +HOKH +XHOKHX +HOKH +XHOKHX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XIOKIX +XIOKIX +XIOKIX +XIOKIX +IOKI +XIOKIX +IOKI +XIOKIX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XJOKJX +XJOKJX +XJOKJX +XJOKJX +JOKJ +XJOKJX +JOKJ +XJOKJX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XKOKKX +XKOKKX +XKOKKX +XKOKKX +KOKK +XKOKKX +KOKK +XKOKKX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XLOKLX +XLOKLX +XLOKLX +XLOKLX +LOKL +XLOKLX +LOKL +XLOKLX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XMOKMX +XMOKMX +XMOKMX +XMOKMX +MOKM +XMOKMX +MOKM +XMOKMX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XNOKNX +XNOKNX +XNOKNX +XNOKNX +NOKN +XNOKNX +NOKN +XNOKNX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XOOKOX +XOOKOX +XOOKOX +XOOKOX +OOKO +XOOKOX +OOKO +XOOKOX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XPOKPX +XPOKPX +XPOKPX +XPOKPX +POKP +XPOKPX +POKP +XPOKPX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XQOKQX +XQOKQX +XQOKQX +XQOKQX +QOKQ +XQOKQX +QOKQ +XQOKQX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XROKRX +XROKRX +XROKRX +XROKRX +ROKR +XROKRX +ROKR +XROKRX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XSOKSX +XSOKSX +XSOKSX +XSOKSX +SOKS +XSOKSX +SOKS +XSOKSX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XTOKTX +XTOKTX +XTOKTX +XTOKTX +TOKT +XTOKTX +TOKT +XTOKTX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XUOKUX +XUOKUX +XUOKUX +XUOKUX +UOKU +XUOKUX +UOKU +XUOKUX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XVOKVX +XVOKVX +XVOKVX +XVOKVX +VOKV +XVOKVX +VOKV +XVOKVX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XWOKWX +XWOKWX +XWOKWX +XWOKWX +WOKW +XWOKWX +WOKW +XWOKWX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XXOKXX +XXOKXX +XXOKXX +XXOKXX +XOKX +XXOKXX +XOKX +XXOKXX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XYOKYX +XYOKYX +XYOKYX +XYOKYX +YOKY +XYOKYX +YOKY +XYOKYX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XZOKZX +XZOKZX +XZOKZX +XZOKZX +ZOKZ +XZOKZX +ZOKZ +XZOKZX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X[OK[X +X[OK[X +X[OK[X +X[OK[X +[OK[ +X[OK[X +[OK[ +X[OK[X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X\OK\X +X\OK\X +X\OK\X +X\OK\X +\OK\ +X\OK\X +\OK\ +X\OK\X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X]OK]X +X]OK]X +X]OK]X +X]OK]X +]OK] +X]OK]X +]OK] +X]OK]X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X^OK^X +X^OK^X +X^OK^X +X^OK^X +^OK^ +X^OK^X +^OK^ +X^OK^X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X_OK_X +X_OK_X +X_OK_X +X_OK_X +_OK_ +X_OK_X +_OK_ +X_OK_X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X`OK`X +X`OK`X +X`OK`X +X`OK`X +`OK` +X`OK`X +`OK` +X`OK`X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XaOKaX +XaOKaX +XaOKaX +XaOKaX +aOKa +XaOKaX +aOKa +XaOKaX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XbOKbX +XbOKbX +XbOKbX +XbOKbX +bOKb +XbOKbX +bOKb +XbOKbX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XcOKcX +XcOKcX +XcOKcX +XcOKcX +cOKc +XcOKcX +cOKc +XcOKcX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XdOKdX +XdOKdX +XdOKdX +XdOKdX +dOKd +XdOKdX +dOKd +XdOKdX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XeOKeX +XeOKeX +XeOKeX +XeOKeX +eOKe +XeOKeX +eOKe +XeOKeX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XfOKfX +XfOKfX +XfOKfX +XfOKfX +fOKf +XfOKfX +fOKf +XfOKfX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XgOKgX +XgOKgX +XgOKgX +XgOKgX +gOKg +XgOKgX +gOKg +XgOKgX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XhOKhX +XhOKhX +XhOKhX +XhOKhX +hOKh +XhOKhX +hOKh +XhOKhX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XiOKiX +XiOKiX +XiOKiX +XiOKiX +iOKi +XiOKiX +iOKi +XiOKiX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XjOKjX +XjOKjX +XjOKjX +XjOKjX +jOKj +XjOKjX +jOKj +XjOKjX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XkOKkX +XkOKkX +XkOKkX +XkOKkX +kOKk +XkOKkX +kOKk +XkOKkX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XlOKlX +XlOKlX +XlOKlX +XlOKlX +lOKl +XlOKlX +lOKl +XlOKlX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XmOKmX +XmOKmX +XmOKmX +XmOKmX +mOKm +XmOKmX +mOKm +XmOKmX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XnOKnX +XnOKnX +XnOKnX +XnOKnX +nOKn +XnOKnX +nOKn +XnOKnX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XoOKoX +XoOKoX +XoOKoX +XoOKoX +oOKo +XoOKoX +oOKo +XoOKoX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XpOKpX +XpOKpX +XpOKpX +XpOKpX +pOKp +XpOKpX +pOKp +XpOKpX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XqOKqX +XqOKqX +XqOKqX +XqOKqX +qOKq +XqOKqX +qOKq +XqOKqX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XrOKrX +XrOKrX +XrOKrX +XrOKrX +rOKr +XrOKrX +rOKr +XrOKrX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XsOKsX +XsOKsX +XsOKsX +XsOKsX +sOKs +XsOKsX +sOKs +XsOKsX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XtOKtX +XtOKtX +XtOKtX +XtOKtX +tOKt +XtOKtX +tOKt +XtOKtX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XuOKuX +XuOKuX +XuOKuX +XuOKuX +uOKu +XuOKuX +uOKu +XuOKuX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XvOKvX +XvOKvX +XvOKvX +XvOKvX +vOKv +XvOKvX +vOKv +XvOKvX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XwOKwX +XwOKwX +XwOKwX +XwOKwX +wOKw +XwOKwX +wOKw +XwOKwX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XxOKxX +XxOKxX +XxOKxX +XxOKxX +xOKx +XxOKxX +xOKx +XxOKxX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XyOKyX +XyOKyX +XyOKyX +XyOKyX +yOKy +XyOKyX +yOKy +XyOKyX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +XzOKzX +XzOKzX +XzOKzX +XzOKzX +zOKz +XzOKzX +zOKz +XzOKzX +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X{OK{X +X{OK{X +X{OK{X +X{OK{X +{OK{ +X{OK{X +{OK{ +X{OK{X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X|OK|X +X|OK|X +X|OK|X +X|OK|X +|OK| +X|OK|X +|OK| +X|OK|X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X}OK}X +X}OK}X +X}OK}X +X}OK}X +}OK} +X}OK}X +}OK} +X}OK}X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX +X~OK~X +X~OK~X +X~OK~X +X~OK~X +~OK~ +X~OK~X +~OK~ +X~OK~X +XOKX +XOKX +XOKX +XOKX +OK +XOKX +OK +XOKX