Zi ,dZddlmZddlmZddlmZddlmZddl m Z ddl m Z dd l mZmZmZmZmZdd lmZdd lmZdd lmZdd lmZmZmZmZddlmZm Z m!Z!ddl"m#Z#ddl$m%Z%m&Z&m'Z'm(Z(ddl)m*Z*er ddl+m,Z,ddlm-Z-e*dZ.ee.Z/ee.Z0e#e1e2e#Z3e e.Z4e5e6e!dde!dddzZ7e5de De7zZ8dZ9e5dZ:eZ;dZddd?de6ddDdzd?de6ddDzZ@d ZAed!"dOdPd*ZB dQdRd/ZCed"dSd2ZDed3"dTd5ZEdUd8ZFdVdWd9ZGd:d3dd;dXd?ZH dYd:ddAdZdDZI dYd:ddAdZdEZJ dYd:ddAdZdFZKd[dGZLd@d3ddHdId\dNZMd+S)]a This is a python implementation of wcwidth() and wcswidth(). https://github.com/jquast/wcwidth from Markus Kuhn's C code, retrieved from: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c This is an implementation of wcwidth() and wcswidth() (defined in IEEE Std 1002.1-2001) for Unicode. http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html In fixed-width output devices, Latin characters all occupy a single "cell" position of equal width, whereas ideographic CJK characters occupy two such cells. Interoperability between terminal-line applications and (teletype-style) character terminals using the UTF-8 encoding requires agreement on which character should advance the cursor by how many cell positions. No established formal standards exist at present on which Unicode character shall occupy how many cell positions on character terminals. These routines are a first attempt of defining such behavior based on simple rules applied to data provided by the Unicode Consortium. For some graphical characters, the Unicode standard explicitly defines a character-cell width via the definition of the East Asian FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes. In all these cases, there is no ambiguity about which width a terminal shall use. For characters in the East Asian Ambiguous (A) class, the width choice depends purely on a preference of backward compatibility with either historic CJK or Western practice. Choosing single-width for these characters is easy to justify as the appropriate long-term solution, as the CJK practice of displaying these characters as double-width comes from historic implementation simplicity (8-bit encoded characters were displayed single-width and 16-bit ones double-width, even for Greek, Cyrillic, etc.) and not any typographic considerations. Much less clear is the choice of width for the Not East Asian (Neutral) class. Existing practice does not dictate a width for any of these characters. It would nevertheless make sense typographically to allocate two character cells to characters such as for instance EM SPACE or VOLUME INTEGRAL, which cannot be represented adequately with a single-width glyph. The following routines at present merely assign a single-cell width to all neutral characters, in the interest of simplicity. This is not entirely satisfactory and should be reconsidered before establishing a formal standard in this area. At the moment, the decision which Not East Asian (Neutral) characters should be represented by double-width glyphs cannot yet be answered by applying a simple rule from the Unicode database content. Setting up a proper standard for the behavior of UTF-8 character terminals will require a careful analysis not only of each Unicode character, but also of each presentation form, something the author of these routines has avoided to do so far. http://www.unicode.org/unicode/reports/tr11/ Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c ) annotations) lru_cache) TYPE_CHECKING)bisearch)iter_graphemes) CATEGORY_MC) _SGR_PATTERN_SGR_STATE_DEFAULT_sgr_state_update_sgr_state_is_active_sgr_state_to_sequence)VS16_NARROW_TO_WIDE)WIDE_EASTASIAN) ZERO_WIDTH) ILLEGAL_CTRL VERTICAL_CTRLHORIZONTAL_CTRLZERO_WIDTH_CTRL) ISC_CONSONANTEXTENDED_PICTOGRAPHICGRAPHEME_REGIONAL_INDICATOR)AMBIGUOUS_EASTASIAN)ZERO_WIDTH_PATTERNCURSOR_LEFT_SEQUENCECURSOR_RIGHT_SEQUENCEINDETERMINATE_EFFECT_SEQUENCE) list_versions)Iterator)Literalc#LK|]\}}t||dzD]}|V dS)rN)range).0lohicps _/home/jenkins/workspace/simtester-sanitize/venv/lib/python3.11/site-packages/wcwidth/wcwidth.py r)ksY 2rU2rAv5F5F/1B)ii)iM i iM i iM i iM i iM i iDiiĨiiFiii5iMiBiii?ii9ii?c#4K|]}t|VdSNchrr$cs r(r)r)( . .qCFF . . . . . .r* c#4K|]}t|VdSr.r/r1s r(r)r)r3r*)rrrrrwcwidthwcswidthwidthiter_sequencesljustrjustcenterclipstrip_sequences_wcmatch_version_wcversion_valuei)maxsizeautowcstrunicode_versionambiguous_widthintreturnc|rt|nd}d|cxkrdkrnndS|r|dksd|cxkrdkrnndSt|trdSt|trdS|dkrt|trdSdS)a* Given one Unicode codepoint, return its printable length on a terminal. :param wc: A single Unicode character. :param unicode_version: Ignored. Retained for backwards compatibility. .. deprecated:: 0.3.0 Only the latest Unicode version is now shipped. :param ambiguous_width: Width to use for East Asian Ambiguous (A) characters. Default is ``1`` (narrow). Set to ``2`` for CJK contexts where ambiguous characters display as double-width. See :ref:`ambiguous_width` for details. :returns: The width, in cells, necessary to display the character of Unicode string character, ``wc``. Returns 0 if the ``wc`` argument has no printable effect on a terminal (such as NUL '\0'), -1 if ``wc`` is not printable, or has an indeterminate effect on the terminal, such as a control character. Otherwise, the number of column positions the character occupies on a graphic terminal (1 or 2) is returned. See :ref:`Specification` for details of cell measurement. rr4rr8r!)ord _bisearch_ZERO_WIDTH_TABLE_WIDE_EASTASIAN_TABLE_AMBIGUOUS_TABLE)rFrHrIucss r(r9r9s0 #b'''QC  S4q sRxx5C////%/////r'((q+,,q! #/? @ @q 1r*Npwcsn int | Nonecp|7|r#|rt|Sdkrtnfd}|t|n|}d}d}d}d} d} d} ||kr||} t | } | dkr!| r|dz }n|dz|kr|d z }d} n|dz }d} E| d kr?|dkr9|t t ||t d z }d}|dz }| d kr| tvrgd}|dz }|dkrHt ||tvr,|dz }|dz}|dkrt ||tv,|d zdkr|dz }| } n6td| cxkrtdkrnn| tvr|dz }6| r$t | tr|}| } d} d } |dz }\|| }|dkr|S|dkr| r|dz }d} |}| } d} n-|dkrt | tr d}d}d} d} n | tv} ||z }|dz }||k| r|dz }|S)a8 Given a unicode string, return its printable length on a terminal. :param pwcs: Measure width of given unicode string. :param n: When ``n`` is None (default), return the length of the entire string, otherwise only the first ``n`` characters are measured. Better to use string slicing capability, ``wcswidth(pwcs[:n])``, instead, for performance. This argument is a holdover from the POSIX function for matching signatures. Be careful that ``n`` is at grapheme boundaries. :param unicode_version: Ignored. Retained for backwards compatibility. .. deprecated:: 0.3.0 Only the latest Unicode version is now shipped. :param ambiguous_width: Width to use for East Asian Ambiguous (A) characters. Default is ``1`` (narrow). Set to ``2`` for CJK contexts. :returns: The width, in cells, needed to display the first ``n`` characters of the unicode string ``pwcs``. Returns ``-1`` for C0 and C1 control characters! See :ref:`Specification` for details of cell measurement. Nrc&t|dSNrEr9r2rIs r(zwcswidth..gaQ`>a>ar*rr!Fi rN9.0.0T) isascii isprintablelenr9rOrPr_REGIONAL_INDICATOR_SET_FITZPATRICK_RANGE_EMOJI_ZWJ_SET_ISC_CONSONANT_TABLE_CATEGORY_MC_TABLE_ISC_VIRAMA_SET)rUrVrHrI_wcwidthend total_widthidxlast_measured_idxlast_measured_ucslast_was_viramaconjunct_pendingcharrT ri_beforejwcws ` r(r:r:s3H yT\\^^y(8(8(:(:y4yy *Q..ww4a4a4a4aHy#d)))aCK CO ))Cy$ii &== (qq3q"'q"'  &==.!33 9S.?)@%A%A%8%ACC CK "  1HC  <<--- !G1ffT!W1H!H!HNIFA1ffT!W1H!H!Hq=A%%1HC(+% &%Q'3GGGG2DQ2GGGGGG'>99q  y.BCC  #  # #O#  1HC htnn 77J 77 )q #( #  # #OO ! # # #7I(J(J #C " #O$  !_4Os  q_ ))`q r* ver_stringtuple[int, ...]cpttt|d}|S)aZ Integer-mapped value of given dotted version string. .. deprecated:: 0.3.0 This function is no longer used internally by wcwidth but is retained for API compatibility with external tools. :param ver_string: Unicode version string, of form ``n.n.n``. :returns: tuple of digit tuples, ``tuple(int, [...])``. .)tuplemaprJsplit)rxretvals r(rCrC{s.3sZ--c2244 5 5F Mr* given_versionctS)a Return the supported Unicode version level. .. deprecated:: 0.3.0 This function now always returns the latest version. This function is no longer used internally by wcwidth but is retained for API compatibility with external tools. :param given_version: Ignored. Any value is accepted for compatibility. :returns: The latest unicode version string. )_LATEST_VERSION)rs r(rBrBs  r*textIterator[tuple[str, bool]]c#fKd}t|}d}||kr||}|dkrf||kr|||dfVtj||}|r-|dfV|}n |dfV|dz }|}n|dz }||k||kr||ddfVdSdS)a Iterate through text, yielding segments with sequence identification. This generator yields tuples of ``(segment, is_sequence)`` for each part of the input text, where ``is_sequence`` is ``True`` if the segment is a recognized terminal escape sequence. :param text: String to iterate through. :returns: Iterator of (segment, is_sequence) tuples. .. versionadded:: 0.3.0 Example:: >>> list(iter_sequences('hello')) [('hello', False)] >>> list(iter_sequences('\x1b[31mred')) [('\x1b[31m', True), ('red', False)] >>> list(iter_sequences('\x1b[1m\x1b[31m')) [('\x1b[1m', True), ('\x1b[31m', True)] rFTrN)rermatchgrouprm)rrotext_len segment_startrtrs r(r<r<s , C4yyHM ..Cy 6>>]""M#-.6666',T377E {{}}d++++iikkTl"""qMM 1HC' ..,xMNN#U++++++ r*cntt|t|S)z Fast path for width() with control_codes='ignore'. Strips escape sequences and control characters, then measures remaining text. rI)r:rA translate_CONTROL_CHAR_TABLE)rrIs r(_width_ignored_codesrs8 ''(;<<'   r*parse) control_codestabsizerIr$Literal['parse', 'strict', 'ignore']rc  |r#|rt|S|dkrRt|tkr:d|vr6d|vr2d|vr.d|vs(t j|st j|sd}|dkrt|S|dk}d}d}d}d }d } d } d } t|} d krtnfd } || kr||}|dkrtj ||}|r| }|r&tj |rtd|t j |}|r(|t| d pd z }nKt j |}|r5td|t| d pd z }|}n|d z }t||}|t"vr,|r#tdt%|dd||d z }S|t&vr,|r#tdt%|dd||d z }|t(vrI|dkr|dkr ||||zz z }n|dkr |dkr|d z}n|dkrd}t||}|d z }|dkr"| r|d z }n|d z| kr|dz }d } n|d z }d } |t*vr|d z }t%|}|dkrS||d z krCt-t%||t.dr|d z }t||}|d z }z|dkr|t0vrhd}|d z }|dkrHt%||t0vr,|d z }|d z}|dkrt%||t0v,|dzd kr |} |d z }n6t2d|cxkrt2d krnn| t4vr|d z }'| r$t-|t6r|}|} d } d} |d z }M| |}|dkr%| r|d z }d } ||z }t||}|}|} d } n@|dkr1t-|t8r|d z }t||}d }d } d } n |t:v} |d z }|| k| r|d z }t||}|S)u Return printable width of text containing many kinds of control codes and sequences. Unlike :func:`wcswidth`, this function handles most control characters and many popular terminal output sequences. Never returns -1. :param text: String to measure. :param control_codes: How to handle control characters and sequences: - ``'parse'`` (default): Track horizontal cursor movement from BS ``\b``, CR ``\r``, TAB ``\t``, and cursor left and right movement sequences. Vertical movement (LF, VT, FF) and indeterminate sequences are zero-width. Never raises. - ``'strict'``: Like parse, but raises :exc:`ValueError` on control characters with indeterminate results of the screen or cursor, like clear or vertical movement. Generally, these should be handled with a virtual terminal emulator (like 'pyte'). - ``'ignore'``: All C0 and C1 control characters and escape sequences are measured as width 0. This is the fastest measurement for text already filtered or known not to contain any kinds of control codes or sequences. TAB ``\t`` is zero-width; for tab expansion, pre-process: ``text.replace('\t', ' ' * 8)``. :param tabsize: Tab stop width for ``'parse'`` and ``'strict'`` modes. Default is 8. Must be positive. Has no effect when ``control_codes='ignore'``. :param ambiguous_width: Width to use for East Asian Ambiguous (A) characters. Default is ``1`` (narrow). Set to ``2`` for CJK contexts. :returns: Maximum cursor position reached, "extent", accounting for cursor movement sequences present in ``text`` according to given parameters. This represents the rightmost column the cursor reaches. Always a non-negative integer. :raises ValueError: If ``control_codes='strict'`` and control characters with indeterminate effects, such as vertical movement or clear sequences are encountered, or on unexpected C0 or C1 control code. Also raised when ``control_codes`` is not one of the valid values. .. versionadded:: 0.3.0 Examples:: >>> width('hello') 5 >>> width('コンニチハ') 10 >>> width('\x1b[31mred\x1b[0m') 3 >>> width('\x1b[31mred\x1b[0m', control_codes='ignore') # same result (ignored) 3 >>> width('123\b4') # backspace overwrites previous cell (outputs '124') 3 >>> width('abc\t') # tab caused cursor to move to column 8 8 >>> width('1\x1b[10C') # '1' + cursor right 10, cursor ends on column 11 11 >>> width('1\x1b[10C', control_codes='ignore') # faster but wrong in this case 1 r  rignorestrictrr_r!Frc&t|dSrZr[r\s r(r]zwidth..Ar^r*z*Indeterminate cursor sequence at position zIllegal control character z#xz at position zVertical movement character u‍rNr`rarbT)rcrdre_WIDTH_FAST_PATH_MIN_LENrsearchrrr9rrrr ValueErrorrJmaxrmrrOrrrrPrrfrgrhrirjrk)rrrrIr current_col max_extentrorprqrrrsrrlrtrseqrightleftrTrurvws ` r(r;r;s?D ||~~$**,,4yyCII0H$H$H t  D 0 0T5E5ET!!)066"(/55"!)   #D/::: h &FKJ CO4yyH *Q..ww4a4a4a4aH ..Cy 6>>&,T377E kkmmY;A#FFY$%WRU%W%WXXX-3C88T3u{{1~~':#;#;;KK/5c::DT&)![3tzz!}}?QPQ;R;R-R&S&S iikkqZ55J  <   ` !^c$ii!^!^!^Y\!^!^___ 1HC  =  b !`D !`!`!`[^!`!`aaa 1HC  ? " "v~~'A++w+*?@@ ??1$K Z55J 1HC  8   (qq8##q"'q"'  ? " " 1HC $ii &== C!G++S&7!899;Nw;WXX>1$K!$Z!=!=J 1HC  <<--- !G1ffT!W1H!H!HNIFA1ffT!W1H!H!Hq=A%%(+%1HC& %Q'3GGGG2DQ2GGGGGG'>99q  y.BCC  #  # #O#  1HC  HTNN q55 )q #( 1 KZ55J #  # #OO ! # # #7I(J(J # 1 KZ55J " #O$  !_4O qI ..L2q [11 r* rrI dest_widthfillcharc|r$|rt|}nt|||}t d||z }|||zzS)u) Return text left-justified in a string of given display width. :param text: String to justify, may contain terminal sequences. :param dest_width: Total display width of result in terminal cells. :param fillchar: Single character for padding (default space). Must have display width of 1 (not wide, not zero-width, not combining). Unicode characters like ``'·'`` are acceptable. The width is not validated. :param control_codes: How to handle control sequences when measuring. Passed to :func:`width` for measurement. :param ambiguous_width: Width to use for East Asian Ambiguous (A) characters. Default is ``1`` (narrow). Set to ``2`` for CJK contexts. :returns: Text padded on the right to reach ``dest_width``. .. versionadded:: 0.3.0 Example:: >>> wcwidth.ljust('hi', 5) 'hi ' >>> wcwidth.ljust('\x1b[31mhi\x1b[0m', 5) '\x1b[31mhi\x1b[0m ' >>> wcwidth.ljust('\U0001F468\u200D\U0001F469\u200D\U0001F467', 6) '👨‍👩‍👧 ' rrrcrdrer;rrrrrrI text_width padding_cellss r(r=r=soB ||~~_$**,,_YY 4}o^^^ : 233M (]* **r*c|r$|rt|}nt|||}t d||z }||z|zS)u) Return text right-justified in a string of given display width. :param text: String to justify, may contain terminal sequences. :param dest_width: Total display width of result in terminal cells. :param fillchar: Single character for padding (default space). Must have display width of 1 (not wide, not zero-width, not combining). Unicode characters like ``'·'`` are acceptable. The width is not validated. :param control_codes: How to handle control sequences when measuring. Passed to :func:`width` for measurement. :param ambiguous_width: Width to use for East Asian Ambiguous (A) characters. Default is ``1`` (narrow). Set to ``2`` for CJK contexts. :returns: Text padded on the left to reach ``dest_width``. .. versionadded:: 0.3.0 Example:: >>> wcwidth.rjust('hi', 5) ' hi' >>> wcwidth.rjust('\x1b[31mhi\x1b[0m', 5) ' \x1b[31mhi\x1b[0m' >>> wcwidth.rjust('\U0001F468\u200D\U0001F469\u200D\U0001F467', 6) ' 👨‍👩‍👧' rrrrs r(r>r>soB ||~~_$**,,_YY 4}o^^^ : 233M m #d **r*c|r$|rt|}nt|||}t d||z }|dz||zdzz}||z }||z|z||zzS)u Return text centered in a string of given display width. :param text: String to center, may contain terminal sequences. :param dest_width: Total display width of result in terminal cells. :param fillchar: Single character for padding (default space). Must have display width of 1 (not wide, not zero-width, not combining). Unicode characters like ``'·'`` are acceptable. The width is not validated. :param control_codes: How to handle control sequences when measuring. Passed to :func:`width` for measurement. :param ambiguous_width: Width to use for East Asian Ambiguous (A) characters. Default is ``1`` (narrow). Set to ``2`` for CJK contexts. :returns: Text padded on both sides to reach ``dest_width``. For odd-width padding, the extra cell goes on the right (matching Python's :meth:`str.center` behavior). .. versionadded:: 0.3.0 Example:: >>> wcwidth.center('hi', 6) ' hi ' >>> wcwidth.center('\x1b[31mhi\x1b[0m', 6) ' \x1b[31mhi\x1b[0m ' >>> wcwidth.center('\U0001F468\u200D\U0001F469\u200D\U0001F467', 6) ' 👨‍👩‍👧 ' rrrNrr) rrrrrIr total_paddingleft_pad right_pads r(r?r?!sH ||~~_$**,,_YY 4}o^^^ : 233M!]Z%?!%CDH(I h  %9(< <>> strip_sequences('\x1b[31mred\x1b[0m') 'red' >>> strip_sequences('hello') 'hello' >>> strip_sequences('\x1b[1m\x1b[31mbold red\x1b[0m text') 'bold red text' r,)rsub)rs r(rArAPs(  !"d + ++r*T)rrrI propagate_sgrstartrmrboolct|d}||krdS|r|r |||S|rd|vrd}d}|rt}g} d} d} | t |kr6|| } | |kr || dkrn| dkr|t j|| x} re| }|r%tj|rt||}n| || } | dkr| | | dz } | dkrj|dkrH| || |zz z}| |kr6|| cxkr|krnn| d|r||}| dz } | |k6n| | | dz } ?tt|| }t|| }|dkr&|| cxkr|krnn| |n| |kr*| |z|kr!| ||r||}| |z } nZ| |krO| |z|krF| |t|| |zt|| z z|r||}| |z } n| |z } | t |z } | t |k6d| }|*t#|x}r||z}t%|r|d z }|S) u6 Clip text to display columns ``(start, end)`` while preserving all terminal sequences. This function extracts a substring based on visible column positions rather than character indices. Terminal escape sequences are preserved in the output since they have zero display width. If a wide character (width 2) would be split at either boundary, it is replaced with ``fillchar``. TAB characters (``\t``) are expanded to spaces up to the next tab stop, controlled by the ``tabsize`` parameter. Other cursor movement characters (backspace, carriage return) and cursor movement sequences are passed through unchanged as zero-width. :param text: String to clip, may contain terminal escape sequences. :param start: Absolute starting column (inclusive, 0-indexed). :param end: Absolute ending column (exclusive). :param fillchar: Character to use when a wide character must be split at a boundary (default space). Must have display width of 1. :param tabsize: Tab stop width (default 8). Set to 0 to pass tabs through as zero-width (preserved in output but don't advance column position). :param ambiguous_width: Width to use for East Asian Ambiguous (A) characters. Default is ``1`` (narrow). Set to ``2`` for CJK contexts. :param propagate_sgr: If True (default), SGR (terminal styling) sequences are propagated. The result begins with any active style at the start position and ends with a reset sequence if styles are active. :returns: Substring of ``text`` spanning display columns ``(start, end)``, with all terminal sequences preserved and wide characters at boundaries replaced with ``fillchar``. SGR (terminal styling) sequences are propagated by default. The result begins with any active style and ends with a reset:: >>> clip('\x1b[1;34mHello world\x1b[0m', 6, 11) '\x1b[1;34mworld\x1b[0m' Set ``propagate_sgr=False`` to disable this behavior. .. versionadded:: 0.3.0 .. versionchanged:: 0.5.0 Added ``propagate_sgr`` parameter (default True). Example:: >>> clip('hello world', 0, 5) 'hello' >>> clip('中文字', 0, 3) # Wide char split at column 3 '中 ' >>> clip('a\tb', 0, 10) # Tab expanded to spaces 'a b' rr,rFNrrr)rrz)rrcrdr rerrrr r appendrmnextrr;minjoinrr )rrrmrrrIrsgr_at_clip_startsgroutputcolrortrrnext_tabgraphemerresultprefixs r(r@r@gsB qMME e||r ||~~$**,,E#It++ ! F C C D //Cy #::+7DFNN  6>>(:(@s(K(KKu>++--C #!3C!8!8 #'S11 c"""))++C  6>> MM$    1HC  4<<{{'S7]";<Hnn))))c))))) c***(4->-F03-1HC Hnn d### 1HC t377788 (O < < < 66!!!!c!!!!! h''' E\\cAgnn MM( # # # (!2!:$'! 1HCC 3YY37U?? MM(c#sQw&7&7#eS//&IJ K K K (!2!:$'! 1HCC 1HC s8}}} D //@WWV__F$+,=>> >6 %f_F  1 2 2 i F Mr*)rEr)rFrGrHrGrIrJrKrJ)NrEr) rUrGrVrWrHrGrIrJrKrJ)rxrGrKry)rrGrKrG)rrGrKr)r)rrGrIrJrKrJ) rrGrrrrJrIrJrKrJ)r) rrGrrJrrGrrrIrJrKrG)rrGrKrG)rrGrrJrmrJrrGrrJrIrJrrrKrG)N__doc__ __future__r functoolsrtypingrrrPrrtable_mcr sgr_stater r r r r table_vs16r table_wider table_zerorrrrrrtable_graphemerrrtable_ambiguousrescape_sequencesrrrrunicode_versionsrcollections.abcrr rrQrRriterrSrj frozensetr#rfrhrgrkrirrG maketransrr__all__r9r:rCrBr<rr;r=r>r?rAr@r*r(rsJ==~#"""""  ,+++++$$$$$$!!!!!!00000000000000 ,+++++&&&&&&""""""XXXXXXXXXXXX]]]]]]]]]]000000>>>>>>>>>>>>,+++++(((((( -//"%/&7&ttDD1D,E,E'F'FG 1#) E %a ( +-H-KA-NQR-RSS*():% mmBGG . .EE$-- . . ...  GG . .EE$-- . . .../ 0 4/ / / / / h! EEEEE^ 3      1     1,1,1,1,h     ;B ooooooj&+ ;B &+&+&+&+&+&+X&+ ;B &+&+&+&+&+&+X,= ;B ,=,=,=,=,=,=^,,,,8________r*