def key(string):
<EOL>subkeys = [], [], [], []<EOL>add_alphabet = subkeys[<NUM_LIT:0>].append<EOL>add_diacritic = subkeys[<NUM_LIT:1>].append<EOL>add_case = subkeys[<NUM_LIT:2>].append<EOL>add_punctuation = subkeys[<NUM_LIT:3>].append<EOL>skip = <NUM_LIT:0><EOL>normal = nfkd(string).rstrip()<EOL>diacritics = []<EOL>for i, char in enumerate(normal):<EOL><INDENT>if skip > <NUM_LIT:0>:<EOL><INDENT>skip -= <NUM_LIT:1><EOL>continue<EOL><DEDENT>category = get_category(char)<EOL>cat0, cat1 = category<EOL>if cat0 == '<STR_LIT:L>':<EOL><INDENT>char_lower = char.lower()<EOL>found = False<EOL>if char_lower in DECOMPOSING_EXTRAS:<EOL><INDENT>char_lower, _extra_diacritics = DECOMPOSING_EXTRAS[char]<EOL>diacritics.extend(_extra_diacritics)<EOL><DEDENT>for next in normal[i+<NUM_LIT:1>:]:<EOL><INDENT>if next == HACEK and char_lower in ('<STR_LIT:c>', '<STR_LIT:r>', '<STR_LIT:s>', '<STR_LIT:z>'):<EOL><INDENT>skip += <NUM_LIT:1><EOL>char_lower = char_lower + '<STR_LIT:x>'<EOL><DEDENT>elif char_lower == '<STR_LIT:c>' and next.lower() == '<STR_LIT:h>':<EOL><INDENT>skip += <NUM_LIT:1><EOL>char_lower = '<STR_LIT>'<EOL>break<EOL><DEDENT>elif next in DIACRITICS_MAP:<EOL><INDENT>skip += <NUM_LIT:1><EOL>diacritics.extend(DIACRITICS_MAP[next])<EOL><DEDENT>elif unicodedata.category(char)[<NUM_LIT:0>] == '<STR_LIT:M>':<EOL><INDENT>skip += <NUM_LIT:1><EOL>diacritics.append((POS_UNKNOWN, SH_UNKNOWN))<EOL><DEDENT>else:<EOL><INDENT>break<EOL><DEDENT><DEDENT>add_alphabet((<NUM_LIT:1>, char_lower))<EOL>if diacritics:<EOL><INDENT>add_diacritic(make_diacritics_key(diacritics))<EOL><DEDENT>else:<EOL><INDENT>add_diacritic(())<EOL><DEDENT>add_case(cat1 in ('<STR_LIT:u>', '<STR_LIT:t>'))  <EOL>add_punctuation((<NUM_LIT:0>, ))<EOL>diacritics = []<EOL><DEDENT>elif cat0 == '<STR_LIT>':<EOL><INDENT>counts = {'<STR_LIT>': <NUM_LIT:0>, '<STR_LIT>': <NUM_LIT:0>, '<STR_LIT>': <NUM_LIT:0>}<EOL>counts[category] = <NUM_LIT:1><EOL>for next in normal[i+<NUM_LIT:1>:]:<EOL><INDENT>next_cat = get_category(next)<EOL>if next_cat[<NUM_LIT:0>] == '<STR_LIT>':<EOL><INDENT>counts[next_cat] += <NUM_LIT:1><EOL>skip += <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>break<EOL><DEDENT><DEDENT>add_alphabet((<NUM_LIT:0>, -counts['<STR_LIT>'], -counts['<STR_LIT>'], -counts['<STR_LIT>']))<EOL>add_diacritic(())<EOL>add_case(False)<EOL>add_punctuation((<NUM_LIT:0>, ))<EOL><DEDENT>elif char in DIACRITICS_BEFORE_MAP:<EOL><INDENT>diacritics.extend(DIACRITICS_BEFORE_MAP[char])<EOL><DEDENT>elif char in DIACRITICS_MAP:<EOL><INDENT>diacritics.extend(DIACRITICS_MAP[char])<EOL><DEDENT>elif char in PUNCTUATION_MAP:<EOL><INDENT>add_punctuation(PUNCTUATION_MAP[char])<EOL><DEDENT>elif cat0 == '<STR_LIT:P>':<EOL><INDENT>add_punctuation((<NUM_LIT:3>, ))<EOL><DEDENT>elif cat0 == '<STR_LIT:N>':<EOL><INDENT>add_alphabet((<NUM_LIT:2>, int(unicodedata.numeric(char, <NUM_LIT:0>)) * <NUM_LIT:100>))<EOL>add_diacritic(())<EOL>add_case(False)<EOL>add_punctuation((<NUM_LIT:0>, ))<EOL><DEDENT>elif cat0 == '<STR_LIT:S>':<EOL><INDENT>add_punctuation((<NUM_LIT:3>, ))<EOL><DEDENT>elif cat0 == '<STR_LIT:C>':<EOL><INDENT>pass<EOL><DEDENT>elif cat0 == '<STR_LIT:M>':<EOL><INDENT>diacritics.append((POS_FRONT, SH_UNKNOWN))<EOL><DEDENT>else:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT><DEDENT>if diacritics:<EOL><INDENT>add_diacritic(make_diacritics_key(diacritics))<EOL>diacritics = []<EOL><DEDENT>return tuple(tuple(k) for k in subkeys) + (normal, string)<EOL>
Return a Czech sort key for the given string

    :param string: string (unicode in Python 2)

    Comparing the sort keys of two strings will give the result according
    to how the strings would compare in Czech collation order, i.e.
        ``key(s1) < key(s2)``  <=>  ``s1`` comes before ``s2``

    The structure of the sort key may change in the future.
    The only operations guaranteed to work on it are comparisons and equality
    checks (<, ==, etc.) against other keys.