From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Luke Lee Newsgroups: gmane.emacs.bugs Subject: bug#17854: The patch #3 of 3 for hideif.el, a lot of bug fixes and enhancements Date: Mon, 30 Jun 2014 22:42:37 +0800 Message-ID: References: <75lhsh7qb8.fsf@fencepost.gnu.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=001a1136505610053e04fd0eaeaf X-Trace: ger.gmane.org 1404139472 1779 80.91.229.3 (30 Jun 2014 14:44:32 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 30 Jun 2014 14:44:32 +0000 (UTC) To: 17854@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Mon Jun 30 16:44:25 2014 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1X1coh-0007ay-LQ for geb-bug-gnu-emacs@m.gmane.org; Mon, 30 Jun 2014 16:44:24 +0200 Original-Received: from localhost ([::1]:34788 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X1coh-0008WU-A2 for geb-bug-gnu-emacs@m.gmane.org; Mon, 30 Jun 2014 10:44:23 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:45014) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X1coV-0008S7-EV for bug-gnu-emacs@gnu.org; Mon, 30 Jun 2014 10:44:19 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X1coN-0005eo-NR for bug-gnu-emacs@gnu.org; Mon, 30 Jun 2014 10:44:11 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:46875) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X1coN-0005ee-He for bug-gnu-emacs@gnu.org; Mon, 30 Jun 2014 10:44:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1X1coM-0001CW-Jz for bug-gnu-emacs@gnu.org; Mon, 30 Jun 2014 10:44:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Luke Lee Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 30 Jun 2014 14:44:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 17854 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 17854-submit@debbugs.gnu.org id=B17854.14041394204578 (code B ref 17854); Mon, 30 Jun 2014 14:44:02 +0000 Original-Received: (at 17854) by debbugs.gnu.org; 30 Jun 2014 14:43:40 +0000 Original-Received: from localhost ([127.0.0.1]:38025 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1X1cnu-0001Be-QF for submit@debbugs.gnu.org; Mon, 30 Jun 2014 10:43:40 -0400 Original-Received: from mail-pa0-f45.google.com ([209.85.220.45]:52765) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1X1cnk-0001BJ-SA for 17854@debbugs.gnu.org; Mon, 30 Jun 2014 10:43:30 -0400 Original-Received: by mail-pa0-f45.google.com with SMTP id rd3so8746040pab.32 for <17854@debbugs.gnu.org>; Mon, 30 Jun 2014 07:43:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type; bh=+yuM2t61llNXydnCrN4BX7K3Vc597llJzPRj80Z0eHo=; b=KpV5+Tuh3ENCT6jLYEunGvNfC4kBI5O5SFKs5NoFt1n07iIrCuVTRVQ2vV19/2bm8f 3NoZK3vywwbaoXaSVAdu3tkt3qHPJOIMIp1f69+r4OLT0SLAApqNWk56phSU8H3KLJKn eE7uvad9bhQofBlvlPRoFgGK7zzkkLA2jRok2ARCVolYhDi3lt8+eIM2/WiNHm9ysIIP 8JxC2LCWtoRKwjbKI601zoe+cYpAQyEK1iPoLZrEM7/Sb4F58PFN9ozdCn92TqBBh9Rf wWHZa6CD9C1IeYM61dWcNVxZwFCnDgjyDnWM5mS0kTLLicLukfb7vnzq9Htf3rgJNdat RDsg== X-Received: by 10.67.16.67 with SMTP id fu3mr52906021pad.38.1404139398496; Mon, 30 Jun 2014 07:43:18 -0700 (PDT) Original-Received: by 10.70.89.165 with HTTP; Mon, 30 Jun 2014 07:42:37 -0700 (PDT) In-Reply-To: <75lhsh7qb8.fsf@fencepost.gnu.org> X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:91003 Archived-At: --001a1136505610053e04fd0eaeaf Content-Type: text/plain; charset=UTF-8 >I hope that the version you install will actually not change the >whitespace, rather than that just being hidden with diff -w. Sure, I will. However, my hideif modification was splitted into 3 patches and I already submitted 2 so I'll keep those white space changes that should went to the earlier 2 patches. I learnt this rule "no white space change alone" too late. For thosecodes that I did not touch I will keep the white spaces. Sorry about that. >> + :version "24.4") > >Why is the :version changing? >In any case, it is the wrong :version, since this won't be in 24.4. Isn't the Emacs trunk currently at version 24.4.XX.X? IIUC, according to the document of ":version" shouldn't this be the Emacs version that I introduced those variables? Since I consider the 3 patches as one so I use current version. >"This behavior is generally undesirable. If this option is non-nil, the >outermost #if is always visible." > >(I wonder: why would anyone want to set this option to nil?) IMHO usually don't, but I don't know if there will be cases that some header files are written as: #if XXXXXXXXXXX ... #elif YYYYYYYYY ... #elif ZZZZZZZZZZ ... #endif And each part is very long, maybe someone would like only one portion to be visible? If so, maybe making this variable a buffer local would make more sense? What do you think? >This would be better written as > >"\\.[hH]\\([hH]\\|[xX][xX]\\|[pP][pP]\\)?\\'" Thanks, followed >(why not just case-fold?) That variable is used only once in `hide-ifdef-guts' and it already bound case fold as nil with `let' (for matching lower-cased ifdef) so I use [hH] to match both cases. But, after a second thought since it is a customizable variable that users might forget about the upper/lower case so using case-fold could help users from making this kind of errors. So I change `hide-ifdef-guts' to use `let*' instead of `let' and bind `case-fold-search' twice once with `'t' for this and another with `nil' for lower-cased ifdef. >Also, you match it against buffer-name, which is fragile to things like >uniquify. Seems it would be better to match the file name. Great! I changed it to `buffer-file-name' instead. >> +(defun hif-clear-all-ifdef-defined () >> + "Clears all symbols defined in `hide-ifdef-env'. >... >Is that backup really necessary, given that you ask for confirmation? When we hide 10+ headers and save 5000 symbols in `hide-ifdef-env', it's really painful to clear it without saving it (I did that). Before I added my TODO: `automatically search for all header files using "#include"', I would like to have this backup there. Once we can have #include search works, it's okay to clear this variable without any backup. >Suggestion: >"With optional prefix agument ARG, also hide the #ifdefs themselves." >> (interactive) >> - (message "Hiding...") >> + (let ((hide-ifdef-lines current-prefix-arg)) > >I think this should take an explicit prefix argument. Originally, I followed, adding optional argument "arg" added and applied `interactive "P"'. Change all the callers to include one more argument. However, I need to keep the `current-prefix-arg' since locally I bind "C-c @ C-h" (compare with the default hide-ifdefs shortcut key "C-c @ h") for "strong-hide-ifdefs" to invoke hide-ifdefs with a prefix command automatically: (defun strong-hide-ifdefs () "Perform hideif-defs including the #ifdef themselves." (interactive) (let ((current-prefix-arg t)) (hide-ifdefs))) Thus, "C-u C-c @ h" or the shorter "C-c @ C-h" both works. If I use use ARG in the let binding of `hide-ifdefs', strong-hide-ifdefs won't work so I kept the `current-prefix-arg'. Therefore, 'arg' become an unused argument so I roll my code back. If you got better idea about how to implement things like `strong-hide-ifdefs', please tell me. Others might meet the same problem. >> +(defun hide-ifdef-block (&optional start end) >> + "Hide the ifdef block (true or false part) enclosing or before the cursor. >> +If prefixed, it will also hide #ifdefs themselves." > >Suggestion: >"With optional prefix agument ARG, also hide the #ifdefs themselves." It's nice but I can make it work with either `interactive "Pr"' or `interactive "rP" so I keep it unchanged. Also thanks for all those doc-string/comment corrections, I'm not a good English tech writer :-) Everything you suggested is great and I followed them all. The following is the new patch #3 in plain texts. Best regards, Luke Lee =========================================== diff --git a/lisp/progmodes/hideif.el b/lisp/progmodes/hideif.el index 6585668..713d330 100644 --- a/lisp/progmodes/hideif.el +++ b/lisp/progmodes/hideif.el @@ -138,7 +138,38 @@ (defcustom hide-ifdef-exclude-define-regexp nil "Ignore #define names if those names match this exclusion pattern." - :type 'string) + :type 'string + :version "24.4") + +(defcustom hide-ifdef-expand-reinclusion-protection t + "Non-nil means don't hide an entire header file enclused by #ifndef...#endif. +Most C/C++ headers are usually wrapped with ifdefs to prevent re-inclusion: + + ----- beginning of file ----- + #ifndef _XXX_HEADER_FILE_INCLUDED_ + #define _XXX_HEADER_FILE_INCLUDED_ + xxx + xxx + xxx... + #endif + ----- end of file ----- + +The first time we visit such a file, _XXX_HEADER_FILE_INCLUDED_ is +undefined, and so nothing is hidden. The next time we visit it, everything will +be hidden. + +This behavior is generally undesirable. If this option is non-nil, the outermost +#if is always visible." + :type 'boolean + :version "24.4") + +(defcustom hide-ifdef-header-regexp + "\\.h\\(h\\|xx\\|pp\\)?" + "C/C++ header file name patterns to determine if current buffer is a header. +Effective only if `hide-ifdef-expand-reinclusion-protection' is t." + :type 'string + :group 'hide-ifdef + :version "24.4") (defvar hide-ifdef-mode-submap ;; Set up the submap that goes after the prefix key. @@ -152,6 +183,8 @@ (define-key map "s" 'show-ifdefs) (define-key map "\C-d" 'hide-ifdef-block) (define-key map "\C-s" 'show-ifdef-block) + (define-key map "e" 'hif-evaluate-macro) + (define-key map "C" 'hif-clear-all-ifdef-defined) (define-key map "\C-q" 'hide-ifdef-toggle-read-only) (define-key map "\C-w" 'hide-ifdef-toggle-shadowing) @@ -216,6 +249,11 @@ (defvar hide-ifdef-env nil "An alist of defined symbols and their values.") +(defvar hide-ifdef-env-backup nil + "This variable is a backup of the previously cleared `hide-ifdef-env'. +This backup prevents any accidental clearance of `hide-fidef-env' by +`hif-clear-all-ifdef-defined'.") + (defvar hif-outside-read-only nil "Internal variable. Saves the value of `buffer-read-only' while hiding.") @@ -233,8 +271,12 @@ Several variables affect how the hiding is done: `hide-ifdef-env' An association list of defined and undefined symbols for the - current buffer. Initially, the global value of `hide-ifdef-env' - is used. + current project. Initially, the global value of `hide-ifdef-env' + is used. This variable was a buffer-local variable, which limits + hideif to parse only one C/C++ file at a time. We've extended + hideif to support parsing a C/C++ project containing multiple C/C++ + source files opened simultaneously in different buffers. Therefore + `hide-ifdef-env' can no longer be buffer local but must be global. `hide-ifdef-define-alist' An association list of defined symbol lists. @@ -259,8 +301,14 @@ Several variables affect how the hiding is done: (if hide-ifdef-mode (progn ;; inherit global values - (set (make-local-variable 'hide-ifdef-env) - (default-value 'hide-ifdef-env)) + + ;; `hide-ifdef-env' is now a global variable. + ;; We can still simulate the behavior of older hideif versions (i.e. + ;; `hide-ifdef-env' being buffer local) by clearing this variable + ;; (C-c @ C) everytime before hiding current buffer. +;; (set (make-local-variable 'hide-ifdef-env) +;; (default-value 'hide-ifdef-env)) + (set 'hide-ifdef-env (default-value 'hide-ifdef-env)) (set (make-local-variable 'hide-ifdef-hiding) (default-value 'hide-ifdef-hiding)) (set (make-local-variable 'hif-outside-read-only) buffer-read-only) @@ -279,6 +327,14 @@ Several variables affect how the hiding is done: (when hide-ifdef-hiding (show-ifdefs)))) +(defun hif-clear-all-ifdef-defined () + "Clears all symbols defined in `hide-ifdef-env'. +It will backup this variable to `hide-ifdef-env-backup' before clearing to +prevent accidental clearance." + (interactive) + (when (y-or-n-p "Clear all #defined symbols?") + (setq hide-ifdef-env-backup hide-ifdef-env) + (setq hide-ifdef-env nil))) (defun hif-show-all () "Show all of the text in the current buffer." @@ -298,16 +354,64 @@ Several variables affect how the hiding is done: (while (= (logand 1 (skip-chars-backward "\\\\")) 1) (end-of-line 2))) +(defun hif-merge-ifdef-region (start end) + "This function merges nearby ifdef regions to form a bigger overlay. +The region is defined by START and END. This will decrease the number of +overlays created." + ;; Generally there is no need to call itself recursively since there should + ;; originally exists no un-merged regions; however, if a part of the file is + ;; hidden with `hide-ifdef-lines' equals to nil while another part with 't, + ;; this case happens. + ;; TODO: Should we merge? or just create a container overlay? -- this can + ;; prevent `hideif-show-ifdef' expanding too many hidden contents since there + ;; is only a big overlay exists there without any smaller overlays. + (save-restriction + (widen) ; Otherwise `point-min' and `point-max' will be restricted and thus + ; fail to find neighbor overlays + (let ((begovrs (overlays-in + (max (- start 2) (point-min)) + (max (- start 1) (point-min)))) + (endovrs (overlays-in + (min (+ end 1) (point-max)) + (min (+ end 2) (point-max)))) + (ob nil) + (oe nil) + b e) + ;; Merge overlays before START + (dolist (o begovrs) + (when (overlay-get o 'hide-ifdef) + (setq b (min start (overlay-start o)) + e (max end (overlay-end o))) + (move-overlay o b e) + (hif-merge-ifdef-region b e) + (setq ob o))) + ;; Merge overlays after END + (dolist (o endovrs) + (when (overlay-get o 'hide-ifdef) + (setq b (min start (overlay-start o)) + e (max end (overlay-end o))) + (move-overlay o b e) + (hif-merge-ifdef-region b e) + (setf oe o))) + ;; If both START and END merging happens, merge into bigger one + (when (and ob oe) + (let ((b (min (overlay-start ob) (overlay-start oe))) + (e (max (overlay-end ob) (overlay-end oe)))) + (delete-overlay oe) + (move-overlay ob b e) + (hif-merge-ifdef-region b e))) + (or ob oe)))) + (defun hide-ifdef-region-internal (start end) - (remove-overlays start end 'hide-ifdef t) + (unless (hif-merge-ifdef-region start end) (let ((o (make-overlay start end))) (overlay-put o 'hide-ifdef t) (if hide-ifdef-shadow (overlay-put o 'face 'hide-ifdef-shadow) - (overlay-put o 'invisible 'hide-ifdef)))) + (overlay-put o 'invisible 'hide-ifdef))))) (defun hide-ifdef-region (start end) - "START is the start of a #if or #else form. END is the ending part. + "START is the start of a #if, #elif, or #else form. END is the ending part. Everything including these lines is made invisible." (save-excursion (goto-char start) (hif-end-of-line) (setq start (point)) @@ -316,7 +420,9 @@ Everything including these lines is made invisible." (defun hif-show-ifdef-region (start end) "Everything between START and END is made visible." - (remove-overlays start end 'hide-ifdef t)) + (let ((onum (length (overlays-in start end)))) + (remove-overlays start end 'hide-ifdef t) + (/= onum (length (overlays-in start end))))) ;;===%%SF%% evaluation (Start) === @@ -375,10 +481,8 @@ that form should be displayed.") (concat hif-cpp-prefix "\\(if\\(n?def\\)?\\|elif\\|define\\)[ \t]+")) (defconst hif-white-regexp "[ \t]*") -(defconst hif-define-regexp - (concat hif-cpp-prefix "\\(define\\|undef\\)")) -(defconst hif-id-regexp - (concat "[[:alpha:]_][[:alnum:]_]*")) +(defconst hif-define-regexp (concat hif-cpp-prefix "\\(define\\|undef\\)")) +(defconst hif-id-regexp (concat "[[:alpha:]_][[:alnum:]_]*")) (defconst hif-macroref-regexp (concat hif-white-regexp "\\(" hif-id-regexp "\\)" hif-white-regexp "\\(" @@ -499,6 +603,8 @@ that form should be displayed.") (setq hif-simple-token-only nil))) token-list))) + ((looking-at "\r") ; Sometimes MS-Windows user will leave CR in + (forward-char 1)) ; the source code. Let's not get stuck here. (t (error "Bad #if expression: %s" (buffer-string))))))) (nreverse token-list))) @@ -1173,13 +1279,16 @@ Do this when cursor is at the beginning of `regexp' (i.e. #ifX)." (if (= start (point)) (error "Mismatched #ifdef #endif pair"))) (cond ((hif-looking-at-endif) - (hif-endif-to-ifdef) ; find beginning of nested if - (hif-endif-to-ifdef)) ; find beginning of outer if or else + (hif-endif-to-ifdef) ; Find beginning of nested if + (hif-endif-to-ifdef)) ; Find beginning of outer if or else + ((hif-looking-at-elif) + (hif-endif-to-ifdef)) ((hif-looking-at-else) (hif-endif-to-ifdef)) ((hif-looking-at-ifX) 'done) - (t))) ; never gets here + (t + (error "Mismatched #endif")))) ; never gets here (defun forward-ifdef (&optional arg) @@ -1273,26 +1382,25 @@ With argument, do this that many times." ;;===%%SF%% hide-ifdef-hiding (Start) === -;;; A range is a structure with four components: -;;; ELSE-P True if there was an else clause for the ifdef. -;;; START The start of the range. (beginning of line) -;;; ELSE The else marker (beginning of line) -;;; Only valid if ELSE-P is true. -;;; END The end of the range. (beginning of line) +;; A range is a structure with four components: +;; START The start of the range. (beginning of line) +;; ELSE The else marker (beginning of line) +;; END The end of the range. (beginning of line) +;; ELIF A sequence of #elif markers (beginning of line) -(defsubst hif-make-range (start end &optional else) - (list start else end)) +(defsubst hif-make-range (start end &optional else elif) + (list start else end elif)) (defsubst hif-range-start (range) (elt range 0)) (defsubst hif-range-else (range) (elt range 1)) (defsubst hif-range-end (range) (elt range 2)) +(defsubst hif-range-elif (range) (elt range 3)) - -;;; Find-Range -;;; The workhorse, it delimits the #if region. Reasonably simple: -;;; Skip until an #else or #endif is found, remembering positions. If -;;; an #else was found, skip some more, looking for the true #endif. +;; Find-Range +;; The workhorse, it delimits the #if region. Reasonably simple: +;; Skip until an #else or #endif is found, remembering positions. If +;; an #else was found, skip some more, looking for the true #endif. (defun hif-find-range () "Return a Range structure describing the current #if region. @@ -1301,19 +1409,23 @@ Point is left unchanged." (save-excursion (beginning-of-line) (let ((start (point)) + (elif nil) (else nil) (end nil)) - ;; Part one. Look for either #endif or #else. + ;; Part one. Look for either #elif, #else or #endif. ;; This loop-and-a-half dedicated to E. Dijkstra. + (while (and (not else) (not end)) (while (progn (hif-find-next-relevant) (hif-looking-at-ifX)) ; Skip nested ifdef (hif-ifdef-to-endif)) - ;; Found either a #else or an #endif. - (cond ((hif-looking-at-else) + ;; Found either a #else, #elif, or an #endif. + (cond ((hif-looking-at-elif) + (setq elif (nconc elif (list (point))))) + ((hif-looking-at-else) (setq else (point))) (t - (setq end (point)))) ; (line-end-position) + (setq end (point))))) ;; If found #else, look for #endif. (when else (while (progn @@ -1323,7 +1435,7 @@ Point is left unchanged." (if (hif-looking-at-else) (error "Found two elses in a row? Broken!")) (setq end (point))) ; (line-end-position) - (hif-make-range start end else)))) + (hif-make-range start end else elif)))) ;; A bit slimy. @@ -1338,70 +1450,180 @@ Does nothing if `hide-ifdef-lines' is nil." (line-beginning-position) (progn (hif-end-of-line) (point)))))) -;;; Hif-Possibly-Hide -;;; There are four cases. The #ifX expression is "taken" if it -;;; the hide-ifdef-evaluator returns T. Presumably, this means the code -;;; inside the #ifdef would be included when the program was -;;; compiled. -;;; -;;; Case 1: #ifX taken, and there's an #else. -;;; The #else part must be hidden. The #if (then) part must be -;;; processed for nested #ifX's. -;;; Case 2: #ifX taken, and there's no #else. -;;; The #if part must be processed for nested #ifX's. -;;; Case 3: #ifX not taken, and there's an #else. -;;; The #if part must be hidden. The #else part must be processed -;;; for nested #ifs. -;;; Case 4: #ifX not taken, and there's no #else. -;;; The #ifX part must be hidden. -;;; -;;; Further processing is done by narrowing to the relevant region -;;; and just recursively calling hide-ifdef-guts. -;;; -;;; When hif-possibly-hide returns, point is at the end of the -;;; possibly-hidden range. - -(defun hif-recurse-on (start end) +;; Hif-Possibly-Hide +;; There are four cases. The #ifX expression is "taken" if it +;; the hide-ifdef-evaluator returns T. Presumably, this means the code +;; inside the #ifdef would be included when the program was +;; compiled. +;; +;; Case 1: #ifX taken, and there's an #else. +;; The #else part must be hidden. The #if (then) part must be +;; processed for nested #ifX's. +;; Case 2: #ifX taken, and there's no #else. +;; The #if part must be processed for nested #ifX's. +;; Case 3: #ifX not taken, and there's an #elif +;; The #if part must be hidden, and then evaluate +;; the #elif condition like a new #ifX. +;; Case 4: #ifX not taken, and there's just an #else. +;; The #if part must be hidden. The #else part must be processed +;; for nested #ifs. +;; Case 5: #ifX not taken, and there's no #else. +;; The #ifX part must be hidden. +;; +;; Further processing is done by narrowing to the relevant region +;; and just recursively calling hide-ifdef-guts. +;; +;; When hif-possibly-hide returns, point is at the end of the +;; possibly-hidden range. + +(defvar hif-recurse-level 0) + +(defun hif-recurse-on (start end &optional dont-go-eol) "Call `hide-ifdef-guts' after narrowing to end of START line and END line." (save-excursion (save-restriction (goto-char start) - (end-of-line) + (unless dont-go-eol + (end-of-line)) (narrow-to-region (point) end) - (hide-ifdef-guts)))) + (let ((hif-recurse-level (1+ hif-recurse-level))) + (hide-ifdef-guts))))) -(defun hif-possibly-hide () +(defun hif-possibly-hide (expand-reinclusion) "Called at #ifX expression, this hides those parts that should be hidden. -It uses the judgment of `hide-ifdef-evaluator'." +It uses the judgment of `hide-ifdef-evaluator'. EXPAND-REINCLUSION is a flag +indicating that we should expand the #ifdef even if it should be hidden. +Refer to `hide-ifdef-expand-reinclusion-protection' for more details." ;; (message "hif-possibly-hide") (sit-for 1) - (let ((test (hif-canonicalize hif-ifx-regexp)) - (range (hif-find-range))) + (let* ((case-fold-search nil) + (test (hif-canonicalize hif-ifx-regexp)) + (range (hif-find-range)) + (elifs (hif-range-elif range)) + (if-part t) ; Everytime we start from if-part + (complete nil)) ;; (message "test = %s" test) (sit-for 1) (hif-hide-line (hif-range-end range)) - (if (not (hif-not (funcall hide-ifdef-evaluator test))) - (cond ((hif-range-else range) ; case 1 + (while (not complete) + (if (and (not (and expand-reinclusion if-part)) + (hif-not (funcall hide-ifdef-evaluator test))) + ;; ifX/elif is FALSE + (if elifs + ;; Case 3 - Hide the #ifX and eval #elif + (let ((newstart (car elifs))) + (hif-hide-line (hif-range-start range)) + (hide-ifdef-region (hif-range-start range) + (1- newstart)) + (setcar range newstart) + (goto-char newstart) + (setq elifs (cdr elifs)) + (setq test (hif-canonicalize hif-elif-regexp))) + + ;; Check for #else + (cond ((hif-range-else range) + ;; Case 4 - #else block visible + (hif-hide-line (hif-range-else range)) + (hide-ifdef-region (hif-range-start range) + (1- (hif-range-else range))) + (hif-recurse-on (hif-range-else range) + (hif-range-end range))) + (t + ;; Case 5 - No #else block, hide #ifX + (hide-ifdef-region (point) + (1- (hif-range-end range))))) + (setq complete t)) + + ;; ifX/elif is TRUE + (cond (elifs + ;; Luke fix: distinguish from #elif..#elif to #elif..#else + (let ((elif (car elifs))) + ;; hide all elifs + (hif-hide-line elif) + (hide-ifdef-region elif (1- (hif-range-end range))) + (hif-recurse-on (hif-range-start range) + elif))) + ((hif-range-else range) + ;; Case 1 - Hide #elif and #else blocks, recurse #ifX (hif-hide-line (hif-range-else range)) (hide-ifdef-region (hif-range-else range) (1- (hif-range-end range))) (hif-recurse-on (hif-range-start range) (hif-range-else range))) - (t ; case 2 + (t + ;; Case 2 - No #else, just recurse #ifX (hif-recurse-on (hif-range-start range) (hif-range-end range)))) - (cond ((hif-range-else range) ; case 3 - (hif-hide-line (hif-range-else range)) - (hide-ifdef-region (hif-range-start range) - (1- (hif-range-else range))) - (hif-recurse-on (hif-range-else range) - (hif-range-end range))) - (t ; case 4 - (hide-ifdef-region (point) - (1- (hif-range-end range)))))) + (setq complete t)) + (setq if-part nil)) + + ;; complete = t (hif-hide-line (hif-range-start range)) ; Always hide start. (goto-char (hif-range-end range)) (end-of-line))) +(defun hif-evaluate-region (start end) + (let* ((tokens (ignore-errors ; Prevent C statement things like + ; 'do { ... } while (0)' + (hif-tokenize start end))) + (expr (and tokens + (condition-case nil + (hif-parse-exp tokens) + (error + tokens)))) + (result (funcall hide-ifdef-evaluator expr))) + result)) + +(defun hif-evaluate-macro (rstart rend) + "Evaluate the macro expansion result for a region. +If no region active, find the current #ifdefs and evaluate the result. +Currently it supports only math calculations, strings or argumented macros can +not be expanded." + (interactive "r") + (let ((case-fold-search nil)) + (save-excursion + (unless mark-active + (setq rstart nil rend nil) + (beginning-of-line) + (when (and (re-search-forward hif-macro-expr-prefix-regexp nil t) + (string= "define" (match-string 2))) + (re-search-forward hif-macroref-regexp nil t))) + (let* ((start (or rstart (point))) + (end (or rend (progn (hif-end-of-line) (point)))) + (defined nil) + (simple 't) + (tokens (ignore-errors ; Prevent C statement things like + ; 'do { ... } while (0)' + (hif-tokenize start end))) + (expr (or (and (<= (length tokens) 1) ; Simple token + (setq defined (assoc (car tokens) hide-ifdef-env)) + (setq simple (atom (hif-lookup (car tokens)))) + (hif-lookup (car tokens))) + (and tokens + (condition-case nil + (hif-parse-exp tokens) + (error + nil))))) + (result (funcall hide-ifdef-evaluator expr)) + (exprstring (replace-regexp-in-string + ;; Trim off leading/trailing whites + "^[ \t]*\\([^ \t]+\\)[ \t]*" "\\1" + (replace-regexp-in-string + "\\(//.*\\)" "" ; Trim off end-of-line comments + (buffer-substring-no-properties start end))))) + (cond + ((and (<= (length tokens) 1) simple) ; Simple token + (if defined + (message "%S <= `%s'" result exprstring) + (message "`%s' is not defined" exprstring))) + ((integerp result) + (if (or (= 0 result) (= 1 result)) + (message "%S <= `%s'" result exprstring) + (message "%S (0x%x) <= `%s'" result result exprstring))) + ((null result) (message "%S <= `%s'" 'false exprstring)) + ((eq t result) (message "%S <= `%s'" 'true exprstring)) + (t (message "%S <= `%s'" result exprstring))) + result)))) + (defun hif-parse-macro-arglist (str) "Parse argument list formatted as '( arg1 [ , argn] [...] )'. The '...' is also included. Return a list of the arguments, if '...' exists the @@ -1529,7 +1751,12 @@ first arg will be `hif-etc'." It does not do the work that's pointless to redo on a recursive entry." ;; (message "hide-ifdef-guts") (save-excursion - (let ((case-fold-search nil) + (let* ((case-fold-search t) ; Ignore case for `hide-ifdef-header-regexp' + (expand-header (and hide-ifdef-expand-reinclusion-protection + (string-match hide-ifdef-header-regexp + (buffer-file-name)) + (zerop hif-recurse-level))) + (case-fold-search nil) min max) (goto-char (point-min)) (setf min (point)) @@ -1537,7 +1764,7 @@ It does not do the work that's pointless to redo on a recursive entry." (setf max (hif-find-any-ifX)) (hif-add-new-defines min max) (if max - (hif-possibly-hide)) + (hif-possibly-hide expand-header)) (setf min (point)) while max)))) @@ -1584,17 +1811,30 @@ It does not do the work that's pointless to redo on a recursive entry." (overlay-put overlay 'face nil) (overlay-put overlay 'invisible 'hide-ifdef)))))) -(defun hide-ifdef-define (var) - "Define a VAR so that #ifdef VAR would be included." - (interactive "SDefine what? ") - (hif-set-var var 1) +(defun hide-ifdef-define (var &optional val) + "Define a VAR to VAL (DEFAULT 1) in `hide-ifdef-env'. +This allows #ifdef VAR to be hidden." + (interactive + (let* ((default (save-excursion + (beginning-of-line) + (cond ((looking-at hif-ifx-else-endif-regexp) + (forward-word 2) + (current-word 'strict)) + (t + nil)))) + (var (read-minibuffer "Define what? " default)) + (val (read-from-minibuffer (format "Set %s to? (default 1): " var) + nil nil t nil "1"))) + (list var val))) + (hif-set-var var (or val 1)) + (message "%s set to %s" var (or val 1)) + (sleep-for 1) (if hide-ifdef-hiding (hide-ifdefs))) (defun hif-undefine-symbol (var) (setq hide-ifdef-env (delete (assoc var hide-ifdef-env) hide-ifdef-env))) - (defun hide-ifdef-undef (start end) "Undefine a VAR so that #ifdef VAR would not be included." (interactive "r") @@ -1615,20 +1855,23 @@ It does not do the work that's pointless to redo on a recursive entry." Assume that defined symbols have been added to `hide-ifdef-env'. The text hidden is the text that would not be included by the C preprocessor if it were given the file with those symbols defined. +With prefix command presents it will also hide the #ifdefs themselves. Turn off hiding by calling `show-ifdefs'." (interactive) - (message "Hiding...") + (let ((hide-ifdef-lines current-prefix-arg)) + (or nomsg + (message "Hiding...")) (setq hif-outside-read-only buffer-read-only) - (unless hide-ifdef-mode (hide-ifdef-mode 1)) ; turn on hide-ifdef-mode + (unless hide-ifdef-mode (hide-ifdef-mode 1)) ; Turn on hide-ifdef-mode (if hide-ifdef-hiding (show-ifdefs)) ; Otherwise, deep confusion. (setq hide-ifdef-hiding t) (hide-ifdef-guts) (setq buffer-read-only (or hide-ifdef-read-only hif-outside-read-only)) (or nomsg - (message "Hiding done"))) + (message "Hiding done")))) (defun show-ifdefs () @@ -1660,9 +1903,15 @@ Return as (TOP . BOTTOM) the extent of ifdef block." (min max-bottom (1- (point))))))) -(defun hide-ifdef-block () - "Hide the ifdef block (true or false part) enclosing or before the cursor." - (interactive) +(defun hide-ifdef-block (&optional start end) + "Hide the ifdef block (true or false part) enclosing or before the cursor. +With prefix command presents it will also hide the #ifdefs themselves." + (interactive "r") + (let ((hide-ifdef-lines current-prefix-arg)) + (if mark-active + (let ((hif-recurse-level (1+ hif-recurse-level))) + (hif-recurse-on start end t) + (setq mark-active nil)) (unless hide-ifdef-mode (hide-ifdef-mode 1)) (let ((top-bottom (hif-find-ifdef-block))) (hide-ifdef-region (car top-bottom) (cdr top-bottom)) @@ -1670,12 +1919,26 @@ Return as (TOP . BOTTOM) the extent of ifdef block." (hif-hide-line (car top-bottom)) (hif-hide-line (1+ (cdr top-bottom)))) (setq hide-ifdef-hiding t)) - (setq buffer-read-only (or hide-ifdef-read-only hif-outside-read-only))) + (setq buffer-read-only + (or hide-ifdef-read-only hif-outside-read-only))))) -(defun show-ifdef-block () +(defun show-ifdef-block (&optional start end) "Show the ifdef block (true or false part) enclosing or before the cursor." - (interactive) - (let ((top-bottom (hif-find-ifdef-block))) + (interactive "r") + (if mark-active + (progn + (dolist (o (overlays-in start end)) + (if (overlay-get o 'hide-ifdef) + (delete-overlay o))) + (setq mark-active nil)) + (let ((top-bottom (condition-case nil + (hif-find-ifdef-block) + (error + nil))) + (ovrs (overlays-in (max (point-min) (1- (point))) + (min (point-max) (1+ (point))))) + (del nil)) + (if top-bottom (if hide-ifdef-lines (hif-show-ifdef-region (save-excursion @@ -1683,7 +1946,15 @@ Return as (TOP . BOTTOM) the extent of ifdef block." (save-excursion (goto-char (1+ (cdr top-bottom))) (hif-end-of-line) (point))) - (hif-show-ifdef-region (1- (car top-bottom)) (cdr top-bottom))))) + (setf del (hif-show-ifdef-region + (1- (car top-bottom)) (cdr top-bottom))))) + (if (not (and top-bottom + del)) + (dolist (o ovrs) + ;;(dolist (o (overlays-in (1- (point)) (1+ (point)))) + ;; (if (overlay-get o 'hide-ifdef) (message "%S" o))) + (if (overlay-get o 'hide-ifdef) + (delete-overlay o))))))) ;;; definition alist support --001a1136505610053e04fd0eaeaf Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+PGRpdj48ZGl2PjxkaXY+PGRpdj48ZGl2PjxkaXY+Jmd0O0kgaG9wZSB0 aGF0IHRoZSB2ZXJzaW9uIHlvdSBpbnN0YWxsIHdpbGwgYWN0dWFsbHkgbm90IGNoYW5nZSB0aGU8 YnI+Jmd0O3doaXRlc3BhY2UsIHJhdGhlciB0aGFuIHRoYXQganVzdCBiZWluZyBoaWRkZW4gd2l0 aCBkaWZmIC13Ljxicj4NCjxicj48L2Rpdj5TdXJlLCBJIHdpbGwuIEhvd2V2ZXIsIG15IGhpZGVp ZiBtb2RpZmljYXRpb24gd2FzIHNwbGl0dGVkIGludG8gMyA8YnI+cGF0Y2hlc8KgIGFuZCBJIGFs cmVhZHkgc3VibWl0dGVkIDIgc28gSSYjMzk7bGwga2VlcCB0aG9zZSB3aGl0ZSA8YnI+c3BhY2Ug Y2hhbmdlcyB0aGF0IHNob3VsZCB3ZW50IHRvIHRoZSBlYXJsaWVyIDIgcGF0Y2hlcy4gSSA8YnI+ bGVhcm50IHRoaXMgcnVsZSAmcXVvdDtubyB3aGl0ZSBzcGFjZSBjaGFuZ2UgYWxvbmUmcXVvdDsg dG9vIGxhdGUuIEZvciA8YnI+DQoNCnRob3NlY29kZXMgdGhhdCBJIGRpZCBub3QgdG91Y2ggSSB3 aWxsIGtlZXAgdGhlIHdoaXRlIHNwYWNlcy4gPGJyPlNvcnJ5IGFib3V0IHRoYXQuPGJyPjwvZGl2 PjwvZGl2Pjxicj4mZ3Q7Jmd0OyArIMKgOnZlcnNpb24gJnF1b3Q7MjQuNCZxdW90Oyk8YnI+DQom Z3Q7PGJyPiZndDtXaHkgaXMgdGhlIDp2ZXJzaW9uIGNoYW5naW5nPzxicj4mZ3Q7SW4gYW55IGNh c2UsIGl0IGlzIHRoZSB3cm9uZyA6dmVyc2lvbiwgc2luY2UgdGhpcyB3b24mIzM5O3QgYmUgaW4g MjQuNC48YnI+DQo8YnI+DQo8L2Rpdj5Jc24mIzM5O3QgdGhlIEVtYWNzIHRydW5rIGN1cnJlbnRs eSBhdCB2ZXJzaW9uIDI0LjQuWFguWD8gSUlVQywgPGJyPmFjY29yZGluZyB0byB0aGUgZG9jdW1l bnQgb2YgJnF1b3Q7OnZlcnNpb24mcXVvdDsgc2hvdWxkbiYjMzk7dCB0aGlzIGJlIHRoZTxicj48 L2Rpdj5FbWFjcyB2ZXJzaW9uIHRoYXQgSSBpbnRyb2R1Y2VkIHRob3NlIHZhcmlhYmxlcz8gU2lu Y2UgSSA8YnI+DQoNCg0KDQo8L2Rpdj48ZGl2PmNvbnNpZGVyIHRoZSAzIHBhdGNoZXMgYXMgb25l IHNvIEkgdXNlIGN1cnJlbnQgdmVyc2lvbi48YnI+PC9kaXY+PGRpdj48ZGl2PjxkaXY+PGRpdj48 ZGl2PjxkaXY+PGRpdj48ZGl2IGNsYXNzPSJnbWFpbF9leHRyYSI+PGJyPiZndDsmcXVvdDtUaGlz IGJlaGF2aW9yIGlzIGdlbmVyYWxseSB1bmRlc2lyYWJsZS4gwqBJZiB0aGlzIG9wdGlvbiBpcyBu b24tbmlsLCB0aGU8YnI+DQoNCg0KDQomZ3Q7b3V0ZXJtb3N0ICNpZiBpcyBhbHdheXMgdmlzaWJs ZS4mcXVvdDs8YnI+Jmd0Ozxicj4NCiZndDsoSSB3b25kZXI6IHdoeSB3b3VsZCBhbnlvbmUgd2Fu dCB0byBzZXQgdGhpcyBvcHRpb24gdG8gbmlsPyk8YnI+DQo8YnI+PC9kaXY+PGRpdiBjbGFzcz0i Z21haWxfZXh0cmEiPklNSE8gdXN1YWxseSBkb24mIzM5O3QsIGJ1dCBJIGRvbiYjMzk7dCBrbm93 IGlmIHRoZXJlIHdpbGwgYmUgY2FzZXMgdGhhdDxicj48L2Rpdj48ZGl2IGNsYXNzPSJnbWFpbF9l eHRyYSI+c29tZSBoZWFkZXIgZmlsZXMgYXJlIHdyaXR0ZW4gYXM6PGJyPjxicj48L2Rpdj48ZGl2 IGNsYXNzPSJnbWFpbF9leHRyYSI+I2lmIFhYWFhYWFhYWFhYPGJyPg0KDQoNCg0KLi4uPGJyPjwv ZGl2PjxkaXYgY2xhc3M9ImdtYWlsX2V4dHJhIj4jZWxpZiBZWVlZWVlZWVk8YnI+Li4uPGJyPjwv ZGl2PjxkaXYgY2xhc3M9ImdtYWlsX2V4dHJhIj4jZWxpZiBaWlpaWlpaWlpaPGJyPi4uLjxicj48 L2Rpdj48ZGl2IGNsYXNzPSJnbWFpbF9leHRyYSI+I2VuZGlmPGJyPjxicj48L2Rpdj48ZGl2IGNs YXNzPSJnbWFpbF9leHRyYSI+QW5kIGVhY2ggcGFydCBpcyB2ZXJ5IGxvbmcsIG1heWJlIHNvbWVv bmUgd291bGQgbGlrZSBvbmx5IG9uZTxicj4NCg0KDQoNCjwvZGl2PjxkaXYgY2xhc3M9ImdtYWls X2V4dHJhIj5wb3J0aW9uIHRvIGJlIHZpc2libGU/IElmIHNvLCBtYXliZSBtYWtpbmcgdGhpcyB2 YXJpYWJsZSBhIGJ1ZmZlciA8YnI+bG9jYWwgd291bGQgbWFrZSBtb3JlIHNlbnNlPyBXaGF0IGRv IHlvdSB0aGluaz88YnI+PC9kaXY+PGRpdiBjbGFzcz0iZ21haWxfZXh0cmEiPjxicj4mZ3Q7VGhp cyB3b3VsZCBiZSBiZXR0ZXIgd3JpdHRlbiBhczxicj4NCg0KDQoNCg0KJmd0Ozxicj4mZ3Q7JnF1 b3Q7XFwuW2hIXVxcKFtoSF1cXHxbeFhdW3hYXVxcfFtwUF1bcFBdXFwpP1xcJiMzOTsmcXVvdDs8 YnI+PGJyPlRoYW5rcywgZm9sbG93ZWQ8YnI+PGJyPiZndDsod2h5IG5vdCBqdXN0IGNhc2UtZm9s ZD8pPGJyPjxicj48L2Rpdj48ZGl2IGNsYXNzPSJnbWFpbF9leHRyYSI+VGhhdCB2YXJpYWJsZSBp cyB1c2VkIG9ubHkgb25jZSBpbiBgaGlkZS1pZmRlZi1ndXRzJiMzOTsgYW5kIGl0IGFscmVhZHk8 YnI+DQoNCg0KDQo8L2Rpdj48ZGl2IGNsYXNzPSJnbWFpbF9leHRyYSI+Ym91bmQgY2FzZSBmb2xk IGFzIG5pbCB3aXRoIGBsZXQmIzM5OyAoZm9yIG1hdGNoaW5nIGxvd2VyLWNhc2VkIGlmZGVmKSA8 YnI+c28gSSB1c2UgW2hIXSB0byBtYXRjaCBib3RoIGNhc2VzLiA8YnI+PGJyPkJ1dCwgYWZ0ZXIg YSBzZWNvbmQgdGhvdWdodCBzaW5jZSBpdCBpcyBhIGN1c3RvbWl6YWJsZTxicj52YXJpYWJsZSB0 aGF0IHVzZXJzIG1pZ2h0IGZvcmdldCBhYm91dCB0aGUgdXBwZXIvbG93ZXIgY2FzZSA8YnI+DQoN Cg0KDQpzbyB1c2luZyBjYXNlLWZvbGQgY291bGQgaGVscCB1c2VycyBmcm9tIG1ha2luZyB0aGlz IGtpbmQgb2Y8YnI+ZXJyb3JzLiBTbyBJIGNoYW5nZSBgaGlkZS1pZmRlZi1ndXRzJiMzOTsgdG8g dXNlIGBsZXQqJiMzOTsgaW5zdGVhZCBvZiA8YnI+PC9kaXY+PGRpdiBjbGFzcz0iZ21haWxfZXh0 cmEiPmBsZXQmIzM5OyBhbmQgYmluZCBgY2FzZS1mb2xkLXNlYXJjaCYjMzk7IHR3aWNlIG9uY2Ug d2l0aCBgJiMzOTt0JiMzOTsgZm9yIHRoaXM8YnI+DQoNCg0KDQphbmQgYW5vdGhlciB3aXRoIGBu aWwmIzM5OyBmb3IgbG93ZXItY2FzZWQgaWZkZWYuPGJyPjxicj4mZ3Q7QWxzbywgeW91IG1hdGNo IGl0IGFnYWluc3QgYnVmZmVyLW5hbWUsIHdoaWNoIGlzIGZyYWdpbGUgdG8gdGhpbmdzIGxpa2U8 YnI+Jmd0O3VuaXF1aWZ5LiBTZWVtcyBpdCB3b3VsZCBiZSBiZXR0ZXIgdG8gbWF0Y2ggdGhlIGZp bGUgbmFtZS48YnI+PGJyPjwvZGl2PjxkaXYgY2xhc3M9ImdtYWlsX2V4dHJhIj4NCg0KDQoNCkdy ZWF0ISBJIGNoYW5nZWQgaXQgdG8gYGJ1ZmZlci1maWxlLW5hbWUmIzM5OyBpbnN0ZWFkLjxicj48 L2Rpdj48ZGl2IGNsYXNzPSJnbWFpbF9leHRyYSI+PGJyPiZndDsmZ3Q7ICsoZGVmdW4gaGlmLWNs ZWFyLWFsbC1pZmRlZi1kZWZpbmVkICgpPGJyPiZndDsmZ3Q7ICsgwqAmcXVvdDtDbGVhcnMgYWxs IHN5bWJvbHMgZGVmaW5lZCBpbiBgaGlkZS1pZmRlZi1lbnYmIzM5Oy48YnI+Jmd0Oy4uLjxicj4N Cg0KDQoNCiZndDtJcyB0aGF0IGJhY2t1cCByZWFsbHkgbmVjZXNzYXJ5LCBnaXZlbiB0aGF0IHlv dSBhc2sgZm9yIGNvbmZpcm1hdGlvbj88YnI+PGJyPjwvZGl2PjxkaXYgY2xhc3M9ImdtYWlsX2V4 dHJhIj5XaGVuIHdlIGhpZGUgMTArIGhlYWRlcnMgYW5kIHNhdmUgNTAwMCBzeW1ib2xzIGluIGBo aWRlLWlmZGVmLWVudiYjMzk7LDxicj48L2Rpdj48ZGl2IGNsYXNzPSJnbWFpbF9leHRyYSI+aXQm IzM5O3MgcmVhbGx5IHBhaW5mdWwgdG8gY2xlYXIgaXQgd2l0aG91dCBzYXZpbmcgaXQgKEkgZGlk IHRoYXQpLiBCZWZvcmUgSSBhZGRlZCA8YnI+DQoNCg0KDQpteSBUT0RPOiBgYXV0b21hdGljYWxs eSBzZWFyY2ggZm9yIGFsbCBoZWFkZXIgZmlsZXMgdXNpbmcgJnF1b3Q7I2luY2x1ZGUmcXVvdDsm IzM5OywgPGJyPkkgd291bGQgbGlrZSB0byBoYXZlIHRoaXMgYmFja3VwIHRoZXJlLiBPbmNlIHdl IGNhbiBoYXZlICNpbmNsdWRlPGJyPjwvZGl2PjxkaXYgY2xhc3M9ImdtYWlsX2V4dHJhIj5zZWFy Y2ggd29ya3MsIGl0JiMzOTtzIG9rYXkgdG8gY2xlYXIgdGhpcyB2YXJpYWJsZSB3aXRob3V0IGFu eSBiYWNrdXAuPGJyPg0KDQoNCg0KPC9kaXY+PGRpdiBjbGFzcz0iZ21haWxfZXh0cmEiPjxicj4m Z3Q7U3VnZ2VzdGlvbjo8YnI+Jmd0OyZxdW90O1dpdGggb3B0aW9uYWwgcHJlZml4IGFndW1lbnQg QVJHLCBhbHNvIGhpZGUgdGhlICNpZmRlZnMgdGhlbXNlbHZlcy4mcXVvdDs8YnI+Jmd0OyZndDsg wqAgwqAoaW50ZXJhY3RpdmUpPGJyPiZndDsmZ3Q7IC0gwqAobWVzc2FnZSAmcXVvdDtIaWRpbmcu Li4mcXVvdDspPGJyPiZndDsmZ3Q7ICsgwqAobGV0ICgoaGlkZS1pZmRlZi1saW5lcyBjdXJyZW50 LXByZWZpeC1hcmcpKTxicj4NCg0KDQoNCiZndDs8YnI+Jmd0O0kgdGhpbmsgdGhpcyBzaG91bGQg dGFrZSBhbiBleHBsaWNpdCBwcmVmaXggYXJndW1lbnQuPGJyPg0KPGJyPjxkaXYgY2xhc3M9Imdt YWlsX2V4dHJhIj5PcmlnaW5hbGx5LCBJIGZvbGxvd2VkLCBhZGRpbmcgb3B0aW9uYWwgYXJndW1l bnQgJnF1b3Q7YXJnJnF1b3Q7IGFkZGVkIDxicj5hbmQgYXBwbGllZCBgaW50ZXJhY3RpdmUgJnF1 b3Q7UCZxdW90OyYjMzk7LiBDaGFuZ2UgYWxsIHRoZSBjYWxsZXJzIHRvIGluY2x1ZGU8YnI+b25l IG1vcmUgYXJndW1lbnQuPGJyPkhvd2V2ZXIsIEkgbmVlZCB0byBrZWVwIHRoZSBgY3VycmVudC1w cmVmaXgtYXJnJiMzOTsgc2luY2UgbG9jYWxseSBJIGJpbmQgPGJyPg0KDQoNCjwvZGl2PjwvZGl2 PjxkaXYgY2xhc3M9ImdtYWlsX2V4dHJhIj4mcXVvdDtDLWMgQCBDLWgmcXVvdDsgKGNvbXBhcmUg d2l0aCB0aGUgZGVmYXVsdCBoaWRlLWlmZGVmcyBzaG9ydGN1dCBrZXk8YnI+JnF1b3Q7Qy1jIEAg aCZxdW90OykgZm9yICZxdW90O3N0cm9uZy1oaWRlLWlmZGVmcyZxdW90OyB0byBpbnZva2UgaGlk ZS1pZmRlZnMgd2l0aCBhIHByZWZpeDxicj5jb21tYW5kIGF1dG9tYXRpY2FsbHk6PGJyPg0KDQoN Cjxicj4oZGVmdW4gc3Ryb25nLWhpZGUtaWZkZWZzICgpPGJyPsKgICZxdW90O1BlcmZvcm0gaGlk ZWlmLWRlZnMgaW5jbHVkaW5nIHRoZSAjaWZkZWYgdGhlbXNlbHZlcy4mcXVvdDs8YnI+wqAgKGlu dGVyYWN0aXZlKTxicj7CoCAobGV0ICgoY3VycmVudC1wcmVmaXgtYXJnIHQpKTxicj7CoMKgwqAg KGhpZGUtaWZkZWZzKSkpPGJyPjxicj48L2Rpdj48ZGl2IGNsYXNzPSJnbWFpbF9leHRyYSI+VGh1 cywgJnF1b3Q7Qy11IEMtYyBAIGgmcXVvdDsgb3IgdGhlIHNob3J0ZXIgJnF1b3Q7Qy1jIEAgQy1o JnF1b3Q7IGJvdGggd29ya3MuPGJyPg0KDQoNCjwvZGl2PjxkaXYgY2xhc3M9ImdtYWlsX2V4dHJh Ij48L2Rpdj48ZGl2IGNsYXNzPSJnbWFpbF9leHRyYSI+SWYgSSB1c2UgdXNlIEFSRyBpbiB0aGUg bGV0IGJpbmRpbmcgb2YgYGhpZGUtaWZkZWZzJiMzOTssIHN0cm9uZy1oaWRlLWlmZGVmczxicj53 b24mIzM5O3Qgd29yayBzbyBJIGtlcHQgdGhlIGBjdXJyZW50LXByZWZpeC1hcmcmIzM5Oy4gVGhl cmVmb3JlLCAmIzM5O2FyZyYjMzk7IGJlY29tZTxicj4NCg0KDQphbiB1bnVzZWQgYXJndW1lbnQg c28gSSByb2xsIG15IGNvZGUgYmFjay4gSWYgeW91IGdvdCBiZXR0ZXIgaWRlYTxicj48L2Rpdj48 ZGl2IGNsYXNzPSJnbWFpbF9leHRyYSI+YWJvdXQgaG93IHRvIGltcGxlbWVudCB0aGluZ3MgbGlr ZSBgc3Ryb25nLWhpZGUtaWZkZWZzJiMzOTssIHBsZWFzZSB0ZWxsIDxicj5tZS4gT3RoZXJzIG1p Z2h0IG1lZXQgdGhlIHNhbWUgcHJvYmxlbS48YnI+DQoNCjwvZGl2Pg0KPGRpdiBjbGFzcz0iZ21h aWxfZXh0cmEiPjxicj4mZ3Q7Jmd0OyArKGRlZnVuIGhpZGUtaWZkZWYtYmxvY2sgKCZhbXA7b3B0 aW9uYWwgc3RhcnQgZW5kKTxicj4mZ3Q7Jmd0OyArIMKgJnF1b3Q7SGlkZSB0aGUgaWZkZWYgYmxv Y2sgKHRydWUgb3IgZmFsc2UgcGFydCkgZW5jbG9zaW5nIG9yIGJlZm9yZSB0aGUgY3Vyc29yLjxi cj4mZ3Q7Jmd0OyArSWYgcHJlZml4ZWQsIGl0IHdpbGwgYWxzbyBoaWRlICNpZmRlZnMgdGhlbXNl bHZlcy4mcXVvdDs8YnI+DQoNCg0KDQomZ3Q7PGJyPiZndDtTdWdnZXN0aW9uOjxicj4mZ3Q7JnF1 b3Q7V2l0aCBvcHRpb25hbCBwcmVmaXggYWd1bWVudCBBUkcsIGFsc28gaGlkZSB0aGUgI2lmZGVm cyB0aGVtc2VsdmVzLiZxdW90Ozxicj4NCjxicj48L2Rpdj48ZGl2IGNsYXNzPSJnbWFpbF9leHRy YSI+SXQmIzM5O3MgbmljZSBidXQgSSBjYW4gbWFrZSBpdCB3b3JrIHdpdGggZWl0aGVyIGBpbnRl cmFjdGl2ZSAmcXVvdDtQciZxdW90OyYjMzk7IG9yIDxicj5gaW50ZXJhY3RpdmUgJnF1b3Q7clAm cXVvdDsgc28gSSBrZWVwIGl0IHVuY2hhbmdlZC48YnI+PC9kaXY+PGRpdiBjbGFzcz0iZ21haWxf ZXh0cmEiPjxicj5BbHNvIHRoYW5rcyBmb3IgYWxsIHRob3NlIGRvYy1zdHJpbmcvY29tbWVudCBj b3JyZWN0aW9ucywgSSYjMzk7bSBub3QgYSA8YnI+DQoNCg0KDQpnb29kIEVuZ2xpc2ggdGVjaCB3 cml0ZXIgOi0pIEV2ZXJ5dGhpbmcgeW91IHN1Z2dlc3RlZCBpcyBncmVhdCA8YnI+YW5kIEkgZm9s bG93ZWQgdGhlbSBhbGwuwqAgVGhlIGZvbGxvd2luZyBpcyB0aGUgbmV3IHBhdGNoICMzIGluPGJy PjwvZGl2PjxkaXYgY2xhc3M9ImdtYWlsX2V4dHJhIj5wbGFpbiB0ZXh0cy48YnI+PC9kaXY+PGRp diBjbGFzcz0iZ21haWxfZXh0cmEiPjxicj48L2Rpdj4NCg0KDQoNCjxkaXYgY2xhc3M9ImdtYWls X2V4dHJhIj5CZXN0IHJlZ2FyZHMsPGJyPjwvZGl2PjxkaXYgY2xhc3M9ImdtYWlsX2V4dHJhIj5M dWtlIExlZTxicj48YnI+PGJyPj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT08YnI+PGJyPjxicj5kaWZmIC0tZ2l0IGEvbGlzcC9wcm9nbW9kZXMvaGlkZWlmLmVsIGIv bGlzcC9wcm9nbW9kZXMvaGlkZWlmLmVsPGJyPmluZGV4IDY1ODU2NjguLjcxM2QzMzAgMTAwNjQ0 PGJyPg0KDQoNCi0tLSBhL2xpc3AvcHJvZ21vZGVzL2hpZGVpZi5lbDxicj4rKysgYi9saXNwL3By b2dtb2Rlcy9oaWRlaWYuZWw8YnI+QEAgLTEzOCw3ICsxMzgsMzggQEA8YnI+wqA8YnI+wqAoZGVm Y3VzdG9tIGhpZGUtaWZkZWYtZXhjbHVkZS1kZWZpbmUtcmVnZXhwIG5pbDxicj7CoMKgICZxdW90 O0lnbm9yZSAjZGVmaW5lIG5hbWVzIGlmIHRob3NlIG5hbWVzIG1hdGNoIHRoaXMgZXhjbHVzaW9u IHBhdHRlcm4uJnF1b3Q7PGJyPg0KDQoNCi3CoCA6dHlwZSAmIzM5O3N0cmluZyk8YnI+K8KgIDp0 eXBlICYjMzk7c3RyaW5nPGJyPivCoCA6dmVyc2lvbiAmcXVvdDsyNC40JnF1b3Q7KTxicj4rPGJy PisoZGVmY3VzdG9tIGhpZGUtaWZkZWYtZXhwYW5kLXJlaW5jbHVzaW9uLXByb3RlY3Rpb24gdDxi cj4rwqAgJnF1b3Q7Tm9uLW5pbCBtZWFucyBkb24mIzM5O3QgaGlkZSBhbiBlbnRpcmUgaGVhZGVy IGZpbGUgZW5jbHVzZWQgYnkgI2lmbmRlZi4uLiNlbmRpZi48YnI+DQoNCg0KK01vc3QgQy9DKysg aGVhZGVycyBhcmUgdXN1YWxseSB3cmFwcGVkIHdpdGggaWZkZWZzIHRvIHByZXZlbnQgcmUtaW5j bHVzaW9uOjxicj4rPGJyPivCoCAtLS0tLSBiZWdpbm5pbmcgb2YgZmlsZSAtLS0tLTxicj4rwqAg I2lmbmRlZiBfWFhYX0hFQURFUl9GSUxFX0lOQ0xVREVEXzxicj4rwqAgI2RlZmluZSBfWFhYX0hF QURFUl9GSUxFX0lOQ0xVREVEXzxicj4rwqDCoMKgwqAgeHh4PGJyPivCoMKgwqDCoCB4eHg8YnI+ DQoNCg0KK8KgwqDCoMKgIHh4eC4uLjxicj4rwqAgI2VuZGlmPGJyPivCoCAtLS0tLSBlbmQgb2Yg ZmlsZSAtLS0tLTxicj4rPGJyPitUaGUgZmlyc3QgdGltZSB3ZSB2aXNpdCBzdWNoIGEgZmlsZSwg X1hYWF9IRUFERVJfRklMRV9JTkNMVURFRF8gaXM8YnI+K3VuZGVmaW5lZCwgYW5kIHNvIG5vdGhp bmcgaXMgaGlkZGVuLiBUaGUgbmV4dCB0aW1lIHdlIHZpc2l0IGl0LCBldmVyeXRoaW5nIHdpbGw8 YnI+K2JlIGhpZGRlbi48YnI+DQoNCg0KKzxicj4rVGhpcyBiZWhhdmlvciBpcyBnZW5lcmFsbHkg dW5kZXNpcmFibGUuIElmIHRoaXMgb3B0aW9uIGlzIG5vbi1uaWwsIHRoZSBvdXRlcm1vc3Q8YnI+ KyNpZiBpcyBhbHdheXMgdmlzaWJsZS4mcXVvdDs8YnI+K8KgIDp0eXBlICYjMzk7Ym9vbGVhbjxi cj4rwqAgOnZlcnNpb24gJnF1b3Q7MjQuNCZxdW90Oyk8YnI+Kzxicj4rKGRlZmN1c3RvbSBoaWRl LWlmZGVmLWhlYWRlci1yZWdleHA8YnI+DQoNCg0KK8KgICZxdW90O1xcLmhcXChoXFx8eHhcXHxw cFxcKT8mcXVvdDs8YnI+K8KgICZxdW90O0MvQysrIGhlYWRlciBmaWxlIG5hbWUgcGF0dGVybnMg dG8gZGV0ZXJtaW5lIGlmIGN1cnJlbnQgYnVmZmVyIGlzIGEgaGVhZGVyLjxicj4rRWZmZWN0aXZl IG9ubHkgaWYgYGhpZGUtaWZkZWYtZXhwYW5kLXJlaW5jbHVzaW9uLXByb3RlY3Rpb24mIzM5OyBp cyB0LiZxdW90Ozxicj4rwqAgOnR5cGUgJiMzOTtzdHJpbmc8YnI+DQoNCg0KK8KgIDpncm91cCAm IzM5O2hpZGUtaWZkZWY8YnI+K8KgIDp2ZXJzaW9uICZxdW90OzI0LjQmcXVvdDspPGJyPsKgPGJy PsKgKGRlZnZhciBoaWRlLWlmZGVmLW1vZGUtc3VibWFwPGJyPsKgwqAgOzsgU2V0IHVwIHRoZSBz dWJtYXAgdGhhdCBnb2VzIGFmdGVyIHRoZSBwcmVmaXgga2V5Ljxicj5AQCAtMTUyLDYgKzE4Myw4 IEBAPGJyPsKgwqDCoMKgIChkZWZpbmUta2V5IG1hcCAmcXVvdDtzJnF1b3Q7ICYjMzk7c2hvdy1p ZmRlZnMpPGJyPg0KDQoNCsKgwqDCoMKgIChkZWZpbmUta2V5IG1hcCAmcXVvdDtcQy1kJnF1b3Q7 ICYjMzk7aGlkZS1pZmRlZi1ibG9jayk8YnI+wqDCoMKgwqAgKGRlZmluZS1rZXkgbWFwICZxdW90 O1xDLXMmcXVvdDsgJiMzOTtzaG93LWlmZGVmLWJsb2NrKTxicj4rwqDCoMKgIChkZWZpbmUta2V5 IG1hcCAmcXVvdDtlJnF1b3Q7ICYjMzk7aGlmLWV2YWx1YXRlLW1hY3JvKTxicj4rwqDCoMKgIChk ZWZpbmUta2V5IG1hcCAmcXVvdDtDJnF1b3Q7ICYjMzk7aGlmLWNsZWFyLWFsbC1pZmRlZi1kZWZp bmVkKTxicj4NCg0KDQrCoDxicj7CoMKgwqDCoCAoZGVmaW5lLWtleSBtYXAgJnF1b3Q7XEMtcSZx dW90OyAmIzM5O2hpZGUtaWZkZWYtdG9nZ2xlLXJlYWQtb25seSk8YnI+wqDCoMKgwqAgKGRlZmlu ZS1rZXkgbWFwICZxdW90O1xDLXcmcXVvdDsgJiMzOTtoaWRlLWlmZGVmLXRvZ2dsZS1zaGFkb3dp bmcpPGJyPkBAIC0yMTYsNiArMjQ5LDExIEBAPGJyPsKgKGRlZnZhciBoaWRlLWlmZGVmLWVudiBu aWw8YnI+wqDCoCAmcXVvdDtBbiBhbGlzdCBvZiBkZWZpbmVkIHN5bWJvbHMgYW5kIHRoZWlyIHZh bHVlcy4mcXVvdDspPGJyPg0KDQoNCsKgPGJyPisoZGVmdmFyIGhpZGUtaWZkZWYtZW52LWJhY2t1 cCBuaWw8YnI+K8KgICZxdW90O1RoaXMgdmFyaWFibGUgaXMgYSBiYWNrdXAgb2YgdGhlIHByZXZp b3VzbHkgY2xlYXJlZCBgaGlkZS1pZmRlZi1lbnYmIzM5Oy48YnI+K1RoaXMgYmFja3VwIHByZXZl bnRzIGFueSBhY2NpZGVudGFsIGNsZWFyYW5jZSBvZiBgaGlkZS1maWRlZi1lbnYmIzM5OyBieTxi cj4rYGhpZi1jbGVhci1hbGwtaWZkZWYtZGVmaW5lZCYjMzk7LiZxdW90Oyk8YnI+DQoNCg0KKzxi cj7CoChkZWZ2YXIgaGlmLW91dHNpZGUtcmVhZC1vbmx5IG5pbDxicj7CoMKgICZxdW90O0ludGVy bmFsIHZhcmlhYmxlLsKgIFNhdmVzIHRoZSB2YWx1ZSBvZiBgYnVmZmVyLXJlYWQtb25seSYjMzk7 IHdoaWxlIGhpZGluZy4mcXVvdDspPGJyPsKgPGJyPkBAIC0yMzMsOCArMjcxLDEyIEBAIFNldmVy YWwgdmFyaWFibGVzIGFmZmVjdCBob3cgdGhlIGhpZGluZyBpcyBkb25lOjxicj7CoDxicj4NCg0K DQrCoGBoaWRlLWlmZGVmLWVudiYjMzk7PGJyPsKgwqDCoMKgwqDCoMKgwqAgQW4gYXNzb2NpYXRp b24gbGlzdCBvZiBkZWZpbmVkIGFuZCB1bmRlZmluZWQgc3ltYm9scyBmb3IgdGhlPGJyPi3CoMKg wqAgY3VycmVudCBidWZmZXIuwqAgSW5pdGlhbGx5LCB0aGUgZ2xvYmFsIHZhbHVlIG9mIGBoaWRl LWlmZGVmLWVudiYjMzk7PGJyPi3CoMKgwqAgaXMgdXNlZC48YnI+K8KgwqDCoMKgwqDCoMKgIGN1 cnJlbnQgcHJvamVjdC7CoCBJbml0aWFsbHksIHRoZSBnbG9iYWwgdmFsdWUgb2YgYGhpZGUtaWZk ZWYtZW52JiMzOTs8YnI+DQoNCg0KK8KgwqDCoMKgwqDCoMKgIGlzIHVzZWQuwqAgVGhpcyB2YXJp YWJsZSB3YXMgYSBidWZmZXItbG9jYWwgdmFyaWFibGUsIHdoaWNoIGxpbWl0czxicj4rwqDCoMKg wqDCoMKgwqAgaGlkZWlmIHRvIHBhcnNlIG9ubHkgb25lIEMvQysrIGZpbGUgYXQgYSB0aW1lLsKg IFdlJiMzOTt2ZSBleHRlbmRlZDxicj4rwqDCoMKgwqDCoMKgwqAgaGlkZWlmIHRvIHN1cHBvcnQg cGFyc2luZyBhIEMvQysrIHByb2plY3QgY29udGFpbmluZyBtdWx0aXBsZSBDL0MrKzxicj4NCg0K DQorwqDCoMKgwqDCoMKgwqAgc291cmNlIGZpbGVzIG9wZW5lZCBzaW11bHRhbmVvdXNseSBpbiBk aWZmZXJlbnQgYnVmZmVycy7CoCBUaGVyZWZvcmU8YnI+K8KgwqDCoMKgwqDCoMKgIGBoaWRlLWlm ZGVmLWVudiYjMzk7IGNhbiBubyBsb25nZXIgYmUgYnVmZmVyIGxvY2FsIGJ1dCBtdXN0IGJlIGds b2JhbC48YnI+wqA8YnI+wqBgaGlkZS1pZmRlZi1kZWZpbmUtYWxpc3QmIzM5Ozxicj7CoMKgwqDC oMKgwqDCoMKgIEFuIGFzc29jaWF0aW9uIGxpc3Qgb2YgZGVmaW5lZCBzeW1ib2wgbGlzdHMuPGJy Pg0KDQoNCkBAIC0yNTksOCArMzAxLDE0IEBAIFNldmVyYWwgdmFyaWFibGVzIGFmZmVjdCBob3cg dGhlIGhpZGluZyBpcyBkb25lOjxicj7CoMKgIChpZiBoaWRlLWlmZGVmLW1vZGU8YnI+wqDCoMKg wqDCoMKgIChwcm9nbjxicj7CoMKgwqDCoMKgwqDCoMKgIDs7IGluaGVyaXQgZ2xvYmFsIHZhbHVl czxicj4twqDCoMKgIChzZXQgKG1ha2UtbG9jYWwtdmFyaWFibGUgJiMzOTtoaWRlLWlmZGVmLWVu dik8YnI+LcKgwqDCoCDCoMKgwqDCoCAoZGVmYXVsdC12YWx1ZSAmIzM5O2hpZGUtaWZkZWYtZW52 KSk8YnI+DQoNCg0KKzxicj4rwqDCoMKgwqDCoMKgwqAgOzsgYGhpZGUtaWZkZWYtZW52JiMzOTsg aXMgbm93IGEgZ2xvYmFsIHZhcmlhYmxlLjxicj4rwqDCoMKgwqDCoMKgwqAgOzsgV2UgY2FuIHN0 aWxsIHNpbXVsYXRlIHRoZSBiZWhhdmlvciBvZiBvbGRlciBoaWRlaWYgdmVyc2lvbnMgKGkuZS48 YnI+K8KgwqDCoMKgwqDCoMKgIDs7IGBoaWRlLWlmZGVmLWVudiYjMzk7IGJlaW5nIGJ1ZmZlciBs b2NhbCkgYnkgY2xlYXJpbmcgdGhpcyB2YXJpYWJsZTxicj4NCg0KDQorwqDCoMKgwqDCoMKgwqAg OzsgKEMtYyBAIEMpIGV2ZXJ5dGltZSBiZWZvcmUgaGlkaW5nIGN1cnJlbnQgYnVmZmVyLjxicj4r OzvCoMKgwqDCoMKgIChzZXQgKG1ha2UtbG9jYWwtdmFyaWFibGUgJiMzOTtoaWRlLWlmZGVmLWVu dik8YnI+Kzs7wqDCoMKgwqDCoMKgwqDCoMKgwqAgKGRlZmF1bHQtdmFsdWUgJiMzOTtoaWRlLWlm ZGVmLWVudikpPGJyPivCoMKgwqDCoMKgwqDCoCAoc2V0ICYjMzk7aGlkZS1pZmRlZi1lbnYgKGRl ZmF1bHQtdmFsdWUgJiMzOTtoaWRlLWlmZGVmLWVudikpPGJyPg0KDQoNCsKgwqDCoMKgwqDCoMKg wqAgKHNldCAobWFrZS1sb2NhbC12YXJpYWJsZSAmIzM5O2hpZGUtaWZkZWYtaGlkaW5nKTxicj7C oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoZGVmYXVsdC12YWx1ZSAmIzM5O2hpZGUtaWZkZWYt aGlkaW5nKSk8YnI+wqDCoMKgwqDCoMKgwqDCoCAoc2V0IChtYWtlLWxvY2FsLXZhcmlhYmxlICYj Mzk7aGlmLW91dHNpZGUtcmVhZC1vbmx5KSBidWZmZXItcmVhZC1vbmx5KTxicj5AQCAtMjc5LDYg KzMyNywxNCBAQCBTZXZlcmFsIHZhcmlhYmxlcyBhZmZlY3QgaG93IHRoZSBoaWRpbmcgaXMgZG9u ZTo8YnI+DQoNCg0KwqDCoMKgwqAgKHdoZW4gaGlkZS1pZmRlZi1oaWRpbmc8YnI+wqDCoMKgwqDC oMKgIChzaG93LWlmZGVmcykpKSk8YnI+wqA8YnI+KyhkZWZ1biBoaWYtY2xlYXItYWxsLWlmZGVm LWRlZmluZWQgKCk8YnI+K8KgICZxdW90O0NsZWFycyBhbGwgc3ltYm9scyBkZWZpbmVkIGluIGBo aWRlLWlmZGVmLWVudiYjMzk7Ljxicj4rSXQgd2lsbCBiYWNrdXAgdGhpcyB2YXJpYWJsZSB0byBg aGlkZS1pZmRlZi1lbnYtYmFja3VwJiMzOTsgYmVmb3JlIGNsZWFyaW5nIHRvPGJyPg0KDQoNCitw cmV2ZW50IGFjY2lkZW50YWwgY2xlYXJhbmNlLiZxdW90Ozxicj4rwqAgKGludGVyYWN0aXZlKTxi cj4rwqAgKHdoZW4gKHktb3Itbi1wICZxdW90O0NsZWFyIGFsbCAjZGVmaW5lZCBzeW1ib2xzPyZx dW90Oyk8YnI+K8KgwqDCoCAoc2V0cSBoaWRlLWlmZGVmLWVudi1iYWNrdXAgaGlkZS1pZmRlZi1l bnYpPGJyPivCoMKgwqAgKHNldHEgaGlkZS1pZmRlZi1lbnYgbmlsKSkpPGJyPsKgPGJyPsKgKGRl ZnVuIGhpZi1zaG93LWFsbCAoKTxicj4NCg0KDQrCoMKgICZxdW90O1Nob3cgYWxsIG9mIHRoZSB0 ZXh0IGluIHRoZSBjdXJyZW50IGJ1ZmZlci4mcXVvdDs8YnI+QEAgLTI5OCwxNiArMzU0LDY0IEBA IFNldmVyYWwgdmFyaWFibGVzIGFmZmVjdCBob3cgdGhlIGhpZGluZyBpcyBkb25lOjxicj7CoMKg ICh3aGlsZSAoPSAobG9nYW5kIDEgKHNraXAtY2hhcnMtYmFja3dhcmQgJnF1b3Q7XFxcXCZxdW90 OykpIDEpPGJyPsKgwqDCoMKgIChlbmQtb2YtbGluZSAyKSkpPGJyPg0KDQoNCsKgPGJyPisoZGVm dW4gaGlmLW1lcmdlLWlmZGVmLXJlZ2lvbiAoc3RhcnQgZW5kKTxicj4rwqAgJnF1b3Q7VGhpcyBm dW5jdGlvbiBtZXJnZXMgbmVhcmJ5IGlmZGVmIHJlZ2lvbnMgdG8gZm9ybSBhIGJpZ2dlciBvdmVy bGF5Ljxicj4rVGhlIHJlZ2lvbiBpcyBkZWZpbmVkIGJ5IFNUQVJUIGFuZCBFTkQuwqAgVGhpcyB3 aWxsIGRlY3JlYXNlIHRoZSBudW1iZXIgb2Y8YnI+K292ZXJsYXlzIGNyZWF0ZWQuJnF1b3Q7PGJy Pg0KDQoNCivCoCA7OyBHZW5lcmFsbHkgdGhlcmUgaXMgbm8gbmVlZCB0byBjYWxsIGl0c2VsZiBy ZWN1cnNpdmVseSBzaW5jZSB0aGVyZSBzaG91bGQ8YnI+K8KgIDs7IG9yaWdpbmFsbHkgZXhpc3Rz IG5vIHVuLW1lcmdlZCByZWdpb25zOyBob3dldmVyLCBpZiBhIHBhcnQgb2YgdGhlIGZpbGUgaXM8 YnI+K8KgIDs7IGhpZGRlbiB3aXRoIGBoaWRlLWlmZGVmLWxpbmVzJiMzOTsgZXF1YWxzIHRvIG5p bCB3aGlsZSBhbm90aGVyIHBhcnQgd2l0aCAmIzM5O3QsPGJyPg0KDQoNCivCoCA7OyB0aGlzIGNh c2UgaGFwcGVucy48YnI+K8KgIDs7IFRPRE86IFNob3VsZCB3ZSBtZXJnZT8gb3IganVzdCBjcmVh dGUgYSBjb250YWluZXIgb3ZlcmxheT8gLS0gdGhpcyBjYW48YnI+K8KgIDs7IHByZXZlbnQgYGhp ZGVpZi1zaG93LWlmZGVmJiMzOTsgZXhwYW5kaW5nIHRvbyBtYW55IGhpZGRlbiBjb250ZW50cyBz aW5jZSB0aGVyZTxicj4rwqAgOzsgaXMgb25seSBhIGJpZyBvdmVybGF5IGV4aXN0cyB0aGVyZSB3 aXRob3V0IGFueSBzbWFsbGVyIG92ZXJsYXlzLjxicj4NCg0KDQorwqAgKHNhdmUtcmVzdHJpY3Rp b248YnI+K8KgwqDCoCAod2lkZW4pIDsgT3RoZXJ3aXNlIGBwb2ludC1taW4mIzM5OyBhbmQgYHBv aW50LW1heCYjMzk7IHdpbGwgYmUgcmVzdHJpY3RlZCBhbmQgdGh1czxicj4rwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIDsgZmFpbCB0byBmaW5kIG5laWdoYm9yIG92ZXJsYXlzPGJyPivCoMKgwqAgKGxl dCAoKGJlZ292cnMgKG92ZXJsYXlzLWluPGJyPg0KDQoNCivCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCAobWF4ICgtIHN0YXJ0IDIpIChwb2ludC1taW4pKTxicj4rwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKG1heCAoLSBzdGFydCAxKSAocG9pbnQt bWluKSkpKTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgIChlbmRvdnJzIChvdmVybGF5cy1pbjxicj4r wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKG1pbiAoKyBlbmQgMSkgKHBv aW50LW1heCkpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAobWlu ICgrIGVuZCAyKSAocG9pbnQtbWF4KSkpKTxicj4NCg0KDQorwqDCoMKgwqDCoMKgwqDCoMKgIChv YiBuaWwpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqAgKG9lIG5pbCk8YnI+K8KgwqDCoMKgwqDCoMKg wqDCoCBiIGUpPGJyPivCoMKgwqDCoMKgIDs7IE1lcmdlIG92ZXJsYXlzIGJlZm9yZSBTVEFSVDxi cj4rwqDCoMKgwqDCoCAoZG9saXN0IChvIGJlZ292cnMpPGJyPivCoMKgwqDCoMKgwqDCoCAod2hl biAob3ZlcmxheS1nZXQgbyAmIzM5O2hpZGUtaWZkZWYpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqAg KHNldHEgYiAobWluIHN0YXJ0IChvdmVybGF5LXN0YXJ0IG8pKTxicj4NCg0KDQorwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIGUgKG1heCBlbmQgKG92ZXJsYXktZW5kIG8pKSk8YnI+K8Kg wqDCoMKgwqDCoMKgwqDCoCAobW92ZS1vdmVybGF5IG8gYiBlKTxicj4rwqDCoMKgwqDCoMKgwqDC oMKgIChoaWYtbWVyZ2UtaWZkZWYtcmVnaW9uIGIgZSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoCAo c2V0cSBvYiBvKSkpPGJyPivCoMKgwqDCoMKgIDs7IE1lcmdlIG92ZXJsYXlzIGFmdGVyIEVORDxi cj4rwqDCoMKgwqDCoCAoZG9saXN0IChvIGVuZG92cnMpPGJyPg0KDQoNCivCoMKgwqDCoMKgwqDC oCAod2hlbiAob3ZlcmxheS1nZXQgbyAmIzM5O2hpZGUtaWZkZWYpPGJyPivCoMKgwqDCoMKgwqDC oMKgwqAgKHNldHEgYiAobWluIHN0YXJ0IChvdmVybGF5LXN0YXJ0IG8pKTxicj4rwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIGUgKG1heCBlbmQgKG92ZXJsYXktZW5kIG8pKSk8YnI+K8Kg wqDCoMKgwqDCoMKgwqDCoCAobW92ZS1vdmVybGF5IG8gYiBlKTxicj4rwqDCoMKgwqDCoMKgwqDC oMKgIChoaWYtbWVyZ2UtaWZkZWYtcmVnaW9uIGIgZSk8YnI+DQoNCg0KK8KgwqDCoMKgwqDCoMKg wqDCoCAoc2V0ZiBvZSBvKSkpPGJyPivCoMKgwqDCoMKgIDs7IElmIGJvdGggU1RBUlQgYW5kIEVO RCBtZXJnaW5nIGhhcHBlbnMsIG1lcmdlIGludG8gYmlnZ2VyIG9uZTxicj4rwqDCoMKgwqDCoCAo d2hlbiAoYW5kIG9iIG9lKTxicj4rwqDCoMKgwqDCoMKgwqAgKGxldCAoKGIgKG1pbiAob3Zlcmxh eS1zdGFydCBvYikgKG92ZXJsYXktc3RhcnQgb2UpKSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIChlIChtYXggKG92ZXJsYXktZW5kIG9iKSAob3ZlcmxheS1lbmQgb2UpKSkpPGJyPg0K DQoNCivCoMKgwqDCoMKgwqDCoMKgwqAgKGRlbGV0ZS1vdmVybGF5IG9lKTxicj4rwqDCoMKgwqDC oMKgwqDCoMKgIChtb3ZlLW92ZXJsYXkgb2IgYiBlKTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgICho aWYtbWVyZ2UtaWZkZWYtcmVnaW9uIGIgZSkpKTxicj4rwqDCoMKgwqDCoCAob3Igb2Igb2UpKSkp PGJyPis8YnI+wqAoZGVmdW4gaGlkZS1pZmRlZi1yZWdpb24taW50ZXJuYWwgKHN0YXJ0IGVuZCk8 YnI+LcKgIChyZW1vdmUtb3ZlcmxheXMgc3RhcnQgZW5kICYjMzk7aGlkZS1pZmRlZiB0KTxicj4N Cg0KDQorwqAgKHVubGVzcyAoaGlmLW1lcmdlLWlmZGVmLXJlZ2lvbiBzdGFydCBlbmQpPGJyPsKg wqAgKGxldCAoKG8gKG1ha2Utb3ZlcmxheSBzdGFydCBlbmQpKSk8YnI+wqDCoMKgwqAgKG92ZXJs YXktcHV0IG8gJiMzOTtoaWRlLWlmZGVmIHQpPGJyPsKgwqDCoMKgIChpZiBoaWRlLWlmZGVmLXNo YWRvdzxicj7CoMKgwqDCoMKgwqDCoMKgIChvdmVybGF5LXB1dCBvICYjMzk7ZmFjZSAmIzM5O2hp ZGUtaWZkZWYtc2hhZG93KTxicj4NCg0KDQotwqDCoMKgwqDCoCAob3ZlcmxheS1wdXQgbyAmIzM5 O2ludmlzaWJsZSAmIzM5O2hpZGUtaWZkZWYpKSkpPGJyPivCoMKgwqDCoMKgwqDCoCAob3Zlcmxh eS1wdXQgbyAmIzM5O2ludmlzaWJsZSAmIzM5O2hpZGUtaWZkZWYpKSkpKTxicj7CoDxicj7CoChk ZWZ1biBoaWRlLWlmZGVmLXJlZ2lvbiAoc3RhcnQgZW5kKTxicj4twqAgJnF1b3Q7U1RBUlQgaXMg dGhlIHN0YXJ0IG9mIGEgI2lmIG9yICNlbHNlIGZvcm0uwqAgRU5EIGlzIHRoZSBlbmRpbmcgcGFy dC48YnI+DQoNCg0KK8KgICZxdW90O1NUQVJUIGlzIHRoZSBzdGFydCBvZiBhICNpZiwgI2VsaWYs IG9yICNlbHNlIGZvcm0uwqAgRU5EIGlzIHRoZSBlbmRpbmcgcGFydC48YnI+wqBFdmVyeXRoaW5n IGluY2x1ZGluZyB0aGVzZSBsaW5lcyBpcyBtYWRlIGludmlzaWJsZS4mcXVvdDs8YnI+wqDCoCAo c2F2ZS1leGN1cnNpb248YnI+wqDCoMKgwqAgKGdvdG8tY2hhciBzdGFydCkgKGhpZi1lbmQtb2Yt bGluZSkgKHNldHEgc3RhcnQgKHBvaW50KSk8YnI+DQoNCg0KQEAgLTMxNiw3ICs0MjAsOSBAQCBF dmVyeXRoaW5nIGluY2x1ZGluZyB0aGVzZSBsaW5lcyBpcyBtYWRlIGludmlzaWJsZS4mcXVvdDs8 YnI+wqA8YnI+wqAoZGVmdW4gaGlmLXNob3ctaWZkZWYtcmVnaW9uIChzdGFydCBlbmQpPGJyPsKg wqAgJnF1b3Q7RXZlcnl0aGluZyBiZXR3ZWVuIFNUQVJUIGFuZCBFTkQgaXMgbWFkZSB2aXNpYmxl LiZxdW90Ozxicj4twqAgKHJlbW92ZS1vdmVybGF5cyBzdGFydCBlbmQgJiMzOTtoaWRlLWlmZGVm IHQpKTxicj4NCg0KDQorwqAgKGxldCAoKG9udW0gKGxlbmd0aCAob3ZlcmxheXMtaW4gc3RhcnQg ZW5kKSkpKTxicj4rwqDCoMKgIChyZW1vdmUtb3ZlcmxheXMgc3RhcnQgZW5kICYjMzk7aGlkZS1p ZmRlZiB0KTxicj4rwqDCoMKgICgvPSBvbnVtIChsZW5ndGggKG92ZXJsYXlzLWluIHN0YXJ0IGVu ZCkpKSkpPGJyPsKgPGJyPsKgPGJyPsKgOzs9PT0lJVNGJSUgZXZhbHVhdGlvbiAoU3RhcnQpwqAg PT09PGJyPkBAIC0zNzUsMTAgKzQ4MSw4IEBAIHRoYXQgZm9ybSBzaG91bGQgYmUgZGlzcGxheWVk LiZxdW90Oyk8YnI+DQoNCg0KwqDCoCAoY29uY2F0IGhpZi1jcHAtcHJlZml4ICZxdW90O1xcKGlm XFwobj9kZWZcXCk/XFx8ZWxpZlxcfGRlZmluZVxcKVsgXHRdKyZxdW90OykpPGJyPsKgPGJyPsKg KGRlZmNvbnN0IGhpZi13aGl0ZS1yZWdleHDCoMKgwqAgJnF1b3Q7WyBcdF0qJnF1b3Q7KTxicj4t KGRlZmNvbnN0IGhpZi1kZWZpbmUtcmVnZXhwPGJyPi3CoCAoY29uY2F0IGhpZi1jcHAtcHJlZml4 ICZxdW90O1xcKGRlZmluZVxcfHVuZGVmXFwpJnF1b3Q7KSk8YnI+DQoNCg0KLShkZWZjb25zdCBo aWYtaWQtcmVnZXhwPGJyPi3CoCAoY29uY2F0ICZxdW90O1tbOmFscGhhOl1fXVtbOmFsbnVtOl1f XSomcXVvdDspKTxicj4rKGRlZmNvbnN0IGhpZi1kZWZpbmUtcmVnZXhwwqDCoCAoY29uY2F0IGhp Zi1jcHAtcHJlZml4ICZxdW90O1xcKGRlZmluZVxcfHVuZGVmXFwpJnF1b3Q7KSk8YnI+KyhkZWZj b25zdCBoaWYtaWQtcmVnZXhwwqDCoMKgwqDCoMKgIChjb25jYXQgJnF1b3Q7W1s6YWxwaGE6XV9d W1s6YWxudW06XV9dKiZxdW90OykpPGJyPg0KDQoNCsKgKGRlZmNvbnN0IGhpZi1tYWNyb3JlZi1y ZWdleHA8YnI+wqDCoCAoY29uY2F0IGhpZi13aGl0ZS1yZWdleHAgJnF1b3Q7XFwoJnF1b3Q7IGhp Zi1pZC1yZWdleHAgJnF1b3Q7XFwpJnF1b3Q7IGhpZi13aGl0ZS1yZWdleHA8YnI+wqDCoMKgwqDC oMKgwqDCoMKgwqAgJnF1b3Q7XFwoJnF1b3Q7PGJyPkBAIC00OTksNiArNjAzLDggQEAgdGhhdCBm b3JtIHNob3VsZCBiZSBkaXNwbGF5ZWQuJnF1b3Q7KTxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgKHNldHEgaGlmLXNpbXBsZS10b2tlbi1vbmx5IG5pbCkpKTxi cj4NCg0KDQrCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdG9rZW4tbGlzdCkpKTxicj7C oDxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqAgKChsb29raW5nLWF0ICZxdW90O1xyJnF1b3Q7KSA7 IFNvbWV0aW1lcyBNUy1XaW5kb3dzIHVzZXIgd2lsbCBsZWF2ZSBDUiBpbjxicj4rwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCAoZm9yd2FyZC1jaGFyIDEpKSA7wqAgdGhlIHNvdXJjZSBjb2RlLiBMZXQm IzM5O3Mgbm90IGdldCBzdHVjayBoZXJlLjxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgICh0IChl cnJvciAmcXVvdDtCYWQgI2lmIGV4cHJlc3Npb246ICVzJnF1b3Q7IChidWZmZXItc3RyaW5nKSkp KSkpKTxicj4NCg0KDQrCoDxicj7CoMKgwqDCoCAobnJldmVyc2UgdG9rZW4tbGlzdCkpKTxicj5A QCAtMTE3MywxMyArMTI3OSwxNiBAQCBEbyB0aGlzIHdoZW4gY3Vyc29yIGlzIGF0IHRoZSBiZWdp bm5pbmcgb2YgYHJlZ2V4cCYjMzk7IChpLmUuICNpZlgpLiZxdW90Ozxicj7CoMKgwqDCoCAoaWYg KD0gc3RhcnQgKHBvaW50KSk8YnI+wqDCoMKgwqDCoMKgwqDCoCAoZXJyb3IgJnF1b3Q7TWlzbWF0 Y2hlZCAjaWZkZWYgI2VuZGlmIHBhaXImcXVvdDspKSk8YnI+DQoNCg0KwqDCoCAoY29uZCAoKGhp Zi1sb29raW5nLWF0LWVuZGlmKTxicj4twqDCoMKgIMKgKGhpZi1lbmRpZi10by1pZmRlZikgOyBm aW5kIGJlZ2lubmluZyBvZiBuZXN0ZWQgaWY8YnI+LcKgwqDCoCDCoChoaWYtZW5kaWYtdG8taWZk ZWYpKSA7IGZpbmQgYmVnaW5uaW5nIG9mIG91dGVyIGlmIG9yIGVsc2U8YnI+K8KgwqDCoMKgwqDC oMKgwqAgKGhpZi1lbmRpZi10by1pZmRlZikgOyBGaW5kIGJlZ2lubmluZyBvZiBuZXN0ZWQgaWY8 YnI+DQoNCg0KK8KgwqDCoMKgwqDCoMKgwqAgKGhpZi1lbmRpZi10by1pZmRlZikpIDsgRmluZCBi ZWdpbm5pbmcgb2Ygb3V0ZXIgaWYgb3IgZWxzZTxicj4rwqDCoMKgwqDCoMKgwqAgKChoaWYtbG9v a2luZy1hdC1lbGlmKTxicj4rwqDCoMKgwqDCoMKgwqDCoCAoaGlmLWVuZGlmLXRvLWlmZGVmKSk8 YnI+wqDCoMKgwqDCoMKgwqDCoCAoKGhpZi1sb29raW5nLWF0LWVsc2UpPGJyPsKgwqDCoMKgwqDC oMKgwqDCoCAoaGlmLWVuZGlmLXRvLWlmZGVmKSk8YnI+wqDCoMKgwqDCoMKgwqDCoCAoKGhpZi1s b29raW5nLWF0LWlmWCk8YnI+DQoNCg0KwqDCoMKgwqDCoMKgwqDCoMKgICYjMzk7ZG9uZSk8YnI+ LcKgwqDCoCAodCkpKcKgwqDCoCDCoMKgwqAgwqDCoMKgIDsgbmV2ZXIgZ2V0cyBoZXJlPGJyPivC oMKgwqDCoMKgwqDCoCAodDxicj4rwqDCoMKgwqDCoMKgwqDCoCAoZXJyb3IgJnF1b3Q7TWlzbWF0 Y2hlZCAjZW5kaWYmcXVvdDspKSkpwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgOyBu ZXZlciBnZXRzIGhlcmU8YnI+wqA8YnI+wqA8YnI+wqAoZGVmdW4gZm9yd2FyZC1pZmRlZiAoJmFt cDtvcHRpb25hbCBhcmcpPGJyPg0KDQoNCkBAIC0xMjczLDI2ICsxMzgyLDI1IEBAIFdpdGggYXJn dW1lbnQsIGRvIHRoaXMgdGhhdCBtYW55IHRpbWVzLiZxdW90Ozxicj7CoDs7PT09JSVTRiUlIGhp ZGUtaWZkZWYtaGlkaW5nIChTdGFydCnCoCA9PT08YnI+wqA8YnI+wqA8YnI+LTs7OyBBIHJhbmdl IGlzIGEgc3RydWN0dXJlIHdpdGggZm91ciBjb21wb25lbnRzOjxicj4tOzs7IEVMU0UtUMKgwqDC oCBUcnVlIGlmIHRoZXJlIHdhcyBhbiBlbHNlIGNsYXVzZSBmb3IgdGhlIGlmZGVmLjxicj4NCg0K DQotOzs7IFNUQVJUwqDCoMKgIFRoZSBzdGFydCBvZiB0aGUgcmFuZ2UuIChiZWdpbm5pbmcgb2Yg bGluZSk8YnI+LTs7OyBFTFNFwqDCoMKgIFRoZSBlbHNlIG1hcmtlciAoYmVnaW5uaW5nIG9mIGxp bmUpPGJyPi07OzvCoMKgwqAgwqDCoMKgIMKgwqDCoCBPbmx5IHZhbGlkIGlmIEVMU0UtUCBpcyB0 cnVlLjxicj4tOzs7IEVORMKgwqDCoCDCoMKgwqAgVGhlIGVuZCBvZiB0aGUgcmFuZ2UuwqAgKGJl Z2lubmluZyBvZiBsaW5lKTxicj4NCg0KDQorOzsgQSByYW5nZSBpcyBhIHN0cnVjdHVyZSB3aXRo IGZvdXIgY29tcG9uZW50czo8YnI+Kzs7IFNUQVJUwqDCoMKgwqDCoMKgIFRoZSBzdGFydCBvZiB0 aGUgcmFuZ2UuIChiZWdpbm5pbmcgb2YgbGluZSk8YnI+Kzs7IEVMU0XCoMKgwqDCoMKgwqDCoCBU aGUgZWxzZSBtYXJrZXIgKGJlZ2lubmluZyBvZiBsaW5lKTxicj4rOzsgRU5EwqDCoMKgwqDCoMKg wqDCoCBUaGUgZW5kIG9mIHRoZSByYW5nZS7CoCAoYmVnaW5uaW5nIG9mIGxpbmUpPGJyPg0KDQoN Cis7OyBFTElGwqDCoMKgwqDCoMKgwqAgQSBzZXF1ZW5jZSBvZiAjZWxpZiBtYXJrZXJzIChiZWdp bm5pbmcgb2YgbGluZSk8YnI+wqA8YnI+LShkZWZzdWJzdCBoaWYtbWFrZS1yYW5nZSAoc3RhcnQg ZW5kICZhbXA7b3B0aW9uYWwgZWxzZSk8YnI+LcKgIChsaXN0IHN0YXJ0IGVsc2UgZW5kKSk8YnI+ KyhkZWZzdWJzdCBoaWYtbWFrZS1yYW5nZSAoc3RhcnQgZW5kICZhbXA7b3B0aW9uYWwgZWxzZSBl bGlmKTxicj4NCg0KDQorwqAgKGxpc3Qgc3RhcnQgZWxzZSBlbmQgZWxpZikpPGJyPsKgPGJyPsKg KGRlZnN1YnN0IGhpZi1yYW5nZS1zdGFydCAocmFuZ2UpIChlbHQgcmFuZ2UgMCkpPGJyPsKgKGRl ZnN1YnN0IGhpZi1yYW5nZS1lbHNlIChyYW5nZSkgKGVsdCByYW5nZSAxKSk8YnI+wqAoZGVmc3Vi c3QgaGlmLXJhbmdlLWVuZCAocmFuZ2UpIChlbHQgcmFuZ2UgMikpPGJyPisoZGVmc3Vic3QgaGlm LXJhbmdlLWVsaWYgKHJhbmdlKSAoZWx0IHJhbmdlIDMpKTxicj4NCg0KDQrCoDxicj7CoDxicj4t PGJyPi07OzsgRmluZC1SYW5nZTxicj4tOzs7IFRoZSB3b3JraG9yc2UsIGl0IGRlbGltaXRzIHRo ZSAjaWYgcmVnaW9uLsKgIFJlYXNvbmFibHkgc2ltcGxlOjxicj4tOzs7IFNraXAgdW50aWwgYW4g I2Vsc2Ugb3IgI2VuZGlmIGlzIGZvdW5kLCByZW1lbWJlcmluZyBwb3NpdGlvbnMuwqAgSWY8YnI+ LTs7OyBhbiAjZWxzZSB3YXMgZm91bmQsIHNraXAgc29tZSBtb3JlLCBsb29raW5nIGZvciB0aGUg dHJ1ZSAjZW5kaWYuPGJyPg0KDQoNCis7OyBGaW5kLVJhbmdlPGJyPis7OyBUaGUgd29ya2hvcnNl LCBpdCBkZWxpbWl0cyB0aGUgI2lmIHJlZ2lvbi7CoCBSZWFzb25hYmx5IHNpbXBsZTo8YnI+Kzs7 IFNraXAgdW50aWwgYW4gI2Vsc2Ugb3IgI2VuZGlmIGlzIGZvdW5kLCByZW1lbWJlcmluZyBwb3Np dGlvbnMuwqAgSWY8YnI+Kzs7IGFuICNlbHNlIHdhcyBmb3VuZCwgc2tpcCBzb21lIG1vcmUsIGxv b2tpbmcgZm9yIHRoZSB0cnVlICNlbmRpZi48YnI+DQoNCg0KwqA8YnI+wqAoZGVmdW4gaGlmLWZp bmQtcmFuZ2UgKCk8YnI+wqDCoCAmcXVvdDtSZXR1cm4gYSBSYW5nZSBzdHJ1Y3R1cmUgZGVzY3Jp YmluZyB0aGUgY3VycmVudCAjaWYgcmVnaW9uLjxicj5AQCAtMTMwMSwxOSArMTQwOSwyMyBAQCBQ b2ludCBpcyBsZWZ0IHVuY2hhbmdlZC4mcXVvdDs8YnI+wqDCoCAoc2F2ZS1leGN1cnNpb248YnI+ wqDCoMKgwqAgKGJlZ2lubmluZy1vZi1saW5lKTxicj7CoMKgwqDCoCAobGV0ICgoc3RhcnQgKHBv aW50KSk8YnI+DQoNCg0KK8KgwqDCoMKgwqDCoMKgwqDCoCAoZWxpZiBuaWwpPGJyPsKgwqDCoMKg wqDCoMKgwqDCoMKgIChlbHNlIG5pbCk8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqAgKGVuZCBuaWwp KTxicj4twqDCoMKgwqDCoCA7OyBQYXJ0IG9uZS7CoCBMb29rIGZvciBlaXRoZXIgI2VuZGlmIG9y ICNlbHNlLjxicj4rwqDCoMKgwqDCoCA7OyBQYXJ0IG9uZS7CoCBMb29rIGZvciBlaXRoZXIgI2Vs aWYsICNlbHNlIG9yICNlbmRpZi48YnI+wqDCoMKgwqDCoMKgIDs7IFRoaXMgbG9vcC1hbmQtYS1o YWxmIGRlZGljYXRlZCB0byBFLiBEaWprc3RyYS48YnI+DQoNCg0KK8KgwqDCoMKgwqAgKHdoaWxl IChhbmQgKG5vdCBlbHNlKSAobm90IGVuZCkpPGJyPsKgwqDCoMKgwqDCoMKgwqAgKHdoaWxlIChw cm9nbjxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWYtZmluZC1uZXh0 LXJlbGV2YW50KTxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWYtbG9v a2luZy1hdC1pZlgpKcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgOyBTa2lwIG5lc3RlZCBpZmRlZjxi cj7CoMKgwqDCoMKgwqDCoMKgwqDCoCAoaGlmLWlmZGVmLXRvLWVuZGlmKSk8YnI+DQoNCg0KLcKg wqDCoMKgwqAgOzsgRm91bmQgZWl0aGVyIGEgI2Vsc2Ugb3IgYW4gI2VuZGlmLjxicj4twqDCoMKg wqDCoCAoY29uZCAoKGhpZi1sb29raW5nLWF0LWVsc2UpPGJyPivCoMKgwqDCoMKgwqDCoCA7OyBG b3VuZCBlaXRoZXIgYSAjZWxzZSwgI2VsaWYsIG9yIGFuICNlbmRpZi48YnI+K8KgwqDCoMKgwqDC oMKgIChjb25kICgoaGlmLWxvb2tpbmctYXQtZWxpZik8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgKHNldHEgZWxpZiAobmNvbmMgZWxpZiAobGlzdCAocG9pbnQpKSkpKTxicj4NCg0K DQorwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKChoaWYtbG9va2luZy1hdC1lbHNlKTxicj7C oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKHNldHEgZWxzZSAocG9pbnQpKSk8YnI+wqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAodDxicj4twqDCoMKgIMKgwqDCoMKgIChzZXRxIGVu ZCAocG9pbnQpKSkpIDsgKGxpbmUtZW5kLXBvc2l0aW9uKTxicj4rwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCAoc2V0cSBlbmQgKHBvaW50KSkpKSk8YnI+wqDCoMKgwqDCoMKgIDs7IElmIGZv dW5kICNlbHNlLCBsb29rIGZvciAjZW5kaWYuPGJyPg0KDQoNCsKgwqDCoMKgwqDCoCAod2hlbiBl bHNlPGJyPsKgwqDCoMKgwqDCoMKgwqAgKHdoaWxlIChwcm9nbjxicj5AQCAtMTMyMyw3ICsxNDM1 LDcgQEAgUG9pbnQgaXMgbGVmdCB1bmNoYW5nZWQuJnF1b3Q7PGJyPsKgwqDCoMKgwqDCoMKgwqAg KGlmIChoaWYtbG9va2luZy1hdC1lbHNlKTxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGVy cm9yICZxdW90O0ZvdW5kIHR3byBlbHNlcyBpbiBhIHJvdz/CoCBCcm9rZW4hJnF1b3Q7KSk8YnI+ wqDCoMKgwqDCoMKgwqDCoCAoc2V0cSBlbmQgKHBvaW50KSkpwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCA7IChsaW5lLWVuZC1wb3NpdGlvbik8YnI+DQoNCg0KLcKgwqDCoMKgwqAgKGhpZi1tYWtlLXJh bmdlIHN0YXJ0IGVuZCBlbHNlKSkpKTxicj4rwqDCoMKgwqDCoCAoaGlmLW1ha2UtcmFuZ2Ugc3Rh cnQgZW5kIGVsc2UgZWxpZikpKSk8YnI+wqA8YnI+wqA8YnI+wqA7OyBBIGJpdCBzbGlteS48YnI+ QEAgLTEzMzgsNzAgKzE0NTAsMTgwIEBAIERvZXMgbm90aGluZyBpZiBgaGlkZS1pZmRlZi1saW5l cyYjMzk7IGlzIG5pbC4mcXVvdDs8YnI+wqDCoMKgwqDCoMKgwqAgKGxpbmUtYmVnaW5uaW5nLXBv c2l0aW9uKSAocHJvZ24gKGhpZi1lbmQtb2YtbGluZSkgKHBvaW50KSkpKSkpPGJyPg0KDQoNCsKg PGJyPsKgPGJyPi07OzvCoCBIaWYtUG9zc2libHktSGlkZTxicj4tOzs7wqAgVGhlcmUgYXJlIGZv dXIgY2FzZXMuwqAgVGhlICNpZlggZXhwcmVzc2lvbiBpcyAmcXVvdDt0YWtlbiZxdW90OyBpZiBp dDxicj4tOzs7wqAgdGhlIGhpZGUtaWZkZWYtZXZhbHVhdG9yIHJldHVybnMgVC7CoCBQcmVzdW1h Ymx5LCB0aGlzIG1lYW5zIHRoZSBjb2RlPGJyPi07OzvCoCBpbnNpZGUgdGhlICNpZmRlZiB3b3Vs ZCBiZSBpbmNsdWRlZCB3aGVuIHRoZSBwcm9ncmFtIHdhczxicj4NCg0KDQotOzs7wqAgY29tcGls ZWQuPGJyPi07Ozs8YnI+LTs7O8KgIENhc2UgMTrCoCAjaWZYIHRha2VuLCBhbmQgdGhlcmUmIzM5 O3MgYW4gI2Vsc2UuPGJyPi07OzvCoMKgwqAgVGhlICNlbHNlIHBhcnQgbXVzdCBiZSBoaWRkZW4u wqAgVGhlICNpZiAodGhlbikgcGFydCBtdXN0IGJlPGJyPi07OzvCoMKgwqAgcHJvY2Vzc2VkIGZv ciBuZXN0ZWQgI2lmWCYjMzk7cy48YnI+LTs7O8KgIENhc2UgMjrCoCAjaWZYIHRha2VuLCBhbmQg dGhlcmUmIzM5O3Mgbm8gI2Vsc2UuPGJyPg0KDQoNCi07OzvCoMKgwqAgVGhlICNpZiBwYXJ0IG11 c3QgYmUgcHJvY2Vzc2VkIGZvciBuZXN0ZWQgI2lmWCYjMzk7cy48YnI+LTs7O8KgIENhc2UgMzrC oCAjaWZYIG5vdCB0YWtlbiwgYW5kIHRoZXJlJiMzOTtzIGFuICNlbHNlLjxicj4tOzs7wqDCoMKg IFRoZSAjaWYgcGFydCBtdXN0IGJlIGhpZGRlbi7CoCBUaGUgI2Vsc2UgcGFydCBtdXN0IGJlIHBy b2Nlc3NlZDxicj4tOzs7wqDCoMKgIGZvciBuZXN0ZWQgI2lmcy48YnI+DQoNCg0KLTs7O8KgIENh c2UgNDrCoCAjaWZYIG5vdCB0YWtlbiwgYW5kIHRoZXJlJiMzOTtzIG5vICNlbHNlLjxicj4tOzs7 wqDCoMKgIFRoZSAjaWZYIHBhcnQgbXVzdCBiZSBoaWRkZW4uPGJyPi07Ozs8YnI+LTs7O8KgIEZ1 cnRoZXIgcHJvY2Vzc2luZyBpcyBkb25lIGJ5IG5hcnJvd2luZyB0byB0aGUgcmVsZXZhbnQgcmVn aW9uPGJyPi07OzvCoCBhbmQganVzdCByZWN1cnNpdmVseSBjYWxsaW5nIGhpZGUtaWZkZWYtZ3V0 cy48YnI+DQoNCg0KLTs7Ozxicj4tOzs7wqAgV2hlbiBoaWYtcG9zc2libHktaGlkZSByZXR1cm5z LCBwb2ludCBpcyBhdCB0aGUgZW5kIG9mIHRoZTxicj4tOzs7wqAgcG9zc2libHktaGlkZGVuIHJh bmdlLjxicj4tPGJyPi0oZGVmdW4gaGlmLXJlY3Vyc2Utb24gKHN0YXJ0IGVuZCk8YnI+Kzs7wqAg SGlmLVBvc3NpYmx5LUhpZGU8YnI+Kzs7wqAgVGhlcmUgYXJlIGZvdXIgY2FzZXMuwqAgVGhlICNp ZlggZXhwcmVzc2lvbiBpcyAmcXVvdDt0YWtlbiZxdW90OyBpZiBpdDxicj4NCg0KDQorOzvCoCB0 aGUgaGlkZS1pZmRlZi1ldmFsdWF0b3IgcmV0dXJucyBULsKgIFByZXN1bWFibHksIHRoaXMgbWVh bnMgdGhlIGNvZGU8YnI+Kzs7wqAgaW5zaWRlIHRoZSAjaWZkZWYgd291bGQgYmUgaW5jbHVkZWQg d2hlbiB0aGUgcHJvZ3JhbSB3YXM8YnI+Kzs7wqAgY29tcGlsZWQuPGJyPis7Ozxicj4rOzvCoCBD YXNlIDE6wqAgI2lmWCB0YWtlbiwgYW5kIHRoZXJlJiMzOTtzIGFuICNlbHNlLjxicj4NCg0KDQor OzvCoMKgwqDCoCBUaGUgI2Vsc2UgcGFydCBtdXN0IGJlIGhpZGRlbi7CoCBUaGUgI2lmICh0aGVu KSBwYXJ0IG11c3QgYmU8YnI+Kzs7wqDCoMKgwqAgcHJvY2Vzc2VkIGZvciBuZXN0ZWQgI2lmWCYj Mzk7cy48YnI+Kzs7wqAgQ2FzZSAyOsKgICNpZlggdGFrZW4sIGFuZCB0aGVyZSYjMzk7cyBubyAj ZWxzZS48YnI+Kzs7wqDCoMKgwqAgVGhlICNpZiBwYXJ0IG11c3QgYmUgcHJvY2Vzc2VkIGZvciBu ZXN0ZWQgI2lmWCYjMzk7cy48YnI+DQoNCg0KKzs7wqAgQ2FzZSAzOsKgICNpZlggbm90IHRha2Vu LCBhbmQgdGhlcmUmIzM5O3MgYW4gI2VsaWY8YnI+Kzs7wqDCoMKgwqAgVGhlICNpZiBwYXJ0IG11 c3QgYmUgaGlkZGVuLCBhbmQgdGhlbiBldmFsdWF0ZTxicj4rOzvCoMKgwqDCoCB0aGUgI2VsaWYg Y29uZGl0aW9uIGxpa2UgYSBuZXcgI2lmWC48YnI+Kzs7wqAgQ2FzZSA0OsKgICNpZlggbm90IHRh a2VuLCBhbmQgdGhlcmUmIzM5O3MganVzdCBhbiAjZWxzZS48YnI+DQoNCg0KKzs7wqDCoMKgwqAg VGhlICNpZiBwYXJ0IG11c3QgYmUgaGlkZGVuLsKgIFRoZSAjZWxzZSBwYXJ0IG11c3QgYmUgcHJv Y2Vzc2VkPGJyPis7O8KgwqDCoMKgIGZvciBuZXN0ZWQgI2lmcy48YnI+Kzs7wqAgQ2FzZSA1OsKg ICNpZlggbm90IHRha2VuLCBhbmQgdGhlcmUmIzM5O3Mgbm8gI2Vsc2UuPGJyPis7O8KgwqDCoMKg IFRoZSAjaWZYIHBhcnQgbXVzdCBiZSBoaWRkZW4uPGJyPis7Ozxicj4rOzvCoCBGdXJ0aGVyIHBy b2Nlc3NpbmcgaXMgZG9uZSBieSBuYXJyb3dpbmcgdG8gdGhlIHJlbGV2YW50IHJlZ2lvbjxicj4N Cg0KDQorOzvCoCBhbmQganVzdCByZWN1cnNpdmVseSBjYWxsaW5nIGhpZGUtaWZkZWYtZ3V0cy48 YnI+Kzs7PGJyPis7O8KgIFdoZW4gaGlmLXBvc3NpYmx5LWhpZGUgcmV0dXJucywgcG9pbnQgaXMg YXQgdGhlIGVuZCBvZiB0aGU8YnI+Kzs7wqAgcG9zc2libHktaGlkZGVuIHJhbmdlLjxicj4rPGJy PisoZGVmdmFyIGhpZi1yZWN1cnNlLWxldmVsIDApPGJyPis8YnI+KyhkZWZ1biBoaWYtcmVjdXJz ZS1vbiAoc3RhcnQgZW5kICZhbXA7b3B0aW9uYWwgZG9udC1nby1lb2wpPGJyPg0KDQoNCsKgwqAg JnF1b3Q7Q2FsbCBgaGlkZS1pZmRlZi1ndXRzJiMzOTsgYWZ0ZXIgbmFycm93aW5nIHRvIGVuZCBv ZiBTVEFSVCBsaW5lIGFuZCBFTkQgbGluZS4mcXVvdDs8YnI+wqDCoCAoc2F2ZS1leGN1cnNpb248 YnI+wqDCoMKgwqAgKHNhdmUtcmVzdHJpY3Rpb248YnI+wqDCoMKgwqDCoMKgIChnb3RvLWNoYXIg c3RhcnQpPGJyPi3CoMKgwqDCoMKgIChlbmQtb2YtbGluZSk8YnI+K8KgwqDCoMKgwqAgKHVubGVz cyBkb250LWdvLWVvbDxicj4NCg0KDQorwqDCoMKgwqDCoMKgwqAgKGVuZC1vZi1saW5lKSk8YnI+ wqDCoMKgwqDCoMKgIChuYXJyb3ctdG8tcmVnaW9uIChwb2ludCkgZW5kKTxicj4twqDCoMKgwqDC oCAoaGlkZS1pZmRlZi1ndXRzKSkpKTxicj4rwqDCoMKgwqDCoCAobGV0ICgoaGlmLXJlY3Vyc2Ut bGV2ZWwgKDErIGhpZi1yZWN1cnNlLWxldmVsKSkpPGJyPivCoMKgwqDCoMKgwqDCoCAoaGlkZS1p ZmRlZi1ndXRzKSkpKSk8YnI+wqA8YnI+LShkZWZ1biBoaWYtcG9zc2libHktaGlkZSAoKTxicj4N Cg0KDQorKGRlZnVuIGhpZi1wb3NzaWJseS1oaWRlIChleHBhbmQtcmVpbmNsdXNpb24pPGJyPsKg wqAgJnF1b3Q7Q2FsbGVkIGF0ICNpZlggZXhwcmVzc2lvbiwgdGhpcyBoaWRlcyB0aG9zZSBwYXJ0 cyB0aGF0IHNob3VsZCBiZSBoaWRkZW4uPGJyPi1JdCB1c2VzIHRoZSBqdWRnbWVudCBvZiBgaGlk ZS1pZmRlZi1ldmFsdWF0b3ImIzM5Oy4mcXVvdDs8YnI+K0l0IHVzZXMgdGhlIGp1ZGdtZW50IG9m IGBoaWRlLWlmZGVmLWV2YWx1YXRvciYjMzk7LsKgIEVYUEFORC1SRUlOQ0xVU0lPTiBpcyBhIGZs YWc8YnI+DQoNCg0KK2luZGljYXRpbmcgdGhhdCB3ZSBzaG91bGQgZXhwYW5kIHRoZSAjaWZkZWYg ZXZlbiBpZiBpdCBzaG91bGQgYmUgaGlkZGVuLjxicj4rUmVmZXIgdG8gYGhpZGUtaWZkZWYtZXhw YW5kLXJlaW5jbHVzaW9uLXByb3RlY3Rpb24mIzM5OyBmb3IgbW9yZSBkZXRhaWxzLiZxdW90Ozxi cj7CoMKgIDs7IChtZXNzYWdlICZxdW90O2hpZi1wb3NzaWJseS1oaWRlJnF1b3Q7KSAoc2l0LWZv ciAxKTxicj4NCg0KDQotwqAgKGxldCAoKHRlc3QgKGhpZi1jYW5vbmljYWxpemUgaGlmLWlmeC1y ZWdleHApKTxicj4twqDCoMKgIChyYW5nZSAoaGlmLWZpbmQtcmFuZ2UpKSk8YnI+K8KgIChsZXQq ICgoY2FzZS1mb2xkLXNlYXJjaCBuaWwpPGJyPivCoMKgwqDCoMKgwqDCoMKgICh0ZXN0IChoaWYt Y2Fub25pY2FsaXplIGhpZi1pZngtcmVnZXhwKSk8YnI+K8KgwqDCoMKgwqDCoMKgwqAgKHJhbmdl IChoaWYtZmluZC1yYW5nZSkpPGJyPivCoMKgwqDCoMKgwqDCoMKgIChlbGlmcyAoaGlmLXJhbmdl LWVsaWYgcmFuZ2UpKTxicj4NCg0KDQorwqDCoMKgwqDCoMKgwqDCoCAoaWYtcGFydCB0KSA7IEV2 ZXJ5dGltZSB3ZSBzdGFydCBmcm9tIGlmLXBhcnQ8YnI+K8KgwqDCoMKgwqDCoMKgwqAgKGNvbXBs ZXRlIG5pbCkpPGJyPsKgwqDCoMKgIDs7IChtZXNzYWdlICZxdW90O3Rlc3QgPSAlcyZxdW90OyB0 ZXN0KSAoc2l0LWZvciAxKTxicj7CoDxicj7CoMKgwqDCoCAoaGlmLWhpZGUtbGluZSAoaGlmLXJh bmdlLWVuZCByYW5nZSkpPGJyPi3CoMKgwqAgKGlmIChub3QgKGhpZi1ub3QgKGZ1bmNhbGwgaGlk ZS1pZmRlZi1ldmFsdWF0b3IgdGVzdCkpKTxicj4NCg0KDQotwqDCoMKgIChjb25kICgoaGlmLXJh bmdlLWVsc2UgcmFuZ2UpwqDCoMKgIDsgY2FzZSAxPGJyPivCoMKgwqAgKHdoaWxlIChub3QgY29t cGxldGUpPGJyPivCoMKgwqDCoMKgIChpZiAoYW5kIChub3QgKGFuZCBleHBhbmQtcmVpbmNsdXNp b24gaWYtcGFydCkpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWYtbm90IChm dW5jYWxsIGhpZGUtaWZkZWYtZXZhbHVhdG9yIHRlc3QpKSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDC oCA7OyBpZlgvZWxpZiBpcyBGQUxTRTxicj4NCg0KDQorwqDCoMKgwqDCoMKgwqDCoMKgIChpZiBl bGlmczxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgOzsgQ2FzZSAzIC0gSGlkZSB0aGUg I2lmWCBhbmQgZXZhbCAjZWxpZjxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGxldCAo KG5ld3N0YXJ0IChjYXIgZWxpZnMpKSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCAoaGlmLWhpZGUtbGluZSAoaGlmLXJhbmdlLXN0YXJ0IHJhbmdlKSk8YnI+K8KgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCAoaGlkZS1pZmRlZi1yZWdpb24gKGhpZi1yYW5nZS1zdGFydCBy YW5nZSk8YnI+DQoNCg0KK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICgxLSBuZXdzdGFydCkpPGJyPivCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgKHNldGNhciByYW5nZSBuZXdzdGFydCk8YnI+K8KgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoZ290by1jaGFyIG5ld3N0YXJ0KTxicj4rwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIChzZXRxIGVsaWZzIChjZHIgZWxpZnMpKTxicj4rwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChzZXRxIHRlc3QgKGhpZi1jYW5vbmljYWxpemUgaGlm LWVsaWYtcmVnZXhwKSkpPGJyPg0KDQoNCis8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgOzsg Q2hlY2sgZm9yICNlbHNlPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChjb25kICgoaGlmLXJh bmdlLWVsc2UgcmFuZ2UpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg OzsgQ2FzZSA0IC0gI2Vsc2UgYmxvY2sgdmlzaWJsZTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIChoaWYtaGlkZS1saW5lIChoaWYtcmFuZ2UtZWxzZSByYW5nZSkpPGJy PivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGhpZGUtaWZkZWYtcmVnaW9u IChoaWYtcmFuZ2Utc3RhcnQgcmFuZ2UpPGJyPg0KDQoNCivCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoMS0g KGhpZi1yYW5nZS1lbHNlIHJhbmdlKSkpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgKGhpZi1yZWN1cnNlLW9uIChoaWYtcmFuZ2UtZWxzZSByYW5nZSk8YnI+K8KgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIChoaWYtcmFuZ2UtZW5kIHJhbmdlKSkpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgICh0PGJyPg0KDQoNCivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgOzsgQ2FzZSA1IC0gTm8gI2Vsc2UgYmxvY2ssIGhpZGUgI2lmWDxicj4rwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWRlLWlmZGVmLXJlZ2lvbiAocG9pbnQpPGJy PivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCAoMS0gKGhpZi1yYW5nZS1lbmQgcmFuZ2UpKSkpKTxicj4rwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCAoc2V0cSBjb21wbGV0ZSB0KSk8YnI+Kzxicj4NCg0KDQorwqDC oMKgwqDCoMKgwqAgOzsgaWZYL2VsaWYgaXMgVFJVRTxicj4rwqDCoMKgwqDCoMKgwqAgKGNvbmQg KGVsaWZzPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDs7IEx1a2UgZml4OiBkaXN0 aW5ndWlzaCBmcm9tICNlbGlmLi4jZWxpZiB0byAjZWxpZi4uI2Vsc2U8YnI+K8KgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgKGxldCAoKGVsaWYgKGNhciBlbGlmcykpKTxicj4rwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgOzsgaGlkZSBhbGwgZWxpZnM8YnI+K8KgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWYtaGlkZS1saW5lIGVsaWYpPGJyPg0KDQoNCivCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoaGlkZS1pZmRlZi1yZWdpb24gZWxpZiAoMS0g KGhpZi1yYW5nZS1lbmQgcmFuZ2UpKSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIChoaWYtcmVjdXJzZS1vbiAoaGlmLXJhbmdlLXN0YXJ0IHJhbmdlKTxicj4rwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBl bGlmKSkpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoKGhpZi1yYW5nZS1lbHNlIHJh bmdlKTxicj4NCg0KDQorwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCA7OyBDYXNlIDEgLSBI aWRlICNlbGlmIGFuZCAjZWxzZSBibG9ja3MsIHJlY3Vyc2UgI2lmWDxicj7CoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgKGhpZi1oaWRlLWxpbmUgKGhpZi1yYW5nZS1lbHNlIHJhbmdlKSk8 YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWRlLWlmZGVmLXJlZ2lvbiAoaGlm LXJhbmdlLWVsc2UgcmFuZ2UpPGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICgxLSAoaGlmLXJhbmdlLWVuZCByYW5n ZSkpKTxicj4NCg0KDQrCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGhpZi1yZWN1cnNl LW9uIChoaWYtcmFuZ2Utc3RhcnQgcmFuZ2UpPGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWYtcmFuZ2UtZWxzZSByYW5n ZSkpKTxicj4twqDCoMKgIMKgwqDCoMKgwqAgKHTCoMKgwqAgwqDCoMKgIMKgwqDCoCA7IGNhc2Ug Mjxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKHQ8YnI+K8KgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgOzsgQ2FzZSAyIC0gTm8gI2Vsc2UsIGp1c3QgcmVjdXJzZSAjaWZYPGJyPg0K DQoNCsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoaGlmLXJlY3Vyc2Utb24gKGhpZi1y YW5nZS1zdGFydCByYW5nZSk8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGhpZi1yYW5nZS1lbmQgcmFuZ2UpKSkpPGJyPi3C oMKgwqDCoMKgIChjb25kICgoaGlmLXJhbmdlLWVsc2UgcmFuZ2UpwqDCoMKgIDsgY2FzZSAzPGJy Pi3CoMKgwqAgwqDCoMKgwqAgKGhpZi1oaWRlLWxpbmUgKGhpZi1yYW5nZS1lbHNlIHJhbmdlKSk8 YnI+DQoNCg0KLcKgwqDCoCDCoMKgwqDCoCAoaGlkZS1pZmRlZi1yZWdpb24gKGhpZi1yYW5nZS1z dGFydCByYW5nZSk8YnI+LcKgwqDCoCDCoMKgwqAgwqDCoMKgIMKgwqDCoCAoMS0gKGhpZi1yYW5n ZS1lbHNlIHJhbmdlKSkpPGJyPi3CoMKgwqAgwqDCoMKgwqAgKGhpZi1yZWN1cnNlLW9uIChoaWYt cmFuZ2UtZWxzZSByYW5nZSk8YnI+LcKgwqDCoCDCoMKgwqAgwqDCoMKgIMKgwqDCoMKgIChoaWYt cmFuZ2UtZW5kIHJhbmdlKSkpPGJyPi3CoMKgwqAgwqDCoMKgICh0wqDCoMKgIMKgwqDCoCDCoMKg wqAgwqDCoMKgIDsgY2FzZSA0PGJyPg0KDQoNCi3CoMKgwqAgwqDCoMKgwqAgKGhpZGUtaWZkZWYt cmVnaW9uIChwb2ludCk8YnI+LcKgwqDCoCDCoMKgwqAgwqDCoMKgIMKgwqDCoCAoMS0gKGhpZi1y YW5nZS1lbmQgcmFuZ2UpKSkpKSk8YnI+K8KgwqDCoMKgwqDCoMKgIChzZXRxIGNvbXBsZXRlIHQp KTxicj4rwqDCoMKgwqDCoCAoc2V0cSBpZi1wYXJ0IG5pbCkpPGJyPis8YnI+K8KgwqDCoCA7OyBj b21wbGV0ZSA9IHQ8YnI+wqDCoMKgwqAgKGhpZi1oaWRlLWxpbmUgKGhpZi1yYW5nZS1zdGFydCBy YW5nZSkpIDsgQWx3YXlzIGhpZGUgc3RhcnQuPGJyPg0KDQoNCsKgwqDCoMKgIChnb3RvLWNoYXIg KGhpZi1yYW5nZS1lbmQgcmFuZ2UpKTxicj7CoMKgwqDCoCAoZW5kLW9mLWxpbmUpKSk8YnI+wqA8 YnI+KyhkZWZ1biBoaWYtZXZhbHVhdGUtcmVnaW9uIChzdGFydCBlbmQpPGJyPivCoCAobGV0KiAo KHRva2VucyAoaWdub3JlLWVycm9ycyA7IFByZXZlbnQgQyBzdGF0ZW1lbnQgdGhpbmdzIGxpa2U8 YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIDsgJiMzOTtkbyB7IC4uLiB9IHdoaWxlICgwKSYjMzk7PGJyPg0KDQoNCivCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGhpZi10b2tlbml6ZSBzdGFydCBlbmQp KSk8YnI+K8KgwqDCoMKgwqDCoMKgwqAgKGV4cHIgKGFuZCB0b2tlbnM8YnI+K8KgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChjb25kaXRpb24tY2FzZSBuaWw8YnI+K8KgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGhpZi1wYXJzZS1leHAg dG9rZW5zKTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChl cnJvcjxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdG9r ZW5zKSkpKTxicj4NCg0KDQorwqDCoMKgwqDCoMKgwqDCoCAocmVzdWx0IChmdW5jYWxsIGhpZGUt aWZkZWYtZXZhbHVhdG9yIGV4cHIpKSk8YnI+K8KgwqDCoCByZXN1bHQpKTxicj4rPGJyPisoZGVm dW4gaGlmLWV2YWx1YXRlLW1hY3JvIChyc3RhcnQgcmVuZCk8YnI+K8KgICZxdW90O0V2YWx1YXRl IHRoZSBtYWNybyBleHBhbnNpb24gcmVzdWx0IGZvciBhIHJlZ2lvbi48YnI+K0lmIG5vIHJlZ2lv biBhY3RpdmUsIGZpbmQgdGhlIGN1cnJlbnQgI2lmZGVmcyBhbmQgZXZhbHVhdGUgdGhlIHJlc3Vs dC48YnI+DQoNCg0KK0N1cnJlbnRseSBpdCBzdXBwb3J0cyBvbmx5IG1hdGggY2FsY3VsYXRpb25z LCBzdHJpbmdzIG9yIGFyZ3VtZW50ZWQgbWFjcm9zIGNhbjxicj4rbm90IGJlIGV4cGFuZGVkLiZx dW90Ozxicj4rwqAgKGludGVyYWN0aXZlICZxdW90O3ImcXVvdDspPGJyPivCoCAobGV0ICgoY2Fz ZS1mb2xkLXNlYXJjaCBuaWwpKTxicj4rwqDCoMKgIChzYXZlLWV4Y3Vyc2lvbjxicj4rwqDCoMKg wqDCoCAodW5sZXNzIG1hcmstYWN0aXZlPGJyPg0KDQoNCivCoMKgwqDCoMKgwqDCoCAoc2V0cSBy c3RhcnQgbmlsIHJlbmQgbmlsKTxicj4rwqDCoMKgwqDCoMKgwqAgKGJlZ2lubmluZy1vZi1saW5l KTxicj4rwqDCoMKgwqDCoMKgwqAgKHdoZW4gKGFuZCAocmUtc2VhcmNoLWZvcndhcmQgaGlmLW1h Y3JvLWV4cHItcHJlZml4LXJlZ2V4cCBuaWwgdCk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCAoc3RyaW5nPSAmcXVvdDtkZWZpbmUmcXVvdDsgKG1hdGNoLXN0cmluZyAy KSkpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqAgKHJlLXNlYXJjaC1mb3J3YXJkIGhpZi1tYWNyb3Jl Zi1yZWdleHAgbmlsIHQpKSk8YnI+DQoNCg0KK8KgwqDCoMKgwqAgKGxldCogKChzdGFydCAob3Ig cnN0YXJ0IChwb2ludCkpKTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChlbmTCoMKgIChv ciByZW5kIChwcm9nbiAoaGlmLWVuZC1vZi1saW5lKSAocG9pbnQpKSkpPGJyPivCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgKGRlZmluZWQgbmlsKTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IChzaW1wbGUgJiMzOTt0KTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICh0b2tlbnMgKGln bm9yZS1lcnJvcnMgOyBQcmV2ZW50IEMgc3RhdGVtZW50IHRoaW5ncyBsaWtlPGJyPg0KDQoNCivC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgOyAmIzM5O2RvIHsgLi4uIH0gd2hpbGUgKDApJiMzOTs8YnI+ K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWYtdG9rZW5p emUgc3RhcnQgZW5kKSkpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGV4cHIgKG9yIChh bmQgKCZsdDs9IChsZW5ndGggdG9rZW5zKSAxKSA7IFNpbXBsZSB0b2tlbjxicj4rwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChzZXRxIGRlZmlu ZWQgKGFzc29jIChjYXIgdG9rZW5zKSBoaWRlLWlmZGVmLWVudikpPGJyPg0KDQoNCivCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKHNldHEgc2lt cGxlIChhdG9tIChoaWYtbG9va3VwIChjYXIgdG9rZW5zKSkpKTxicj4rwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWYtbG9va3VwIChjYXIg dG9rZW5zKSkpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCAoYW5kIHRva2Vuczxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIChjb25kaXRpb24tY2FzZSBuaWw8YnI+DQoNCg0KK8KgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWYt cGFyc2UtZXhwIHRva2Vucyk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGVycm9yPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgbmlsKSkpKSk8YnI+K8KgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCAocmVzdWx0IChmdW5jYWxsIGhpZGUtaWZkZWYtZXZhbHVhdG9y IGV4cHIpKTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChleHByc3RyaW5nIChyZXBsYWNl LXJlZ2V4cC1pbi1zdHJpbmc8YnI+DQoNCg0KK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIDs7IFRyaW0gb2ZmIGxlYWRpbmcvdHJhaWxpbmcgd2hpdGVz PGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAm cXVvdDteWyBcdF0qXFwoW14gXHRdK1xcKVsgXHRdKiZxdW90OyAmcXVvdDtcXDEmcXVvdDs8YnI+ K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChyZXBs YWNlLXJlZ2V4cC1pbi1zdHJpbmc8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgJnF1b3Q7XFwoLy8uKlxcKSZxdW90OyAmcXVvdDsmcXVvdDsg OyBUcmltIG9mZiBlbmQtb2YtbGluZSBjb21tZW50czxicj4NCg0KDQorwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoYnVmZmVyLXN1YnN0cmluZy1u by1wcm9wZXJ0aWVzIHN0YXJ0IGVuZCkpKSkpPGJyPivCoMKgwqDCoMKgwqDCoCAoY29uZDxicj4r wqDCoMKgwqDCoMKgwqDCoCAoKGFuZCAoJmx0Oz0gKGxlbmd0aCB0b2tlbnMpIDEpIHNpbXBsZSkg OyBTaW1wbGUgdG9rZW48YnI+K8KgwqDCoMKgwqDCoMKgwqDCoCAoaWYgZGVmaW5lZDxicj4rwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKG1lc3NhZ2UgJnF1b3Q7JVMgJmx0Oz0gYCVzJiMzOTsm cXVvdDsgcmVzdWx0IGV4cHJzdHJpbmcpPGJyPg0KDQoNCivCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IChtZXNzYWdlICZxdW90O2AlcyYjMzk7IGlzIG5vdCBkZWZpbmVkJnF1b3Q7IGV4cHJzdHJpbmcp KSk8YnI+K8KgwqDCoMKgwqDCoMKgwqAgKChpbnRlZ2VycCByZXN1bHQpPGJyPivCoMKgwqDCoMKg wqDCoMKgwqAgKGlmIChvciAoPSAwIHJlc3VsdCkgKD0gMSByZXN1bHQpKTxicj4rwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgKG1lc3NhZ2UgJnF1b3Q7JVMgJmx0Oz0gYCVzJiMzOTsmcXVvdDsg cmVzdWx0IGV4cHJzdHJpbmcpPGJyPg0KDQoNCivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChtZXNz YWdlICZxdW90OyVTICgweCV4KSAmbHQ7PSBgJXMmIzM5OyZxdW90OyByZXN1bHQgcmVzdWx0IGV4 cHJzdHJpbmcpKSk8YnI+K8KgwqDCoMKgwqDCoMKgwqAgKChudWxsIHJlc3VsdCkgKG1lc3NhZ2Ug JnF1b3Q7JVMgJmx0Oz0gYCVzJiMzOTsmcXVvdDsgJiMzOTtmYWxzZSBleHByc3RyaW5nKSk8YnI+ K8KgwqDCoMKgwqDCoMKgwqAgKChlcSB0IHJlc3VsdCkgKG1lc3NhZ2UgJnF1b3Q7JVMgJmx0Oz0g YCVzJiMzOTsmcXVvdDsgJiMzOTt0cnVlIGV4cHJzdHJpbmcpKTxicj4NCg0KDQorwqDCoMKgwqDC oMKgwqDCoCAodCAobWVzc2FnZSAmcXVvdDslUyAmbHQ7PSBgJXMmIzM5OyZxdW90OyByZXN1bHQg ZXhwcnN0cmluZykpKTxicj4rwqDCoMKgwqDCoMKgwqAgcmVzdWx0KSkpKTxicj4rPGJyPsKgKGRl ZnVuIGhpZi1wYXJzZS1tYWNyby1hcmdsaXN0IChzdHIpPGJyPsKgwqAgJnF1b3Q7UGFyc2UgYXJn dW1lbnQgbGlzdCBmb3JtYXR0ZWQgYXMgJiMzOTsoIGFyZzEgWyAsIGFyZ25dIFsuLi5dICkmIzM5 Oy48YnI+DQoNCg0KwqBUaGUgJiMzOTsuLi4mIzM5OyBpcyBhbHNvIGluY2x1ZGVkLsKgIFJldHVy biBhIGxpc3Qgb2YgdGhlIGFyZ3VtZW50cywgaWYgJiMzOTsuLi4mIzM5OyBleGlzdHMgdGhlPGJy PkBAIC0xNTI5LDcgKzE3NTEsMTIgQEAgZmlyc3QgYXJnIHdpbGwgYmUgYGhpZi1ldGMmIzM5Oy4m cXVvdDs8YnI+wqBJdCBkb2VzIG5vdCBkbyB0aGUgd29yayB0aGF0JiMzOTtzIHBvaW50bGVzcyB0 byByZWRvIG9uIGEgcmVjdXJzaXZlIGVudHJ5LiZxdW90Ozxicj4NCg0KDQrCoMKgIDs7IChtZXNz YWdlICZxdW90O2hpZGUtaWZkZWYtZ3V0cyZxdW90Oyk8YnI+wqDCoCAoc2F2ZS1leGN1cnNpb248 YnI+LcKgwqDCoCAobGV0ICgoY2FzZS1mb2xkLXNlYXJjaCBuaWwpPGJyPivCoMKgwqAgKGxldCog KChjYXNlLWZvbGQtc2VhcmNoIHQpIDsgSWdub3JlIGNhc2UgZm9yIGBoaWRlLWlmZGVmLWhlYWRl ci1yZWdleHAmIzM5Ozxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGV4cGFuZC1oZWFkZXIgKGFu ZCBoaWRlLWlmZGVmLWV4cGFuZC1yZWluY2x1c2lvbi1wcm90ZWN0aW9uPGJyPg0KDQoNCivCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg KHN0cmluZy1tYXRjaCBoaWRlLWlmZGVmLWhlYWRlci1yZWdleHA8YnI+K8KgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgKGJ1ZmZlci1maWxlLW5hbWUpKTxicj4rwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICh6ZXJvcCBoaWYt cmVjdXJzZS1sZXZlbCkpKTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGNhc2UtZm9sZC1zZWFy Y2ggbmlsKTxicj4NCg0KDQrCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIG1pbiBtYXgpPGJyPsKgwqDC oMKgwqDCoCAoZ290by1jaGFyIChwb2ludC1taW4pKTxicj7CoMKgwqDCoMKgwqAgKHNldGYgbWlu IChwb2ludCkpPGJyPkBAIC0xNTM3LDcgKzE3NjQsNyBAQCBJdCBkb2VzIG5vdCBkbyB0aGUgd29y ayB0aGF0JiMzOTtzIHBvaW50bGVzcyB0byByZWRvIG9uIGEgcmVjdXJzaXZlIGVudHJ5LiZxdW90 Ozxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKHNldGYgbWF4IChoaWYtZmluZC1hbnktaWZY KSk8YnI+DQoNCg0KwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWYtYWRkLW5ldy1kZWZpbmVz IG1pbiBtYXgpPGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoaWYgbWF4PGJyPi3CoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGhpZi1wb3NzaWJseS1oaWRlKSk8YnI+K8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoaGlmLXBvc3NpYmx5LWhpZGUgZXhwYW5kLWhl YWRlcikpPGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoc2V0ZiBtaW4gKHBvaW50KSk8YnI+ wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHdoaWxlIG1heCkpKSk8YnI+DQoNCg0KwqA8YnI+QEAg LTE1ODQsMTcgKzE4MTEsMzAgQEAgSXQgZG9lcyBub3QgZG8gdGhlIHdvcmsgdGhhdCYjMzk7cyBw b2ludGxlc3MgdG8gcmVkbyBvbiBhIHJlY3Vyc2l2ZSBlbnRyeS4mcXVvdDs8YnI+wqDCoMKgwqDC oMKgwqDCoMKgwqAgKG92ZXJsYXktcHV0IG92ZXJsYXkgJiMzOTtmYWNlIG5pbCk8YnI+wqDCoMKg wqDCoMKgwqDCoMKgwqAgKG92ZXJsYXktcHV0IG92ZXJsYXkgJiMzOTtpbnZpc2libGUgJiMzOTto aWRlLWlmZGVmKSkpKSkpPGJyPg0KDQoNCsKgPGJyPi0oZGVmdW4gaGlkZS1pZmRlZi1kZWZpbmUg KHZhcik8YnI+LcKgICZxdW90O0RlZmluZSBhIFZBUiBzbyB0aGF0ICNpZmRlZiBWQVIgd291bGQg YmUgaW5jbHVkZWQuJnF1b3Q7PGJyPi3CoCAoaW50ZXJhY3RpdmUgJnF1b3Q7U0RlZmluZSB3aGF0 PyAmcXVvdDspPGJyPi3CoCAoaGlmLXNldC12YXIgdmFyIDEpPGJyPisoZGVmdW4gaGlkZS1pZmRl Zi1kZWZpbmUgKHZhciAmYW1wO29wdGlvbmFsIHZhbCk8YnI+DQoNCg0KK8KgICZxdW90O0RlZmlu ZSBhIFZBUiB0byBWQUwgKERFRkFVTFQgMSkgaW4gYGhpZGUtaWZkZWYtZW52JiMzOTsuPGJyPitU aGlzIGFsbG93cyAjaWZkZWYgVkFSIHRvIGJlIGhpZGRlbi4mcXVvdDs8YnI+K8KgIChpbnRlcmFj dGl2ZTxicj4rwqDCoCAobGV0KiAoKGRlZmF1bHQgKHNhdmUtZXhjdXJzaW9uPGJyPivCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChiZWdpbm5pbmctb2YtbGluZSk8YnI+ K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGNvbmQgKChsb29raW5n LWF0IGhpZi1pZngtZWxzZS1lbmRpZi1yZWdleHApPGJyPg0KDQoNCivCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGZvcndhcmQtd29yZCAyKTxi cj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IChjdXJyZW50LXdvcmQgJiMzOTtzdHJpY3QpKTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAodDxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIG5pbCkpKSk8YnI+K8KgwqDCoMKgwqDC oMKgwqDCoCAodmFyIChyZWFkLW1pbmlidWZmZXIgJnF1b3Q7RGVmaW5lIHdoYXQ/ICZxdW90OyBk ZWZhdWx0KSk8YnI+DQoNCg0KK8KgwqDCoMKgwqDCoMKgwqDCoCAodmFsIChyZWFkLWZyb20tbWlu aWJ1ZmZlciAoZm9ybWF0ICZxdW90O1NldCAlcyB0bz8gKGRlZmF1bHQgMSk6ICZxdW90OyB2YXIp PGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgbmlsIG5pbCB0IG5pbCAmcXVvdDsxJnF1b3Q7KSkpPGJyPivC oMKgwqDCoCAobGlzdCB2YXIgdmFsKSkpPGJyPivCoCAoaGlmLXNldC12YXIgdmFyIChvciB2YWwg MSkpPGJyPg0KDQoNCivCoCAobWVzc2FnZSAmcXVvdDslcyBzZXQgdG8gJXMmcXVvdDsgdmFyIChv ciB2YWwgMSkpPGJyPivCoCAoc2xlZXAtZm9yIDEpPGJyPsKgwqAgKGlmIGhpZGUtaWZkZWYtaGlk aW5nIChoaWRlLWlmZGVmcykpKTxicj7CoDxicj7CoChkZWZ1biBoaWYtdW5kZWZpbmUtc3ltYm9s ICh2YXIpPGJyPsKgwqAgKHNldHEgaGlkZS1pZmRlZi1lbnY8YnI+wqDCoMKgwqDCoMKgwqDCoCAo ZGVsZXRlIChhc3NvYyB2YXIgaGlkZS1pZmRlZi1lbnYpIGhpZGUtaWZkZWYtZW52KSkpPGJyPg0K DQoNCsKgPGJyPi08YnI+wqAoZGVmdW4gaGlkZS1pZmRlZi11bmRlZiAoc3RhcnQgZW5kKTxicj7C oMKgICZxdW90O1VuZGVmaW5lIGEgVkFSIHNvIHRoYXQgI2lmZGVmIFZBUiB3b3VsZCBub3QgYmUg aW5jbHVkZWQuJnF1b3Q7PGJyPsKgwqAgKGludGVyYWN0aXZlICZxdW90O3ImcXVvdDspPGJyPkBA IC0xNjE1LDIwICsxODU1LDIzIEBAIEl0IGRvZXMgbm90IGRvIHRoZSB3b3JrIHRoYXQmIzM5O3Mg cG9pbnRsZXNzIHRvIHJlZG8gb24gYSByZWN1cnNpdmUgZW50cnkuJnF1b3Q7PGJyPg0KDQoNCsKg QXNzdW1lIHRoYXQgZGVmaW5lZCBzeW1ib2xzIGhhdmUgYmVlbiBhZGRlZCB0byBgaGlkZS1pZmRl Zi1lbnYmIzM5Oy48YnI+wqBUaGUgdGV4dCBoaWRkZW4gaXMgdGhlIHRleHQgdGhhdCB3b3VsZCBu b3QgYmUgaW5jbHVkZWQgYnkgdGhlIEM8YnI+wqBwcmVwcm9jZXNzb3IgaWYgaXQgd2VyZSBnaXZl biB0aGUgZmlsZSB3aXRoIHRob3NlIHN5bWJvbHMgZGVmaW5lZC48YnI+K1dpdGggcHJlZml4IGNv bW1hbmQgcHJlc2VudHMgaXQgd2lsbCBhbHNvIGhpZGUgdGhlICNpZmRlZnMgdGhlbXNlbHZlcy48 YnI+DQoNCg0KwqA8YnI+wqBUdXJuIG9mZiBoaWRpbmcgYnkgY2FsbGluZyBgc2hvdy1pZmRlZnMm IzM5Oy4mcXVvdDs8YnI+wqA8YnI+wqDCoCAoaW50ZXJhY3RpdmUpPGJyPi3CoCAobWVzc2FnZSAm cXVvdDtIaWRpbmcuLi4mcXVvdDspPGJyPivCoCAobGV0ICgoaGlkZS1pZmRlZi1saW5lcyBjdXJy ZW50LXByZWZpeC1hcmcpKTxicj4rwqDCoMKgIChvciBub21zZzxicj4rwqDCoMKgwqDCoMKgwqAg KG1lc3NhZ2UgJnF1b3Q7SGlkaW5nLi4uJnF1b3Q7KSk8YnI+DQoNCg0KwqDCoMKgwqAgKHNldHEg aGlmLW91dHNpZGUtcmVhZC1vbmx5IGJ1ZmZlci1yZWFkLW9ubHkpPGJyPi3CoCAodW5sZXNzIGhp ZGUtaWZkZWYtbW9kZSAoaGlkZS1pZmRlZi1tb2RlIDEpKSA7IHR1cm4gb24gaGlkZS1pZmRlZi1t b2RlPGJyPivCoMKgwqAgKHVubGVzcyBoaWRlLWlmZGVmLW1vZGUgKGhpZGUtaWZkZWYtbW9kZSAx KSkgOyBUdXJuIG9uIGhpZGUtaWZkZWYtbW9kZTxicj7CoMKgwqDCoCAoaWYgaGlkZS1pZmRlZi1o aWRpbmc8YnI+DQoNCg0KwqDCoMKgwqDCoMKgwqDCoCAoc2hvdy1pZmRlZnMpKcKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDsgT3RoZXJ3aXNlLCBkZWVwIGNvbmZ1c2lvbi48 YnI+wqDCoMKgwqAgKHNldHEgaGlkZS1pZmRlZi1oaWRpbmcgdCk8YnI+wqDCoMKgwqAgKGhpZGUt aWZkZWYtZ3V0cyk8YnI+wqDCoMKgwqAgKHNldHEgYnVmZmVyLXJlYWQtb25seSAob3IgaGlkZS1p ZmRlZi1yZWFkLW9ubHkgaGlmLW91dHNpZGUtcmVhZC1vbmx5KSk8YnI+wqDCoMKgwqAgKG9yIG5v bXNnPGJyPg0KDQoNCi3CoMKgwqDCoMKgIChtZXNzYWdlICZxdW90O0hpZGluZyBkb25lJnF1b3Q7 KSkpPGJyPivCoMKgwqDCoMKgwqDCoCAobWVzc2FnZSAmcXVvdDtIaWRpbmcgZG9uZSZxdW90Oykp KSk8YnI+wqA8YnI+wqA8YnI+wqAoZGVmdW4gc2hvdy1pZmRlZnMgKCk8YnI+QEAgLTE2NjAsOSAr MTkwMywxNSBAQCBSZXR1cm4gYXMgKFRPUCAuIEJPVFRPTSkgdGhlIGV4dGVudCBvZiBpZmRlZiBi bG9jay4mcXVvdDs8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAobWluIG1heC1ib3R0 b20gKDEtIChwb2ludCkpKSkpKSk8YnI+DQoNCg0KwqA8YnI+wqA8YnI+LShkZWZ1biBoaWRlLWlm ZGVmLWJsb2NrICgpPGJyPi3CoCAmcXVvdDtIaWRlIHRoZSBpZmRlZiBibG9jayAodHJ1ZSBvciBm YWxzZSBwYXJ0KSBlbmNsb3Npbmcgb3IgYmVmb3JlIHRoZSBjdXJzb3IuJnF1b3Q7PGJyPi3CoCAo aW50ZXJhY3RpdmUpPGJyPisoZGVmdW4gaGlkZS1pZmRlZi1ibG9jayAoJmFtcDtvcHRpb25hbCBz dGFydCBlbmQpPGJyPivCoCAmcXVvdDtIaWRlIHRoZSBpZmRlZiBibG9jayAodHJ1ZSBvciBmYWxz ZSBwYXJ0KSBlbmNsb3Npbmcgb3IgYmVmb3JlIHRoZSBjdXJzb3IuPGJyPg0KDQoNCitXaXRoIHBy ZWZpeCBjb21tYW5kIHByZXNlbnRzIGl0IHdpbGwgYWxzbyBoaWRlIHRoZSAjaWZkZWZzIHRoZW1z ZWx2ZXMuJnF1b3Q7PGJyPivCoCAoaW50ZXJhY3RpdmUgJnF1b3Q7ciZxdW90Oyk8YnI+K8KgIChs ZXQgKChoaWRlLWlmZGVmLWxpbmVzIGN1cnJlbnQtcHJlZml4LWFyZykpPGJyPivCoMKgwqAgKGlm IG1hcmstYWN0aXZlPGJyPivCoMKgwqDCoMKgwqDCoCAobGV0ICgoaGlmLXJlY3Vyc2UtbGV2ZWwg KDErIGhpZi1yZWN1cnNlLWxldmVsKSkpPGJyPg0KDQoNCivCoMKgwqDCoMKgwqDCoMKgwqAgKGhp Zi1yZWN1cnNlLW9uIHN0YXJ0IGVuZCB0KTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgIChzZXRxIG1h cmstYWN0aXZlIG5pbCkpPGJyPsKgwqDCoMKgwqDCoCAodW5sZXNzIGhpZGUtaWZkZWYtbW9kZSAo aGlkZS1pZmRlZi1tb2RlIDEpKTxicj7CoMKgwqDCoMKgwqAgKGxldCAoKHRvcC1ib3R0b20gKGhp Zi1maW5kLWlmZGVmLWJsb2NrKSkpPGJyPsKgwqDCoMKgwqDCoMKgwqAgKGhpZGUtaWZkZWYtcmVn aW9uIChjYXIgdG9wLWJvdHRvbSkgKGNkciB0b3AtYm90dG9tKSk8YnI+DQoNCg0KQEAgLTE2NzAs MTIgKzE5MTksMjYgQEAgUmV0dXJuIGFzIChUT1AgLiBCT1RUT00pIHRoZSBleHRlbnQgb2YgaWZk ZWYgYmxvY2suJnF1b3Q7PGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWYtaGlkZS1saW5lIChj YXIgdG9wLWJvdHRvbSkpPGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWYtaGlkZS1saW5lICgx KyAoY2RyIHRvcC1ib3R0b20pKSkpPGJyPsKgwqDCoMKgwqDCoMKgwqAgKHNldHEgaGlkZS1pZmRl Zi1oaWRpbmcgdCkpPGJyPg0KDQoNCi3CoCAoc2V0cSBidWZmZXItcmVhZC1vbmx5IChvciBoaWRl LWlmZGVmLXJlYWQtb25seSBoaWYtb3V0c2lkZS1yZWFkLW9ubHkpKSk8YnI+K8KgwqDCoMKgwqAg KHNldHEgYnVmZmVyLXJlYWQtb25seTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAob3IgaGlk ZS1pZmRlZi1yZWFkLW9ubHkgaGlmLW91dHNpZGUtcmVhZC1vbmx5KSkpKSk8YnI+wqA8YnI+LShk ZWZ1biBzaG93LWlmZGVmLWJsb2NrICgpPGJyPisoZGVmdW4gc2hvdy1pZmRlZi1ibG9jayAoJmFt cDtvcHRpb25hbCBzdGFydCBlbmQpPGJyPg0KDQoNCsKgwqAgJnF1b3Q7U2hvdyB0aGUgaWZkZWYg YmxvY2sgKHRydWUgb3IgZmFsc2UgcGFydCkgZW5jbG9zaW5nIG9yIGJlZm9yZSB0aGUgY3Vyc29y LiZxdW90Ozxicj4twqAgKGludGVyYWN0aXZlKTxicj4twqAgKGxldCAoKHRvcC1ib3R0b20gKGhp Zi1maW5kLWlmZGVmLWJsb2NrKSkpPGJyPivCoCAoaW50ZXJhY3RpdmUgJnF1b3Q7ciZxdW90Oyk8 YnI+K8KgIChpZiBtYXJrLWFjdGl2ZTxicj4rwqDCoMKgwqDCoCAocHJvZ248YnI+DQoNCg0KK8Kg wqDCoMKgwqDCoMKgIChkb2xpc3QgKG8gKG92ZXJsYXlzLWluIHN0YXJ0IGVuZCkpPGJyPivCoMKg wqDCoMKgwqDCoMKgwqAgKGlmIChvdmVybGF5LWdldCBvICYjMzk7aGlkZS1pZmRlZik8YnI+K8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChkZWxldGUtb3ZlcmxheSBvKSkpPGJyPivCoMKgwqDC oMKgwqDCoCAoc2V0cSBtYXJrLWFjdGl2ZSBuaWwpKTxicj4rwqDCoMKgIChsZXQgKCh0b3AtYm90 dG9tIChjb25kaXRpb24tY2FzZSBuaWw8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWYtZmluZC1pZmRlZi1ibG9jayk8YnI+DQoNCg0KK8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGVycm9yPGJyPivC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgbmlsKSkpPGJy PivCoMKgwqDCoMKgwqDCoMKgwqAgKG92cnMgKG92ZXJsYXlzLWluIChtYXggKHBvaW50LW1pbikg KDEtIChwb2ludCkpKTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgKG1pbiAocG9pbnQtbWF4KSAoMSsgKHBvaW50KSkpKSk8YnI+K8Kg wqDCoMKgwqDCoMKgwqDCoCAoZGVsIG5pbCkpPGJyPg0KDQoNCivCoMKgwqDCoMKgIChpZiB0b3At Ym90dG9tPGJyPsKgwqDCoMKgIChpZiBoaWRlLWlmZGVmLWxpbmVzPGJyPsKgwqDCoMKgwqDCoMKg wqAgKGhpZi1zaG93LWlmZGVmLXJlZ2lvbjxicj7CoMKgwqDCoMKgwqDCoMKgwqAgKHNhdmUtZXhj dXJzaW9uPGJyPkBAIC0xNjgzLDcgKzE5NDYsMTUgQEAgUmV0dXJuIGFzIChUT1AgLiBCT1RUT00p IHRoZSBleHRlbnQgb2YgaWZkZWYgYmxvY2suJnF1b3Q7PGJyPsKgwqDCoMKgwqDCoMKgwqDCoCAo c2F2ZS1leGN1cnNpb248YnI+DQoNCg0KwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoZ290by1jaGFy ICgxKyAoY2RyIHRvcC1ib3R0b20pKSk8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoaGlmLWVu ZC1vZi1saW5lKSAocG9pbnQpKSk8YnI+LcKgwqDCoMKgwqAgKGhpZi1zaG93LWlmZGVmLXJlZ2lv biAoMS0gKGNhciB0b3AtYm90dG9tKSkgKGNkciB0b3AtYm90dG9tKSkpKSk8YnI+K8KgwqDCoMKg wqAgKHNldGYgZGVsIChoaWYtc2hvdy1pZmRlZi1yZWdpb248YnI+K8KgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgICgxLSAoY2FyIHRvcC1ib3R0b20pKSAoY2RyIHRvcC1ib3R0b20pKSkp KTxicj4NCg0KDQorwqDCoMKgwqDCoCAoaWYgKG5vdCAoYW5kIHRvcC1ib3R0b208YnI+K8KgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGRlbCkpPGJyPivCoMKgwqDCoMKgwqDC oMKgwqAgKGRvbGlzdCAobyBvdnJzKTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCA7Oyhkb2xp c3QgKG8gKG92ZXJsYXlzLWluICgxLSAocG9pbnQpKSAoMSsgKHBvaW50KSkpKTxicj4rwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCA7O8KgwqAgKGlmIChvdmVybGF5LWdldCBvICYjMzk7aGlkZS1pZmRl ZikgKG1lc3NhZ2UgJnF1b3Q7JVMmcXVvdDsgbykpKTxicj4NCg0KDQorwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCAoaWYgKG92ZXJsYXktZ2V0IG8gJiMzOTtoaWRlLWlmZGVmKTxicj4rwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIChkZWxldGUtb3ZlcmxheSBvKSkpKSkpKTxicj7CoDxicj7C oDxicj7CoDs7O8KgIGRlZmluaXRpb24gYWxpc3Qgc3VwcG9ydCA8YnI+PC9kaXY+PC9kaXY+PC9k aXY+PC9kaXY+PC9kaXY+PC9kaXY+PC9kaXY+PC9kaXY+PC9kaXY+DQo= --001a1136505610053e04fd0eaeaf--