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: Thu, 3 Jul 2014 10:37:17 +0800 Message-ID: References: <75lhsh7qb8.fsf@fencepost.gnu.org> <82lhsdtw6o.fsf@fencepost.gnu.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=047d7bf0d57885d56104fd40e578 X-Trace: ger.gmane.org 1404355169 28468 80.91.229.3 (3 Jul 2014 02:39:29 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 3 Jul 2014 02:39:29 +0000 (UTC) Cc: 17854@debbugs.gnu.org To: Glenn Morris Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Thu Jul 03 04:39:21 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 1X2Wvh-0005LT-8e for geb-bug-gnu-emacs@m.gmane.org; Thu, 03 Jul 2014 04:39:21 +0200 Original-Received: from localhost ([::1]:57386 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X2Wvg-0001A1-Pz for geb-bug-gnu-emacs@m.gmane.org; Wed, 02 Jul 2014 22:39:20 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:52263) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X2WvW-000194-KZ for bug-gnu-emacs@gnu.org; Wed, 02 Jul 2014 22:39:16 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X2WvQ-0005xJ-7F for bug-gnu-emacs@gnu.org; Wed, 02 Jul 2014 22:39:10 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:49783) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X2WvQ-0005xE-1m for bug-gnu-emacs@gnu.org; Wed, 02 Jul 2014 22:39:04 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1X2WvP-0000Es-91 for bug-gnu-emacs@gnu.org; Wed, 02 Jul 2014 22:39:03 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Luke Lee Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 03 Jul 2014 02:39: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.1404355097793 (code B ref 17854); Thu, 03 Jul 2014 02:39:02 +0000 Original-Received: (at 17854) by debbugs.gnu.org; 3 Jul 2014 02:38:17 +0000 Original-Received: from localhost ([127.0.0.1]:40933 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1X2Wua-0000CY-GT for submit@debbugs.gnu.org; Wed, 02 Jul 2014 22:38:17 -0400 Original-Received: from mail-pa0-f42.google.com ([209.85.220.42]:51504) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1X2WuR-0000Bj-Il for 17854@debbugs.gnu.org; Wed, 02 Jul 2014 22:38:08 -0400 Original-Received: by mail-pa0-f42.google.com with SMTP id lj1so13668923pab.29 for <17854@debbugs.gnu.org>; Wed, 02 Jul 2014 19:37:57 -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 :cc:content-type; bh=QUJigJypyoEPhbo3Rj7Xf7EsEBiW1ai2CcupGZtFOFA=; b=valZYmtf6lt2Q8XQuSijgmU/IhoFPHUuGvejSIK43qwP7v+PwbpdRPtsAWO1r3S3nE PaUlZi1ICPWQnGgQocb5EOtNo8Nz6A+NtHZ23JD7y01GGWpMHkc8VoKqjHBnbk5srsIA RilYzT+upOpPEK+fRSm1fS2Zb2c0D8nGYwgsZCPQRzJwKhNRIQ0xirysnHS7f/f7LWNa awrKF+i9++zicOIYINRqILW25tpukv9j9ShXbyn1+0TcZbfBniQUUD3UyRl0OqYr3G6k cHsdeH9YWGNFyM2pTp+eHQLAHOdijc5dh0Zl3dzSKySVbYcwjuKPqoUEJpa2hy/tRgB5 5rfQ== X-Received: by 10.66.192.73 with SMTP id he9mr1778763pac.88.1404355077328; Wed, 02 Jul 2014 19:37:57 -0700 (PDT) Original-Received: by 10.70.89.165 with HTTP; Wed, 2 Jul 2014 19:37:17 -0700 (PDT) In-Reply-To: <82lhsdtw6o.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:91130 Archived-At: --047d7bf0d57885d56104fd40e578 Content-Type: text/plain; charset=UTF-8 >>> >>>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. > > I don't follow. Why not just pick one? I fixed that. Just use `interactive "P\nr"' then it works. All other suggestions are followed, please take a look at the updated patch as follows in plain texts. ==================================== diff --git a/lisp/progmodes/hideif.el b/lisp/progmodes/hideif.el index f6562f3..ed76bd6 100644 --- a/lisp/progmodes/hideif.el +++ b/lisp/progmodes/hideif.el @@ -141,6 +141,36 @@ :type 'string :version "24.5") +(defcustom hide-ifdef-expand-reinclusion-protection t + "Non-nil means don't hide an entire header file enclosed 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.5") + +(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.5") + (defvar hide-ifdef-mode-submap ;; Set up the submap that goes after the prefix key. (let ((map (make-sparse-keymap))) @@ -153,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) @@ -217,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.") @@ -234,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. @@ -260,8 +301,18 @@ 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)) + ;; Some C/C++ headers might have other ways to prevent reinclusion and + ;; thus would like `hide-ifdef-expand-reinclusion-protection' to be nil. + (set (make-local-variable 'hide-ifdef-expand-reinclusion-protection) + (default-value 'hide-ifdef-expand-reinclusion-protection)) (set (make-local-variable 'hide-ifdef-hiding) (default-value 'hide-ifdef-hiding)) (set (make-local-variable 'hif-outside-read-only) buffer-read-only) @@ -280,6 +331,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." @@ -299,16 +358,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)) @@ -317,7 +424,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) === @@ -376,10 +485,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 "\\(" @@ -500,6 +607,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))) @@ -573,7 +682,7 @@ that form should be displayed.") (defun hif-expand-token-list (tokens &optional macroname expand_list) "Perform expansion on TOKENS till everything expanded. Self-reference (directly or indirectly) tokens are not expanded. -EXPAND_LIST is the list of macro names currently being expanded, use for +EXPAND_LIST is the list of macro names currently being expanded, used for detecting self-reference." (catch 'self-referencing (let ((expanded nil) @@ -1174,13 +1283,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) @@ -1274,26 +1386,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. @@ -1302,19 +1413,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 @@ -1324,7 +1439,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. @@ -1339,70 +1454,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 @@ -1530,7 +1755,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)) @@ -1538,7 +1768,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)))) @@ -1585,17 +1815,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") @@ -1616,20 +1859,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 () @@ -1661,9 +1907,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 arg start end) + "Hide the ifdef block (true or false part) enclosing or before the cursor. +With optional prefix agument ARG, also hide the #ifdefs themselves." + (interactive "P\nr") + (let ((hide-ifdef-lines 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)) @@ -1671,12 +1923,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 @@ -1684,7 +1950,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 --047d7bf0d57885d56104fd40e578 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+PGRpdj48ZGl2PiZndDsmZ3Q7Jmd0Ozxicj4mZ3Q7Jmd0OyZndDtTdWdn ZXN0aW9uOjxicj4mZ3Q7Jmd0OyZndDsmcXVvdDtXaXRoIG9wdGlvbmFsIHByZWZpeCBhZ3VtZW50 IEFSRywgYWxzbyBoaWRlIHRoZSAjaWZkZWZzIHRoZW1zZWx2ZXMuJnF1b3Q7PGJyPiZndDsmZ3Q7 PGJyPiZndDsmZ3Q7IEl0JiMzOTtzIG5pY2UgYnV0IEkgY2FuIG1ha2UgaXQgd29yayB3aXRoIGVp dGhlciBgaW50ZXJhY3RpdmUgJnF1b3Q7UHImcXVvdDsmIzM5OyBvcjxicj4NCg0KDQomZ3Q7Jmd0 OyBgaW50ZXJhY3RpdmUgJnF1b3Q7clAmcXVvdDsgc28gSSBrZWVwIGl0IHVuY2hhbmdlZC48YnI+ Jmd0Ozxicj4mZ3Q7IEkgZG9uJiMzOTt0IGZvbGxvdy4gV2h5IG5vdCBqdXN0IHBpY2sgb25lPzxi cj48YnI+SSBmaXhlZCB0aGF0LiBKdXN0IHVzZSBgaW50ZXJhY3RpdmUgJnF1b3Q7UFxuciZxdW90 OyYjMzk7IHRoZW4gaXQgd29ya3MuPGJyPjwvZGl2Pjxicj48L2Rpdj48ZGl2Pg0KDQpBbGwgb3Ro ZXIgc3VnZ2VzdGlvbnMgYXJlIGZvbGxvd2VkLCBwbGVhc2UgdGFrZSBhIGxvb2sgYXQgdGhlIHVw ZGF0ZWQ8YnI+PC9kaXY+PGRpdj5wYXRjaCBhcyBmb2xsb3dzIGluIHBsYWluIHRleHRzLjxicj48 L2Rpdj48ZGl2PjxkaXY+DQo8YnI+PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PGJyPjxicj5kaWZmIC0tZ2l0IGEvbGlzcC9wcm9nbW9kZXMvaGlkZWlmLmVsIGIvbGlzcC9wcm9n bW9kZXMvaGlkZWlmLmVsPGJyPmluZGV4IGY2NTYyZjMuLmVkNzZiZDYgMTAwNjQ0PGJyPi0tLSBh L2xpc3AvcHJvZ21vZGVzL2hpZGVpZi5lbDxicj4rKysgYi9saXNwL3Byb2dtb2Rlcy9oaWRlaWYu ZWw8YnI+QEAgLTE0MSw2ICsxNDEsMzYgQEA8YnI+DQoNCsKgwqAgOnR5cGUgJiMzOTtzdHJpbmc8 YnI+wqDCoCA6dmVyc2lvbiAmcXVvdDsyNC41JnF1b3Q7KTxicj7CoDxicj4rKGRlZmN1c3RvbSBo aWRlLWlmZGVmLWV4cGFuZC1yZWluY2x1c2lvbi1wcm90ZWN0aW9uIHQ8YnI+K8KgICZxdW90O05v bi1uaWwgbWVhbnMgZG9uJiMzOTt0IGhpZGUgYW4gZW50aXJlIGhlYWRlciBmaWxlIGVuY2xvc2Vk IGJ5ICNpZm5kZWYuLi4jZW5kaWYuPGJyPitNb3N0IEMvQysrIGhlYWRlcnMgYXJlIHVzdWFsbHkg d3JhcHBlZCB3aXRoIGlmZGVmcyB0byBwcmV2ZW50IHJlLWluY2x1c2lvbjo8YnI+DQoNCis8YnI+ K8KgIC0tLS0tIGJlZ2lubmluZyBvZiBmaWxlIC0tLS0tPGJyPivCoCAjaWZuZGVmIF9YWFhfSEVB REVSX0ZJTEVfSU5DTFVERURfPGJyPivCoCAjZGVmaW5lIF9YWFhfSEVBREVSX0ZJTEVfSU5DTFVE RURfPGJyPivCoMKgwqDCoCB4eHg8YnI+K8KgwqDCoMKgIHh4eDxicj4rwqDCoMKgwqAgeHh4Li4u PGJyPivCoCAjZW5kaWY8YnI+K8KgIC0tLS0tIGVuZCBvZiBmaWxlIC0tLS0tPGJyPis8YnI+K1Ro ZSBmaXJzdCB0aW1lIHdlIHZpc2l0IHN1Y2ggYSBmaWxlLCBfWFhYX0hFQURFUl9GSUxFX0lOQ0xV REVEXyBpczxicj4NCg0KK3VuZGVmaW5lZCwgYW5kIHNvIG5vdGhpbmcgaXMgaGlkZGVuLsKgIFRo ZSBuZXh0IHRpbWUgd2UgdmlzaXQgaXQsIGV2ZXJ5dGhpbmcgd2lsbDxicj4rYmUgaGlkZGVuLjxi cj4rPGJyPitUaGlzIGJlaGF2aW9yIGlzIGdlbmVyYWxseSB1bmRlc2lyYWJsZS7CoCBJZiB0aGlz IG9wdGlvbiBpcyBub24tbmlsLCB0aGUgb3V0ZXJtb3N0PGJyPisjaWYgaXMgYWx3YXlzIHZpc2li bGUuJnF1b3Q7PGJyPg0KDQorwqAgOnR5cGUgJiMzOTtib29sZWFuPGJyPivCoCA6dmVyc2lvbiAm cXVvdDsyNC41JnF1b3Q7KTxicj4rPGJyPisoZGVmY3VzdG9tIGhpZGUtaWZkZWYtaGVhZGVyLXJl Z2V4cDxicj4rwqAgJnF1b3Q7XFwuaFxcKGhcXHx4eFxcfHBwXFwpP1xcJiMzOTsmcXVvdDs8YnI+ K8KgICZxdW90O0MvQysrIGhlYWRlciBmaWxlIG5hbWUgcGF0dGVybnMgdG8gZGV0ZXJtaW5lIGlm IGN1cnJlbnQgYnVmZmVyIGlzIGEgaGVhZGVyLjxicj4NCg0KK0VmZmVjdGl2ZSBvbmx5IGlmIGBo aWRlLWlmZGVmLWV4cGFuZC1yZWluY2x1c2lvbi1wcm90ZWN0aW9uJiMzOTsgaXMgdC4mcXVvdDs8 YnI+K8KgIDp0eXBlICYjMzk7c3RyaW5nPGJyPivCoCA6Z3JvdXAgJiMzOTtoaWRlLWlmZGVmPGJy PivCoCA6dmVyc2lvbiAmcXVvdDsyNC41JnF1b3Q7KTxicj4rPGJyPsKgKGRlZnZhciBoaWRlLWlm ZGVmLW1vZGUtc3VibWFwPGJyPsKgwqAgOzsgU2V0IHVwIHRoZSBzdWJtYXAgdGhhdCBnb2VzIGFm dGVyIHRoZSBwcmVmaXgga2V5Ljxicj4NCg0KwqDCoCAobGV0ICgobWFwIChtYWtlLXNwYXJzZS1r ZXltYXApKSk8YnI+QEAgLTE1Myw2ICsxODMsOCBAQDxicj7CoMKgwqDCoCAoZGVmaW5lLWtleSBt YXAgJnF1b3Q7cyZxdW90OyAmIzM5O3Nob3ctaWZkZWZzKTxicj7CoMKgwqDCoCAoZGVmaW5lLWtl eSBtYXAgJnF1b3Q7XEMtZCZxdW90OyAmIzM5O2hpZGUtaWZkZWYtYmxvY2spPGJyPsKgwqDCoMKg IChkZWZpbmUta2V5IG1hcCAmcXVvdDtcQy1zJnF1b3Q7ICYjMzk7c2hvdy1pZmRlZi1ibG9jayk8 YnI+DQoNCivCoMKgwqAgKGRlZmluZS1rZXkgbWFwICZxdW90O2UmcXVvdDsgJiMzOTtoaWYtZXZh bHVhdGUtbWFjcm8pPGJyPivCoMKgwqAgKGRlZmluZS1rZXkgbWFwICZxdW90O0MmcXVvdDsgJiMz OTtoaWYtY2xlYXItYWxsLWlmZGVmLWRlZmluZWQpPGJyPsKgPGJyPsKgwqDCoMKgIChkZWZpbmUt a2V5IG1hcCAmcXVvdDtcQy1xJnF1b3Q7ICYjMzk7aGlkZS1pZmRlZi10b2dnbGUtcmVhZC1vbmx5 KTxicj7CoMKgwqDCoCAoZGVmaW5lLWtleSBtYXAgJnF1b3Q7XEMtdyZxdW90OyAmIzM5O2hpZGUt aWZkZWYtdG9nZ2xlLXNoYWRvd2luZyk8YnI+DQoNCkBAIC0yMTcsNiArMjQ5LDExIEBAPGJyPsKg KGRlZnZhciBoaWRlLWlmZGVmLWVudiBuaWw8YnI+wqDCoCAmcXVvdDtBbiBhbGlzdCBvZiBkZWZp bmVkIHN5bWJvbHMgYW5kIHRoZWlyIHZhbHVlcy4mcXVvdDspPGJyPsKgPGJyPisoZGVmdmFyIGhp ZGUtaWZkZWYtZW52LWJhY2t1cCBuaWw8YnI+K8KgICZxdW90O1RoaXMgdmFyaWFibGUgaXMgYSBi YWNrdXAgb2YgdGhlIHByZXZpb3VzbHkgY2xlYXJlZCBgaGlkZS1pZmRlZi1lbnYmIzM5Oy48YnI+ DQoNCitUaGlzIGJhY2t1cCBwcmV2ZW50cyBhbnkgYWNjaWRlbnRhbCBjbGVhcmFuY2Ugb2YgYGhp ZGUtZmlkZWYtZW52JiMzOTsgYnk8YnI+K2BoaWYtY2xlYXItYWxsLWlmZGVmLWRlZmluZWQmIzM5 Oy4mcXVvdDspPGJyPis8YnI+wqAoZGVmdmFyIGhpZi1vdXRzaWRlLXJlYWQtb25seSBuaWw8YnI+ wqDCoCAmcXVvdDtJbnRlcm5hbCB2YXJpYWJsZS7CoCBTYXZlcyB0aGUgdmFsdWUgb2YgYGJ1ZmZl ci1yZWFkLW9ubHkmIzM5OyB3aGlsZSBoaWRpbmcuJnF1b3Q7KTxicj4NCg0KwqA8YnI+QEAgLTIz NCw4ICsyNzEsMTIgQEAgU2V2ZXJhbCB2YXJpYWJsZXMgYWZmZWN0IGhvdyB0aGUgaGlkaW5nIGlz IGRvbmU6PGJyPsKgPGJyPsKgYGhpZGUtaWZkZWYtZW52JiMzOTs8YnI+wqDCoMKgwqDCoMKgwqDC oCBBbiBhc3NvY2lhdGlvbiBsaXN0IG9mIGRlZmluZWQgYW5kIHVuZGVmaW5lZCBzeW1ib2xzIGZv ciB0aGU8YnI+LcKgwqDCoCBjdXJyZW50IGJ1ZmZlci7CoCBJbml0aWFsbHksIHRoZSBnbG9iYWwg dmFsdWUgb2YgYGhpZGUtaWZkZWYtZW52JiMzOTs8YnI+DQoNCi3CoMKgwqAgaXMgdXNlZC48YnI+ K8KgwqDCoMKgwqDCoMKgIGN1cnJlbnQgcHJvamVjdC7CoCBJbml0aWFsbHksIHRoZSBnbG9iYWwg dmFsdWUgb2YgYGhpZGUtaWZkZWYtZW52JiMzOTs8YnI+K8KgwqDCoMKgwqDCoMKgIGlzIHVzZWQu wqAgVGhpcyB2YXJpYWJsZSB3YXMgYSBidWZmZXItbG9jYWwgdmFyaWFibGUsIHdoaWNoIGxpbWl0 czxicj4rwqDCoMKgwqDCoMKgwqAgaGlkZWlmIHRvIHBhcnNlIG9ubHkgb25lIEMvQysrIGZpbGUg YXQgYSB0aW1lLsKgIFdlJiMzOTt2ZSBleHRlbmRlZDxicj4NCg0KK8KgwqDCoMKgwqDCoMKgIGhp ZGVpZiB0byBzdXBwb3J0IHBhcnNpbmcgYSBDL0MrKyBwcm9qZWN0IGNvbnRhaW5pbmcgbXVsdGlw bGUgQy9DKys8YnI+K8KgwqDCoMKgwqDCoMKgIHNvdXJjZSBmaWxlcyBvcGVuZWQgc2ltdWx0YW5l b3VzbHkgaW4gZGlmZmVyZW50IGJ1ZmZlcnMuwqAgVGhlcmVmb3JlPGJyPivCoMKgwqDCoMKgwqDC oCBgaGlkZS1pZmRlZi1lbnYmIzM5OyBjYW4gbm8gbG9uZ2VyIGJlIGJ1ZmZlciBsb2NhbCBidXQg bXVzdCBiZSBnbG9iYWwuPGJyPg0KDQrCoDxicj7CoGBoaWRlLWlmZGVmLWRlZmluZS1hbGlzdCYj Mzk7PGJyPsKgwqDCoMKgwqDCoMKgwqAgQW4gYXNzb2NpYXRpb24gbGlzdCBvZiBkZWZpbmVkIHN5 bWJvbCBsaXN0cy48YnI+QEAgLTI2MCw4ICszMDEsMTggQEAgU2V2ZXJhbCB2YXJpYWJsZXMgYWZm ZWN0IGhvdyB0aGUgaGlkaW5nIGlzIGRvbmU6PGJyPsKgwqAgKGlmIGhpZGUtaWZkZWYtbW9kZTxi cj7CoMKgwqDCoMKgwqAgKHByb2duPGJyPsKgwqDCoMKgwqDCoMKgwqAgOzsgaW5oZXJpdCBnbG9i YWwgdmFsdWVzPGJyPg0KDQotwqDCoMKgIChzZXQgKG1ha2UtbG9jYWwtdmFyaWFibGUgJiMzOTto aWRlLWlmZGVmLWVudik8YnI+LcKgwqDCoCDCoMKgwqDCoCAoZGVmYXVsdC12YWx1ZSAmIzM5O2hp ZGUtaWZkZWYtZW52KSk8YnI+Kzxicj4rwqDCoMKgwqDCoMKgwqAgOzsgYGhpZGUtaWZkZWYtZW52 JiMzOTsgaXMgbm93IGEgZ2xvYmFsIHZhcmlhYmxlLjxicj4rwqDCoMKgwqDCoMKgwqAgOzsgV2Ug Y2FuIHN0aWxsIHNpbXVsYXRlIHRoZSBiZWhhdmlvciBvZiBvbGRlciBoaWRlaWYgdmVyc2lvbnMg KGkuZS48YnI+DQoNCivCoMKgwqDCoMKgwqDCoCA7OyBgaGlkZS1pZmRlZi1lbnYmIzM5OyBiZWlu ZyBidWZmZXIgbG9jYWwpIGJ5IGNsZWFyaW5nIHRoaXMgdmFyaWFibGU8YnI+K8KgwqDCoMKgwqDC oMKgIDs7IChDLWMgQCBDKSBldmVyeXRpbWUgYmVmb3JlIGhpZGluZyBjdXJyZW50IGJ1ZmZlci48 YnI+Kzs7wqDCoMKgwqDCoCAoc2V0IChtYWtlLWxvY2FsLXZhcmlhYmxlICYjMzk7aGlkZS1pZmRl Zi1lbnYpPGJyPis7O8KgwqDCoMKgwqDCoMKgwqDCoMKgIChkZWZhdWx0LXZhbHVlICYjMzk7aGlk ZS1pZmRlZi1lbnYpKTxicj4NCg0KK8KgwqDCoMKgwqDCoMKgIChzZXQgJiMzOTtoaWRlLWlmZGVm LWVudiAoZGVmYXVsdC12YWx1ZSAmIzM5O2hpZGUtaWZkZWYtZW52KSk8YnI+K8KgwqDCoMKgwqDC oMKgIDs7IFNvbWUgQy9DKysgaGVhZGVycyBtaWdodCBoYXZlIG90aGVyIHdheXMgdG8gcHJldmVu dCByZWluY2x1c2lvbiBhbmQ8YnI+K8KgwqDCoMKgwqDCoMKgIDs7IHRodXMgd291bGQgbGlrZSBg aGlkZS1pZmRlZi1leHBhbmQtcmVpbmNsdXNpb24tcHJvdGVjdGlvbiYjMzk7IHRvIGJlIG5pbC48 YnI+DQoNCivCoMKgwqDCoMKgwqDCoCAoc2V0IChtYWtlLWxvY2FsLXZhcmlhYmxlICYjMzk7aGlk ZS1pZmRlZi1leHBhbmQtcmVpbmNsdXNpb24tcHJvdGVjdGlvbik8YnI+K8KgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCAoZGVmYXVsdC12YWx1ZSAmIzM5O2hpZGUtaWZkZWYtZXhwYW5kLXJlaW5jbHVz aW9uLXByb3RlY3Rpb24pKTxicj7CoMKgwqDCoMKgwqDCoMKgIChzZXQgKG1ha2UtbG9jYWwtdmFy aWFibGUgJiMzOTtoaWRlLWlmZGVmLWhpZGluZyk8YnI+DQoNCsKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIChkZWZhdWx0LXZhbHVlICYjMzk7aGlkZS1pZmRlZi1oaWRpbmcpKTxicj7CoMKgwqDC oMKgwqDCoMKgIChzZXQgKG1ha2UtbG9jYWwtdmFyaWFibGUgJiMzOTtoaWYtb3V0c2lkZS1yZWFk LW9ubHkpIGJ1ZmZlci1yZWFkLW9ubHkpPGJyPkBAIC0yODAsNiArMzMxLDE0IEBAIFNldmVyYWwg dmFyaWFibGVzIGFmZmVjdCBob3cgdGhlIGhpZGluZyBpcyBkb25lOjxicj7CoMKgwqDCoCAod2hl biBoaWRlLWlmZGVmLWhpZGluZzxicj4NCg0KwqDCoMKgwqDCoMKgIChzaG93LWlmZGVmcykpKSk8 YnI+wqA8YnI+KyhkZWZ1biBoaWYtY2xlYXItYWxsLWlmZGVmLWRlZmluZWQgKCk8YnI+K8KgICZx dW90O0NsZWFycyBhbGwgc3ltYm9scyBkZWZpbmVkIGluIGBoaWRlLWlmZGVmLWVudiYjMzk7Ljxi cj4rSXQgd2lsbCBiYWNrdXAgdGhpcyB2YXJpYWJsZSB0byBgaGlkZS1pZmRlZi1lbnYtYmFja3Vw JiMzOTsgYmVmb3JlIGNsZWFyaW5nIHRvPGJyPg0KDQorcHJldmVudCBhY2NpZGVudGFsIGNsZWFy YW5jZS4mcXVvdDs8YnI+K8KgIChpbnRlcmFjdGl2ZSk8YnI+K8KgICh3aGVuICh5LW9yLW4tcCAm cXVvdDtDbGVhciBhbGwgI2RlZmluZWQgc3ltYm9scz8gJnF1b3Q7KTxicj4rwqDCoMKgIChzZXRx IGhpZGUtaWZkZWYtZW52LWJhY2t1cCBoaWRlLWlmZGVmLWVudik8YnI+K8KgwqDCoCAoc2V0cSBo aWRlLWlmZGVmLWVudiBuaWwpKSk8YnI+wqA8YnI+wqAoZGVmdW4gaGlmLXNob3ctYWxsICgpPGJy Pg0KDQrCoMKgICZxdW90O1Nob3cgYWxsIG9mIHRoZSB0ZXh0IGluIHRoZSBjdXJyZW50IGJ1ZmZl ci4mcXVvdDs8YnI+QEAgLTI5OSwxNiArMzU4LDY0IEBAIFNldmVyYWwgdmFyaWFibGVzIGFmZmVj dCBob3cgdGhlIGhpZGluZyBpcyBkb25lOjxicj7CoMKgICh3aGlsZSAoPSAobG9nYW5kIDEgKHNr aXAtY2hhcnMtYmFja3dhcmQgJnF1b3Q7XFxcXCZxdW90OykpIDEpPGJyPsKgwqDCoMKgIChlbmQt b2YtbGluZSAyKSkpPGJyPg0KDQrCoDxicj4rKGRlZnVuIGhpZi1tZXJnZS1pZmRlZi1yZWdpb24g KHN0YXJ0IGVuZCk8YnI+K8KgICZxdW90O1RoaXMgZnVuY3Rpb24gbWVyZ2VzIG5lYXJieSBpZmRl ZiByZWdpb25zIHRvIGZvcm0gYSBiaWdnZXIgb3ZlcmxheS48YnI+K1RoZSByZWdpb24gaXMgZGVm aW5lZCBieSBTVEFSVCBhbmQgRU5ELsKgIFRoaXMgd2lsbCBkZWNyZWFzZSB0aGUgbnVtYmVyIG9m PGJyPitvdmVybGF5cyBjcmVhdGVkLiZxdW90Ozxicj4NCg0KK8KgIDs7IEdlbmVyYWxseSB0aGVy ZSBpcyBubyBuZWVkIHRvIGNhbGwgaXRzZWxmIHJlY3Vyc2l2ZWx5IHNpbmNlIHRoZXJlIHNob3Vs ZDxicj4rwqAgOzsgb3JpZ2luYWxseSBleGlzdHMgbm8gdW4tbWVyZ2VkIHJlZ2lvbnM7IGhvd2V2 ZXIsIGlmIGEgcGFydCBvZiB0aGUgZmlsZSBpczxicj4rwqAgOzsgaGlkZGVuIHdpdGggYGhpZGUt aWZkZWYtbGluZXMmIzM5OyBlcXVhbHMgdG8gbmlsIHdoaWxlIGFub3RoZXIgcGFydCB3aXRoICYj Mzk7dCw8YnI+DQoNCivCoCA7OyB0aGlzIGNhc2UgaGFwcGVucy48YnI+K8KgIDs7IFRPRE86IFNo b3VsZCB3ZSBtZXJnZT8gb3IganVzdCBjcmVhdGUgYSBjb250YWluZXIgb3ZlcmxheT8gLS0gdGhp cyBjYW48YnI+K8KgIDs7IHByZXZlbnQgYGhpZGVpZi1zaG93LWlmZGVmJiMzOTsgZXhwYW5kaW5n IHRvbyBtYW55IGhpZGRlbiBjb250ZW50cyBzaW5jZSB0aGVyZTxicj4rwqAgOzsgaXMgb25seSBh IGJpZyBvdmVybGF5IGV4aXN0cyB0aGVyZSB3aXRob3V0IGFueSBzbWFsbGVyIG92ZXJsYXlzLjxi cj4NCg0KK8KgIChzYXZlLXJlc3RyaWN0aW9uPGJyPivCoMKgwqAgKHdpZGVuKSA7IE90aGVyd2lz ZSBgcG9pbnQtbWluJiMzOTsgYW5kIGBwb2ludC1tYXgmIzM5OyB3aWxsIGJlIHJlc3RyaWN0ZWQg YW5kIHRodXM8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCA7IGZhaWwgdG8gZmluZCBuZWlnaGJv ciBvdmVybGF5czxicj4rwqDCoMKgIChsZXQgKChiZWdvdnJzIChvdmVybGF5cy1pbjxicj4NCg0K K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChtYXggKC0gc3RhcnQgMikg KHBvaW50LW1pbikpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAo bWF4ICgtIHN0YXJ0IDEpIChwb2ludC1taW4pKSkpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqAgKGVu ZG92cnMgKG92ZXJsYXlzLWluPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoCAobWluICgrIGVuZCAxKSAocG9pbnQtbWF4KSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIChtaW4gKCsgZW5kIDIpIChwb2ludC1tYXgpKSkpPGJyPg0KDQor wqDCoMKgwqDCoMKgwqDCoMKgIChvYiBuaWwpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqAgKG9lIG5p bCk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoCBiIGUpPGJyPivCoMKgwqDCoMKgIDs7IE1lcmdlIG92 ZXJsYXlzIGJlZm9yZSBTVEFSVDxicj4rwqDCoMKgwqDCoCAoZG9saXN0IChvIGJlZ292cnMpPGJy PivCoMKgwqDCoMKgwqDCoCAod2hlbiAob3ZlcmxheS1nZXQgbyAmIzM5O2hpZGUtaWZkZWYpPGJy PivCoMKgwqDCoMKgwqDCoMKgwqAgKHNldHEgYiAobWluIHN0YXJ0IChvdmVybGF5LXN0YXJ0IG8p KTxicj4NCg0KK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBlIChtYXggZW5kIChvdmVy bGF5LWVuZCBvKSkpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqAgKG1vdmUtb3ZlcmxheSBvIGIgZSk8 YnI+K8KgwqDCoMKgwqDCoMKgwqDCoCAoaGlmLW1lcmdlLWlmZGVmLXJlZ2lvbiBiIGUpPGJyPivC oMKgwqDCoMKgwqDCoMKgwqAgKHNldHEgb2IgbykpKTxicj4rwqDCoMKgwqDCoCA7OyBNZXJnZSBv dmVybGF5cyBhZnRlciBFTkQ8YnI+K8KgwqDCoMKgwqAgKGRvbGlzdCAobyBlbmRvdnJzKTxicj4N Cg0KK8KgwqDCoMKgwqDCoMKgICh3aGVuIChvdmVybGF5LWdldCBvICYjMzk7aGlkZS1pZmRlZik8 YnI+K8KgwqDCoMKgwqDCoMKgwqDCoCAoc2V0cSBiIChtaW4gc3RhcnQgKG92ZXJsYXktc3RhcnQg bykpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgZSAobWF4IGVuZCAob3Zlcmxh eS1lbmQgbykpKTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgIChtb3ZlLW92ZXJsYXkgbyBiIGUpPGJy PivCoMKgwqDCoMKgwqDCoMKgwqAgKGhpZi1tZXJnZS1pZmRlZi1yZWdpb24gYiBlKTxicj4NCg0K K8KgwqDCoMKgwqDCoMKgwqDCoCAoc2V0ZiBvZSBvKSkpPGJyPivCoMKgwqDCoMKgIDs7IElmIGJv dGggU1RBUlQgYW5kIEVORCBtZXJnaW5nIGhhcHBlbnMsIG1lcmdlIGludG8gYmlnZ2VyIG9uZTxi cj4rwqDCoMKgwqDCoCAod2hlbiAoYW5kIG9iIG9lKTxicj4rwqDCoMKgwqDCoMKgwqAgKGxldCAo KGIgKG1pbiAob3ZlcmxheS1zdGFydCBvYikgKG92ZXJsYXktc3RhcnQgb2UpKSk8YnI+K8KgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIChlIChtYXggKG92ZXJsYXktZW5kIG9iKSAob3ZlcmxheS1l bmQgb2UpKSkpPGJyPg0KDQorwqDCoMKgwqDCoMKgwqDCoMKgIChkZWxldGUtb3ZlcmxheSBvZSk8 YnI+K8KgwqDCoMKgwqDCoMKgwqDCoCAobW92ZS1vdmVybGF5IG9iIGIgZSk8YnI+K8KgwqDCoMKg wqDCoMKgwqDCoCAoaGlmLW1lcmdlLWlmZGVmLXJlZ2lvbiBiIGUpKSk8YnI+K8KgwqDCoMKgwqAg KG9yIG9iIG9lKSkpKTxicj4rPGJyPsKgKGRlZnVuIGhpZGUtaWZkZWYtcmVnaW9uLWludGVybmFs IChzdGFydCBlbmQpPGJyPi3CoCAocmVtb3ZlLW92ZXJsYXlzIHN0YXJ0IGVuZCAmIzM5O2hpZGUt aWZkZWYgdCk8YnI+DQoNCivCoCAodW5sZXNzIChoaWYtbWVyZ2UtaWZkZWYtcmVnaW9uIHN0YXJ0 IGVuZCk8YnI+wqDCoCAobGV0ICgobyAobWFrZS1vdmVybGF5IHN0YXJ0IGVuZCkpKTxicj7CoMKg wqDCoCAob3ZlcmxheS1wdXQgbyAmIzM5O2hpZGUtaWZkZWYgdCk8YnI+wqDCoMKgwqAgKGlmIGhp ZGUtaWZkZWYtc2hhZG93PGJyPsKgwqDCoMKgwqDCoMKgwqAgKG92ZXJsYXktcHV0IG8gJiMzOTtm YWNlICYjMzk7aGlkZS1pZmRlZi1zaGFkb3cpPGJyPg0KDQotwqDCoMKgwqDCoCAob3ZlcmxheS1w dXQgbyAmIzM5O2ludmlzaWJsZSAmIzM5O2hpZGUtaWZkZWYpKSkpPGJyPivCoMKgwqDCoMKgwqDC oCAob3ZlcmxheS1wdXQgbyAmIzM5O2ludmlzaWJsZSAmIzM5O2hpZGUtaWZkZWYpKSkpKTxicj7C oDxicj7CoChkZWZ1biBoaWRlLWlmZGVmLXJlZ2lvbiAoc3RhcnQgZW5kKTxicj4twqAgJnF1b3Q7 U1RBUlQgaXMgdGhlIHN0YXJ0IG9mIGEgI2lmIG9yICNlbHNlIGZvcm0uwqAgRU5EIGlzIHRoZSBl bmRpbmcgcGFydC48YnI+DQoNCivCoCAmcXVvdDtTVEFSVCBpcyB0aGUgc3RhcnQgb2YgYSAjaWYs ICNlbGlmLCBvciAjZWxzZSBmb3JtLsKgIEVORCBpcyB0aGUgZW5kaW5nIHBhcnQuPGJyPsKgRXZl cnl0aGluZyBpbmNsdWRpbmcgdGhlc2UgbGluZXMgaXMgbWFkZSBpbnZpc2libGUuJnF1b3Q7PGJy PsKgwqAgKHNhdmUtZXhjdXJzaW9uPGJyPsKgwqDCoMKgIChnb3RvLWNoYXIgc3RhcnQpIChoaWYt ZW5kLW9mLWxpbmUpIChzZXRxIHN0YXJ0IChwb2ludCkpPGJyPg0KDQpAQCAtMzE3LDcgKzQyNCw5 IEBAIEV2ZXJ5dGhpbmcgaW5jbHVkaW5nIHRoZXNlIGxpbmVzIGlzIG1hZGUgaW52aXNpYmxlLiZx dW90Ozxicj7CoDxicj7CoChkZWZ1biBoaWYtc2hvdy1pZmRlZi1yZWdpb24gKHN0YXJ0IGVuZCk8 YnI+wqDCoCAmcXVvdDtFdmVyeXRoaW5nIGJldHdlZW4gU1RBUlQgYW5kIEVORCBpcyBtYWRlIHZp c2libGUuJnF1b3Q7PGJyPi3CoCAocmVtb3ZlLW92ZXJsYXlzIHN0YXJ0IGVuZCAmIzM5O2hpZGUt aWZkZWYgdCkpPGJyPg0KDQorwqAgKGxldCAoKG9udW0gKGxlbmd0aCAob3ZlcmxheXMtaW4gc3Rh cnQgZW5kKSkpKTxicj4rwqDCoMKgIChyZW1vdmUtb3ZlcmxheXMgc3RhcnQgZW5kICYjMzk7aGlk ZS1pZmRlZiB0KTxicj4rwqDCoMKgICgvPSBvbnVtIChsZW5ndGggKG92ZXJsYXlzLWluIHN0YXJ0 IGVuZCkpKSkpPGJyPsKgPGJyPsKgPGJyPsKgOzs9PT0lJVNGJSUgZXZhbHVhdGlvbiAoU3RhcnQp wqAgPT09PGJyPkBAIC0zNzYsMTAgKzQ4NSw4IEBAIHRoYXQgZm9ybSBzaG91bGQgYmUgZGlzcGxh eWVkLiZxdW90Oyk8YnI+DQoNCsKgwqAgKGNvbmNhdCBoaWYtY3BwLXByZWZpeCAmcXVvdDtcXChp ZlxcKG4/ZGVmXFwpP1xcfGVsaWZcXHxkZWZpbmVcXClbIFx0XSsmcXVvdDspKTxicj7CoDxicj7C oChkZWZjb25zdCBoaWYtd2hpdGUtcmVnZXhwwqDCoMKgICZxdW90O1sgXHRdKiZxdW90Oyk8YnI+ LShkZWZjb25zdCBoaWYtZGVmaW5lLXJlZ2V4cDxicj4twqAgKGNvbmNhdCBoaWYtY3BwLXByZWZp eCAmcXVvdDtcXChkZWZpbmVcXHx1bmRlZlxcKSZxdW90OykpPGJyPg0KDQotKGRlZmNvbnN0IGhp Zi1pZC1yZWdleHA8YnI+LcKgIChjb25jYXQgJnF1b3Q7W1s6YWxwaGE6XV9dW1s6YWxudW06XV9d KiZxdW90OykpPGJyPisoZGVmY29uc3QgaGlmLWRlZmluZS1yZWdleHDCoMKgIChjb25jYXQgaGlm LWNwcC1wcmVmaXggJnF1b3Q7XFwoZGVmaW5lXFx8dW5kZWZcXCkmcXVvdDspKTxicj4rKGRlZmNv bnN0IGhpZi1pZC1yZWdleHDCoMKgwqDCoMKgwqAgKGNvbmNhdCAmcXVvdDtbWzphbHBoYTpdX11b WzphbG51bTpdX10qJnF1b3Q7KSk8YnI+DQoNCsKgKGRlZmNvbnN0IGhpZi1tYWNyb3JlZi1yZWdl eHA8YnI+wqDCoCAoY29uY2F0IGhpZi13aGl0ZS1yZWdleHAgJnF1b3Q7XFwoJnF1b3Q7IGhpZi1p ZC1yZWdleHAgJnF1b3Q7XFwpJnF1b3Q7IGhpZi13aGl0ZS1yZWdleHA8YnI+wqDCoMKgwqDCoMKg wqDCoMKgwqAgJnF1b3Q7XFwoJnF1b3Q7PGJyPkBAIC01MDAsNiArNjA3LDggQEAgdGhhdCBmb3Jt IHNob3VsZCBiZSBkaXNwbGF5ZWQuJnF1b3Q7KTxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgKHNldHEgaGlmLXNpbXBsZS10b2tlbi1vbmx5IG5pbCkpKTxicj4N Cg0KwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHRva2VuLWxpc3QpKSk8YnI+wqA8YnI+ K8KgwqDCoMKgwqDCoMKgwqDCoMKgICgobG9va2luZy1hdCAmcXVvdDtcciZxdW90OykgOyBTb21l dGltZXMgTVMtV2luZG93cyB1c2VyIHdpbGwgbGVhdmUgQ1IgaW48YnI+K8KgwqDCoMKgwqDCoMKg wqDCoMKgwqAgKGZvcndhcmQtY2hhciAxKSkgO8KgIHRoZSBzb3VyY2UgY29kZS4gTGV0JiMzOTtz IG5vdCBnZXQgc3R1Y2sgaGVyZS48YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAodCAoZXJyb3Ig JnF1b3Q7QmFkICNpZiBleHByZXNzaW9uOiAlcyZxdW90OyAoYnVmZmVyLXN0cmluZykpKSkpKSk8 YnI+DQoNCsKgPGJyPsKgwqDCoMKgIChucmV2ZXJzZSB0b2tlbi1saXN0KSkpPGJyPkBAIC01NzMs NyArNjgyLDcgQEAgdGhhdCBmb3JtIHNob3VsZCBiZSBkaXNwbGF5ZWQuJnF1b3Q7KTxicj7CoChk ZWZ1biBoaWYtZXhwYW5kLXRva2VuLWxpc3QgKHRva2VucyAmYW1wO29wdGlvbmFsIG1hY3JvbmFt ZSBleHBhbmRfbGlzdCk8YnI+wqDCoCAmcXVvdDtQZXJmb3JtIGV4cGFuc2lvbiBvbiBUT0tFTlMg dGlsbCBldmVyeXRoaW5nIGV4cGFuZGVkLjxicj4NCg0KwqBTZWxmLXJlZmVyZW5jZSAoZGlyZWN0 bHkgb3IgaW5kaXJlY3RseSkgdG9rZW5zIGFyZSBub3QgZXhwYW5kZWQuPGJyPi1FWFBBTkRfTElT VCBpcyB0aGUgbGlzdCBvZiBtYWNybyBuYW1lcyBjdXJyZW50bHkgYmVpbmcgZXhwYW5kZWQsIHVz ZSBmb3I8YnI+K0VYUEFORF9MSVNUIGlzIHRoZSBsaXN0IG9mIG1hY3JvIG5hbWVzIGN1cnJlbnRs eSBiZWluZyBleHBhbmRlZCwgdXNlZCBmb3I8YnI+DQoNCsKgZGV0ZWN0aW5nIHNlbGYtcmVmZXJl bmNlLiZxdW90Ozxicj7CoMKgIChjYXRjaCAmIzM5O3NlbGYtcmVmZXJlbmNpbmc8YnI+wqDCoMKg wqAgKGxldCAoKGV4cGFuZGVkIG5pbCk8YnI+QEAgLTExNzQsMTMgKzEyODMsMTYgQEAgRG8gdGhp cyB3aGVuIGN1cnNvciBpcyBhdCB0aGUgYmVnaW5uaW5nIG9mIGByZWdleHAmIzM5OyAoaS5lLiAj aWZYKS4mcXVvdDs8YnI+wqDCoMKgwqAgKGlmICg9IHN0YXJ0IChwb2ludCkpPGJyPg0KDQrCoMKg wqDCoMKgwqDCoMKgIChlcnJvciAmcXVvdDtNaXNtYXRjaGVkICNpZmRlZiAjZW5kaWYgcGFpciZx dW90OykpKTxicj7CoMKgIChjb25kICgoaGlmLWxvb2tpbmctYXQtZW5kaWYpPGJyPi3CoMKgwqAg wqAoaGlmLWVuZGlmLXRvLWlmZGVmKSA7IGZpbmQgYmVnaW5uaW5nIG9mIG5lc3RlZCBpZjxicj4t wqDCoMKgIMKgKGhpZi1lbmRpZi10by1pZmRlZikpIDsgZmluZCBiZWdpbm5pbmcgb2Ygb3V0ZXIg aWYgb3IgZWxzZTxicj4NCg0KK8KgwqDCoMKgwqDCoMKgwqAgKGhpZi1lbmRpZi10by1pZmRlZikg OyBGaW5kIGJlZ2lubmluZyBvZiBuZXN0ZWQgaWY8YnI+K8KgwqDCoMKgwqDCoMKgwqAgKGhpZi1l bmRpZi10by1pZmRlZikpIDsgRmluZCBiZWdpbm5pbmcgb2Ygb3V0ZXIgaWYgb3IgZWxzZTxicj4r wqDCoMKgwqDCoMKgwqAgKChoaWYtbG9va2luZy1hdC1lbGlmKTxicj4rwqDCoMKgwqDCoMKgwqDC oCAoaGlmLWVuZGlmLXRvLWlmZGVmKSk8YnI+wqDCoMKgwqDCoMKgwqDCoCAoKGhpZi1sb29raW5n LWF0LWVsc2UpPGJyPg0KDQrCoMKgwqDCoMKgwqDCoMKgwqAgKGhpZi1lbmRpZi10by1pZmRlZikp PGJyPsKgwqDCoMKgwqDCoMKgwqAgKChoaWYtbG9va2luZy1hdC1pZlgpPGJyPsKgwqDCoMKgwqDC oMKgwqDCoCAmIzM5O2RvbmUpPGJyPi3CoMKgwqAgKHQpKSnCoMKgwqAgwqDCoMKgIMKgwqDCoCA7 IG5ldmVyIGdldHMgaGVyZTxicj4rwqDCoMKgwqDCoMKgwqAgKHQ8YnI+K8KgwqDCoMKgwqDCoMKg wqAgKGVycm9yICZxdW90O01pc21hdGNoZWQgI2VuZGlmJnF1b3Q7KSkpKcKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIDsgbmV2ZXIgZ2V0cyBoZXJlPGJyPg0KDQrCoDxicj7CoDxicj7C oChkZWZ1biBmb3J3YXJkLWlmZGVmICgmYW1wO29wdGlvbmFsIGFyZyk8YnI+QEAgLTEyNzQsMjYg KzEzODYsMjUgQEAgV2l0aCBhcmd1bWVudCwgZG8gdGhpcyB0aGF0IG1hbnkgdGltZXMuJnF1b3Q7 PGJyPsKgOzs9PT0lJVNGJSUgaGlkZS1pZmRlZi1oaWRpbmcgKFN0YXJ0KcKgID09PTxicj7CoDxi cj7CoDxicj4tOzs7IEEgcmFuZ2UgaXMgYSBzdHJ1Y3R1cmUgd2l0aCBmb3VyIGNvbXBvbmVudHM6 PGJyPg0KDQotOzs7IEVMU0UtUMKgwqDCoCBUcnVlIGlmIHRoZXJlIHdhcyBhbiBlbHNlIGNsYXVz ZSBmb3IgdGhlIGlmZGVmLjxicj4tOzs7IFNUQVJUwqDCoMKgIFRoZSBzdGFydCBvZiB0aGUgcmFu Z2UuIChiZWdpbm5pbmcgb2YgbGluZSk8YnI+LTs7OyBFTFNFwqDCoMKgIFRoZSBlbHNlIG1hcmtl ciAoYmVnaW5uaW5nIG9mIGxpbmUpPGJyPi07OzvCoMKgwqAgwqDCoMKgIMKgwqDCoCBPbmx5IHZh bGlkIGlmIEVMU0UtUCBpcyB0cnVlLjxicj4NCg0KLTs7OyBFTkTCoMKgwqAgwqDCoMKgIFRoZSBl bmQgb2YgdGhlIHJhbmdlLsKgIChiZWdpbm5pbmcgb2YgbGluZSk8YnI+Kzs7IEEgcmFuZ2UgaXMg YSBzdHJ1Y3R1cmUgd2l0aCBmb3VyIGNvbXBvbmVudHM6PGJyPis7OyBTVEFSVMKgwqDCoMKgwqDC oCBUaGUgc3RhcnQgb2YgdGhlIHJhbmdlLiAoYmVnaW5uaW5nIG9mIGxpbmUpPGJyPis7OyBFTFNF wqDCoMKgwqDCoMKgwqAgVGhlIGVsc2UgbWFya2VyIChiZWdpbm5pbmcgb2YgbGluZSk8YnI+DQoN Cis7OyBFTkTCoMKgwqDCoMKgwqDCoMKgIFRoZSBlbmQgb2YgdGhlIHJhbmdlLsKgIChiZWdpbm5p bmcgb2YgbGluZSk8YnI+Kzs7IEVMSUbCoMKgwqDCoMKgwqDCoCBBIHNlcXVlbmNlIG9mICNlbGlm IG1hcmtlcnMgKGJlZ2lubmluZyBvZiBsaW5lKTxicj7CoDxicj4tKGRlZnN1YnN0IGhpZi1tYWtl LXJhbmdlIChzdGFydCBlbmQgJmFtcDtvcHRpb25hbCBlbHNlKTxicj4twqAgKGxpc3Qgc3RhcnQg ZWxzZSBlbmQpKTxicj4NCg0KKyhkZWZzdWJzdCBoaWYtbWFrZS1yYW5nZSAoc3RhcnQgZW5kICZh bXA7b3B0aW9uYWwgZWxzZSBlbGlmKTxicj4rwqAgKGxpc3Qgc3RhcnQgZWxzZSBlbmQgZWxpZikp PGJyPsKgPGJyPsKgKGRlZnN1YnN0IGhpZi1yYW5nZS1zdGFydCAocmFuZ2UpIChlbHQgcmFuZ2Ug MCkpPGJyPsKgKGRlZnN1YnN0IGhpZi1yYW5nZS1lbHNlIChyYW5nZSkgKGVsdCByYW5nZSAxKSk8 YnI+wqAoZGVmc3Vic3QgaGlmLXJhbmdlLWVuZCAocmFuZ2UpIChlbHQgcmFuZ2UgMikpPGJyPg0K DQorKGRlZnN1YnN0IGhpZi1yYW5nZS1lbGlmIChyYW5nZSkgKGVsdCByYW5nZSAzKSk8YnI+wqA8 YnI+wqA8YnI+LTxicj4tOzs7IEZpbmQtUmFuZ2U8YnI+LTs7OyBUaGUgd29ya2hvcnNlLCBpdCBk ZWxpbWl0cyB0aGUgI2lmIHJlZ2lvbi7CoCBSZWFzb25hYmx5IHNpbXBsZTo8YnI+LTs7OyBTa2lw IHVudGlsIGFuICNlbHNlIG9yICNlbmRpZiBpcyBmb3VuZCwgcmVtZW1iZXJpbmcgcG9zaXRpb25z LsKgIElmPGJyPg0KDQotOzs7IGFuICNlbHNlIHdhcyBmb3VuZCwgc2tpcCBzb21lIG1vcmUsIGxv b2tpbmcgZm9yIHRoZSB0cnVlICNlbmRpZi48YnI+Kzs7IEZpbmQtUmFuZ2U8YnI+Kzs7IFRoZSB3 b3JraG9yc2UsIGl0IGRlbGltaXRzIHRoZSAjaWYgcmVnaW9uLsKgIFJlYXNvbmFibHkgc2ltcGxl Ojxicj4rOzsgU2tpcCB1bnRpbCBhbiAjZWxzZSBvciAjZW5kaWYgaXMgZm91bmQsIHJlbWVtYmVy aW5nIHBvc2l0aW9ucy7CoCBJZjxicj4NCg0KKzs7IGFuICNlbHNlIHdhcyBmb3VuZCwgc2tpcCBz b21lIG1vcmUsIGxvb2tpbmcgZm9yIHRoZSB0cnVlICNlbmRpZi48YnI+wqA8YnI+wqAoZGVmdW4g aGlmLWZpbmQtcmFuZ2UgKCk8YnI+wqDCoCAmcXVvdDtSZXR1cm4gYSBSYW5nZSBzdHJ1Y3R1cmUg ZGVzY3JpYmluZyB0aGUgY3VycmVudCAjaWYgcmVnaW9uLjxicj5AQCAtMTMwMiwxOSArMTQxMywy MyBAQCBQb2ludCBpcyBsZWZ0IHVuY2hhbmdlZC4mcXVvdDs8YnI+DQoNCsKgwqAgKHNhdmUtZXhj dXJzaW9uPGJyPsKgwqDCoMKgIChiZWdpbm5pbmctb2YtbGluZSk8YnI+wqDCoMKgwqAgKGxldCAo KHN0YXJ0IChwb2ludCkpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqAgKGVsaWYgbmlsKTxicj7CoMKg wqDCoMKgwqDCoMKgwqDCoCAoZWxzZSBuaWwpPGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgIChlbmQg bmlsKSk8YnI+LcKgwqDCoMKgwqAgOzsgUGFydCBvbmUuwqAgTG9vayBmb3IgZWl0aGVyICNlbmRp ZiBvciAjZWxzZS48YnI+K8KgwqDCoMKgwqAgOzsgUGFydCBvbmUuwqAgTG9vayBmb3IgZWl0aGVy ICNlbGlmLCAjZWxzZSBvciAjZW5kaWYuPGJyPg0KDQrCoMKgwqDCoMKgwqAgOzsgVGhpcyBsb29w LWFuZC1hLWhhbGYgZGVkaWNhdGVkIHRvIEUuIERpamtzdHJhLjxicj4rwqDCoMKgwqDCoCAod2hp bGUgKGFuZCAobm90IGVsc2UpIChub3QgZW5kKSk8YnI+wqDCoMKgwqDCoMKgwqDCoCAod2hpbGUg KHByb2duPGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGhpZi1maW5kLW5l eHQtcmVsZXZhbnQpPGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGhpZi1s b29raW5nLWF0LWlmWCkpwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCA7IFNraXAgbmVzdGVkIGlmZGVm PGJyPg0KDQrCoMKgwqDCoMKgwqDCoMKgwqDCoCAoaGlmLWlmZGVmLXRvLWVuZGlmKSk8YnI+LcKg wqDCoMKgwqAgOzsgRm91bmQgZWl0aGVyIGEgI2Vsc2Ugb3IgYW4gI2VuZGlmLjxicj4twqDCoMKg wqDCoCAoY29uZCAoKGhpZi1sb29raW5nLWF0LWVsc2UpPGJyPivCoMKgwqDCoMKgwqDCoCA7OyBG b3VuZCBlaXRoZXIgYSAjZWxzZSwgI2VsaWYsIG9yIGFuICNlbmRpZi48YnI+K8KgwqDCoMKgwqDC oMKgIChjb25kICgoaGlmLWxvb2tpbmctYXQtZWxpZik8YnI+DQoNCivCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIChzZXRxIGVsaWYgKG5jb25jIGVsaWYgKGxpc3QgKHBvaW50KSkpKSk8YnI+ K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICgoaGlmLWxvb2tpbmctYXQtZWxzZSk8YnI+wqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChzZXRxIGVsc2UgKHBvaW50KSkpPGJyPsKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKHQ8YnI+LcKgwqDCoCDCoMKgwqDCoCAoc2V0cSBlbmQg KHBvaW50KSkpKSA7IChsaW5lLWVuZC1wb3NpdGlvbik8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgKHNldHEgZW5kIChwb2ludCkpKSkpPGJyPg0KDQrCoMKgwqDCoMKgwqAgOzsgSWYg Zm91bmQgI2Vsc2UsIGxvb2sgZm9yICNlbmRpZi48YnI+wqDCoMKgwqDCoMKgICh3aGVuIGVsc2U8 YnI+wqDCoMKgwqDCoMKgwqDCoCAod2hpbGUgKHByb2duPGJyPkBAIC0xMzI0LDcgKzE0MzksNyBA QCBQb2ludCBpcyBsZWZ0IHVuY2hhbmdlZC4mcXVvdDs8YnI+wqDCoMKgwqDCoMKgwqDCoCAoaWYg KGhpZi1sb29raW5nLWF0LWVsc2UpPGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoZXJyb3Ig JnF1b3Q7Rm91bmQgdHdvIGVsc2VzIGluIGEgcm93P8KgIEJyb2tlbiEmcXVvdDspKTxicj4NCg0K wqDCoMKgwqDCoMKgwqDCoCAoc2V0cSBlbmQgKHBvaW50KSkpwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCA7IChsaW5lLWVuZC1wb3NpdGlvbik8YnI+LcKgwqDCoMKgwqAgKGhpZi1tYWtlLXJhbmdlIHN0 YXJ0IGVuZCBlbHNlKSkpKTxicj4rwqDCoMKgwqDCoCAoaGlmLW1ha2UtcmFuZ2Ugc3RhcnQgZW5k IGVsc2UgZWxpZikpKSk8YnI+wqA8YnI+wqA8YnI+wqA7OyBBIGJpdCBzbGlteS48YnI+QEAgLTEz MzksNzAgKzE0NTQsMTgwIEBAIERvZXMgbm90aGluZyBpZiBgaGlkZS1pZmRlZi1saW5lcyYjMzk7 IGlzIG5pbC4mcXVvdDs8YnI+DQoNCsKgwqDCoMKgwqDCoMKgIChsaW5lLWJlZ2lubmluZy1wb3Np dGlvbikgKHByb2duIChoaWYtZW5kLW9mLWxpbmUpIChwb2ludCkpKSkpKTxicj7CoDxicj7CoDxi cj4tOzs7wqAgSGlmLVBvc3NpYmx5LUhpZGU8YnI+LTs7O8KgIFRoZXJlIGFyZSBmb3VyIGNhc2Vz LsKgIFRoZSAjaWZYIGV4cHJlc3Npb24gaXMgJnF1b3Q7dGFrZW4mcXVvdDsgaWYgaXQ8YnI+LTs7 O8KgIHRoZSBoaWRlLWlmZGVmLWV2YWx1YXRvciByZXR1cm5zIFQuwqAgUHJlc3VtYWJseSwgdGhp cyBtZWFucyB0aGUgY29kZTxicj4NCg0KLTs7O8KgIGluc2lkZSB0aGUgI2lmZGVmIHdvdWxkIGJl IGluY2x1ZGVkIHdoZW4gdGhlIHByb2dyYW0gd2FzPGJyPi07OzvCoCBjb21waWxlZC48YnI+LTs7 Ozxicj4tOzs7wqAgQ2FzZSAxOsKgICNpZlggdGFrZW4sIGFuZCB0aGVyZSYjMzk7cyBhbiAjZWxz ZS48YnI+LTs7O8KgwqDCoCBUaGUgI2Vsc2UgcGFydCBtdXN0IGJlIGhpZGRlbi7CoCBUaGUgI2lm ICh0aGVuKSBwYXJ0IG11c3QgYmU8YnI+DQotOzs7wqDCoMKgIHByb2Nlc3NlZCBmb3IgbmVzdGVk ICNpZlgmIzM5O3MuPGJyPg0KLTs7O8KgIENhc2UgMjrCoCAjaWZYIHRha2VuLCBhbmQgdGhlcmUm IzM5O3Mgbm8gI2Vsc2UuPGJyPi07OzvCoMKgwqAgVGhlICNpZiBwYXJ0IG11c3QgYmUgcHJvY2Vz c2VkIGZvciBuZXN0ZWQgI2lmWCYjMzk7cy48YnI+LTs7O8KgIENhc2UgMzrCoCAjaWZYIG5vdCB0 YWtlbiwgYW5kIHRoZXJlJiMzOTtzIGFuICNlbHNlLjxicj4tOzs7wqDCoMKgIFRoZSAjaWYgcGFy dCBtdXN0IGJlIGhpZGRlbi7CoCBUaGUgI2Vsc2UgcGFydCBtdXN0IGJlIHByb2Nlc3NlZDxicj4N Cg0KLTs7O8KgwqDCoCBmb3IgbmVzdGVkICNpZnMuPGJyPi07OzvCoCBDYXNlIDQ6wqAgI2lmWCBu b3QgdGFrZW4sIGFuZCB0aGVyZSYjMzk7cyBubyAjZWxzZS48YnI+LTs7O8KgwqDCoCBUaGUgI2lm WCBwYXJ0IG11c3QgYmUgaGlkZGVuLjxicj4tOzs7PGJyPi07OzvCoCBGdXJ0aGVyIHByb2Nlc3Np bmcgaXMgZG9uZSBieSBuYXJyb3dpbmcgdG8gdGhlIHJlbGV2YW50IHJlZ2lvbjxicj4tOzs7wqAg YW5kIGp1c3QgcmVjdXJzaXZlbHkgY2FsbGluZyBoaWRlLWlmZGVmLWd1dHMuPGJyPg0KDQotOzs7 PGJyPi07OzvCoCBXaGVuIGhpZi1wb3NzaWJseS1oaWRlIHJldHVybnMsIHBvaW50IGlzIGF0IHRo ZSBlbmQgb2YgdGhlPGJyPi07OzvCoCBwb3NzaWJseS1oaWRkZW4gcmFuZ2UuPGJyPi08YnI+LShk ZWZ1biBoaWYtcmVjdXJzZS1vbiAoc3RhcnQgZW5kKTxicj4rOzvCoCBIaWYtUG9zc2libHktSGlk ZTxicj4rOzvCoCBUaGVyZSBhcmUgZm91ciBjYXNlcy7CoCBUaGUgI2lmWCBleHByZXNzaW9uIGlz ICZxdW90O3Rha2VuJnF1b3Q7IGlmIGl0PGJyPg0KDQorOzvCoCB0aGUgaGlkZS1pZmRlZi1ldmFs dWF0b3IgcmV0dXJucyBULsKgIFByZXN1bWFibHksIHRoaXMgbWVhbnMgdGhlIGNvZGU8YnI+Kzs7 wqAgaW5zaWRlIHRoZSAjaWZkZWYgd291bGQgYmUgaW5jbHVkZWQgd2hlbiB0aGUgcHJvZ3JhbSB3 YXM8YnI+Kzs7wqAgY29tcGlsZWQuPGJyPis7Ozxicj4rOzvCoCBDYXNlIDE6wqAgI2lmWCB0YWtl biwgYW5kIHRoZXJlJiMzOTtzIGFuICNlbHNlLjxicj4NCg0KKzs7wqDCoMKgwqAgVGhlICNlbHNl IHBhcnQgbXVzdCBiZSBoaWRkZW4uwqAgVGhlICNpZiAodGhlbikgcGFydCBtdXN0IGJlPGJyPis7 O8KgwqDCoMKgIHByb2Nlc3NlZCBmb3IgbmVzdGVkICNpZlgmIzM5O3MuPGJyPis7O8KgIENhc2Ug MjrCoCAjaWZYIHRha2VuLCBhbmQgdGhlcmUmIzM5O3Mgbm8gI2Vsc2UuPGJyPis7O8KgwqDCoMKg IFRoZSAjaWYgcGFydCBtdXN0IGJlIHByb2Nlc3NlZCBmb3IgbmVzdGVkICNpZlgmIzM5O3MuPGJy Pg0KDQorOzvCoCBDYXNlIDM6wqAgI2lmWCBub3QgdGFrZW4sIGFuZCB0aGVyZSYjMzk7cyBhbiAj ZWxpZjxicj4rOzvCoMKgwqDCoCBUaGUgI2lmIHBhcnQgbXVzdCBiZSBoaWRkZW4sIGFuZCB0aGVu IGV2YWx1YXRlPGJyPis7O8KgwqDCoMKgIHRoZSAjZWxpZiBjb25kaXRpb24gbGlrZSBhIG5ldyAj aWZYLjxicj4rOzvCoCBDYXNlIDQ6wqAgI2lmWCBub3QgdGFrZW4sIGFuZCB0aGVyZSYjMzk7cyBq dXN0IGFuICNlbHNlLjxicj4NCg0KKzs7wqDCoMKgwqAgVGhlICNpZiBwYXJ0IG11c3QgYmUgaGlk ZGVuLsKgIFRoZSAjZWxzZSBwYXJ0IG11c3QgYmUgcHJvY2Vzc2VkPGJyPis7O8KgwqDCoMKgIGZv ciBuZXN0ZWQgI2lmcy48YnI+Kzs7wqAgQ2FzZSA1OsKgICNpZlggbm90IHRha2VuLCBhbmQgdGhl cmUmIzM5O3Mgbm8gI2Vsc2UuPGJyPis7O8KgwqDCoMKgIFRoZSAjaWZYIHBhcnQgbXVzdCBiZSBo aWRkZW4uPGJyPis7Ozxicj4rOzvCoCBGdXJ0aGVyIHByb2Nlc3NpbmcgaXMgZG9uZSBieSBuYXJy b3dpbmcgdG8gdGhlIHJlbGV2YW50IHJlZ2lvbjxicj4NCg0KKzs7wqAgYW5kIGp1c3QgcmVjdXJz aXZlbHkgY2FsbGluZyBoaWRlLWlmZGVmLWd1dHMuPGJyPis7Ozxicj4rOzvCoCBXaGVuIGhpZi1w b3NzaWJseS1oaWRlIHJldHVybnMsIHBvaW50IGlzIGF0IHRoZSBlbmQgb2YgdGhlPGJyPis7O8Kg IHBvc3NpYmx5LWhpZGRlbiByYW5nZS48YnI+Kzxicj4rKGRlZnZhciBoaWYtcmVjdXJzZS1sZXZl bCAwKTxicj4rPGJyPisoZGVmdW4gaGlmLXJlY3Vyc2Utb24gKHN0YXJ0IGVuZCAmYW1wO29wdGlv bmFsIGRvbnQtZ28tZW9sKTxicj4NCg0KwqDCoCAmcXVvdDtDYWxsIGBoaWRlLWlmZGVmLWd1dHMm IzM5OyBhZnRlciBuYXJyb3dpbmcgdG8gZW5kIG9mIFNUQVJUIGxpbmUgYW5kIEVORCBsaW5lLiZx dW90Ozxicj7CoMKgIChzYXZlLWV4Y3Vyc2lvbjxicj7CoMKgwqDCoCAoc2F2ZS1yZXN0cmljdGlv bjxicj7CoMKgwqDCoMKgwqAgKGdvdG8tY2hhciBzdGFydCk8YnI+LcKgwqDCoMKgwqAgKGVuZC1v Zi1saW5lKTxicj4rwqDCoMKgwqDCoCAodW5sZXNzIGRvbnQtZ28tZW9sPGJyPg0KDQorwqDCoMKg wqDCoMKgwqAgKGVuZC1vZi1saW5lKSk8YnI+wqDCoMKgwqDCoMKgIChuYXJyb3ctdG8tcmVnaW9u IChwb2ludCkgZW5kKTxicj4twqDCoMKgwqDCoCAoaGlkZS1pZmRlZi1ndXRzKSkpKTxicj4rwqDC oMKgwqDCoCAobGV0ICgoaGlmLXJlY3Vyc2UtbGV2ZWwgKDErIGhpZi1yZWN1cnNlLWxldmVsKSkp PGJyPivCoMKgwqDCoMKgwqDCoCAoaGlkZS1pZmRlZi1ndXRzKSkpKSk8YnI+wqA8YnI+LShkZWZ1 biBoaWYtcG9zc2libHktaGlkZSAoKTxicj4NCg0KKyhkZWZ1biBoaWYtcG9zc2libHktaGlkZSAo ZXhwYW5kLXJlaW5jbHVzaW9uKTxicj7CoMKgICZxdW90O0NhbGxlZCBhdCAjaWZYIGV4cHJlc3Np b24sIHRoaXMgaGlkZXMgdGhvc2UgcGFydHMgdGhhdCBzaG91bGQgYmUgaGlkZGVuLjxicj4tSXQg dXNlcyB0aGUganVkZ21lbnQgb2YgYGhpZGUtaWZkZWYtZXZhbHVhdG9yJiMzOTsuJnF1b3Q7PGJy PitJdCB1c2VzIHRoZSBqdWRnbWVudCBvZiBgaGlkZS1pZmRlZi1ldmFsdWF0b3ImIzM5Oy7CoCBF WFBBTkQtUkVJTkNMVVNJT04gaXMgYSBmbGFnPGJyPg0KDQoraW5kaWNhdGluZyB0aGF0IHdlIHNo b3VsZCBleHBhbmQgdGhlICNpZmRlZiBldmVuIGlmIGl0IHNob3VsZCBiZSBoaWRkZW4uPGJyPitS ZWZlciB0byBgaGlkZS1pZmRlZi1leHBhbmQtcmVpbmNsdXNpb24tcHJvdGVjdGlvbiYjMzk7IGZv ciBtb3JlIGRldGFpbHMuJnF1b3Q7PGJyPsKgwqAgOzsgKG1lc3NhZ2UgJnF1b3Q7aGlmLXBvc3Np Ymx5LWhpZGUmcXVvdDspIChzaXQtZm9yIDEpPGJyPg0KDQotwqAgKGxldCAoKHRlc3QgKGhpZi1j YW5vbmljYWxpemUgaGlmLWlmeC1yZWdleHApKTxicj4twqDCoMKgIChyYW5nZSAoaGlmLWZpbmQt cmFuZ2UpKSk8YnI+K8KgIChsZXQqICgoY2FzZS1mb2xkLXNlYXJjaCBuaWwpPGJyPivCoMKgwqDC oMKgwqDCoMKgICh0ZXN0IChoaWYtY2Fub25pY2FsaXplIGhpZi1pZngtcmVnZXhwKSk8YnI+K8Kg wqDCoMKgwqDCoMKgwqAgKHJhbmdlIChoaWYtZmluZC1yYW5nZSkpPGJyPivCoMKgwqDCoMKgwqDC oMKgIChlbGlmcyAoaGlmLXJhbmdlLWVsaWYgcmFuZ2UpKTxicj4NCg0KK8KgwqDCoMKgwqDCoMKg wqAgKGlmLXBhcnQgdCkgOyBFdmVyeXRpbWUgd2Ugc3RhcnQgZnJvbSBpZi1wYXJ0PGJyPivCoMKg wqDCoMKgwqDCoMKgIChjb21wbGV0ZSBuaWwpKTxicj7CoMKgwqDCoCA7OyAobWVzc2FnZSAmcXVv dDt0ZXN0ID0gJXMmcXVvdDsgdGVzdCkgKHNpdC1mb3IgMSk8YnI+wqA8YnI+wqDCoMKgwqAgKGhp Zi1oaWRlLWxpbmUgKGhpZi1yYW5nZS1lbmQgcmFuZ2UpKTxicj4twqDCoMKgIChpZiAobm90ICho aWYtbm90IChmdW5jYWxsIGhpZGUtaWZkZWYtZXZhbHVhdG9yIHRlc3QpKSk8YnI+DQoNCi3CoMKg wqAgKGNvbmQgKChoaWYtcmFuZ2UtZWxzZSByYW5nZSnCoMKgwqAgOyBjYXNlIDE8YnI+K8KgwqDC oCAod2hpbGUgKG5vdCBjb21wbGV0ZSk8YnI+K8KgwqDCoMKgwqAgKGlmIChhbmQgKG5vdCAoYW5k IGV4cGFuZC1yZWluY2x1c2lvbiBpZi1wYXJ0KSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgKGhpZi1ub3QgKGZ1bmNhbGwgaGlkZS1pZmRlZi1ldmFsdWF0b3IgdGVzdCkpKTxicj4r wqDCoMKgwqDCoMKgwqDCoMKgIDs7IGlmWC9lbGlmIGlzIEZBTFNFPGJyPg0KDQorwqDCoMKgwqDC oMKgwqDCoMKgIChpZiBlbGlmczxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgOzsgQ2Fz ZSAzIC0gSGlkZSB0aGUgI2lmWCBhbmQgZXZhbCAjZWxpZjxicj4rwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgKGxldCAoKG5ld3N0YXJ0IChjYXIgZWxpZnMpKSk8YnI+K8KgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCAoaGlmLWhpZGUtbGluZSAoaGlmLXJhbmdlLXN0YXJ0IHJhbmdlKSk8 YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoaGlkZS1pZmRlZi1yZWdpb24gKGhp Zi1yYW5nZS1zdGFydCByYW5nZSk8YnI+DQoNCivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoMS0gbmV3c3RhcnQpKTxi cj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChzZXRjYXIgcmFuZ2UgbmV3c3RhcnQp PGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGdvdG8tY2hhciBuZXdzdGFydCk8 YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoc2V0cSBlbGlmcyAoY2RyIGVsaWZz KSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoc2V0cSB0ZXN0IChoaWYtY2Fu b25pY2FsaXplIGhpZi1lbGlmLXJlZ2V4cCkpKTxicj4NCg0KKzxicj4rwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCA7OyBDaGVjayBmb3IgI2Vsc2U8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGNv bmQgKChoaWYtcmFuZ2UtZWxzZSByYW5nZSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCA7OyBDYXNlIDQgLSAjZWxzZSBibG9jayB2aXNpYmxlPGJyPivCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGhpZi1oaWRlLWxpbmUgKGhpZi1yYW5nZS1lbHNl IHJhbmdlKSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoaGlkZS1p ZmRlZi1yZWdpb24gKGhpZi1yYW5nZS1zdGFydCByYW5nZSk8YnI+DQoNCivCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoCAoMS0gKGhpZi1yYW5nZS1lbHNlIHJhbmdlKSkpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgKGhpZi1yZWN1cnNlLW9uIChoaWYtcmFuZ2UtZWxzZSByYW5nZSk8 YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIChoaWYtcmFuZ2UtZW5kIHJhbmdlKSkpPGJyPivCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgICh0PGJyPg0KDQorwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIDs7IENhc2UgNSAtIE5vICNlbHNlIGJsb2NrLCBoaWRlICNpZlg8YnI+K8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoaGlkZS1pZmRlZi1yZWdpb24gKHBv aW50KTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKDEtIChoaWYtcmFuZ2UtZW5kIHJhbmdlKSkpKSk8 YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKHNldHEgY29tcGxldGUgdCkpPGJyPis8YnI+DQoN CivCoMKgwqDCoMKgwqDCoCA7OyBpZlgvZWxpZiBpcyBUUlVFPGJyPivCoMKgwqDCoMKgwqDCoCAo Y29uZCAoZWxpZnM8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgOzsgTHVrZSBmaXg6 IGRpc3Rpbmd1aXNoIGZyb20gI2VsaWYuLiNlbGlmIHRvICNlbGlmLi4jZWxzZTxicj4rwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAobGV0ICgoZWxpZiAoY2FyIGVsaWZzKSkpPGJyPivCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCA7OyBoaWRlIGFsbCBlbGlmczxicj4rwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGhpZi1oaWRlLWxpbmUgZWxpZik8YnI+DQoNCivC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoaGlkZS1pZmRlZi1yZWdpb24gZWxpZiAo MS0gKGhpZi1yYW5nZS1lbmQgcmFuZ2UpKSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIChoaWYtcmVjdXJzZS1vbiAoaGlmLXJhbmdlLXN0YXJ0IHJhbmdlKTxicj4rwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBlbGlmKSkpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoKGhpZi1yYW5nZS1lbHNl IHJhbmdlKTxicj4NCg0KK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgOzsgQ2FzZSAxIC0g SGlkZSAjZWxpZiBhbmQgI2Vsc2UgYmxvY2tzLCByZWN1cnNlICNpZlg8YnI+wqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIChoaWYtaGlkZS1saW5lIChoaWYtcmFuZ2UtZWxzZSByYW5nZSkp PGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoaGlkZS1pZmRlZi1yZWdpb24gKGhp Zi1yYW5nZS1lbHNlIHJhbmdlKTxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoMS0gKGhpZi1yYW5nZS1lbmQgcmFu Z2UpKSk8YnI+DQoNCsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoaGlmLXJlY3Vyc2Ut b24gKGhpZi1yYW5nZS1zdGFydCByYW5nZSk8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGhpZi1yYW5nZS1lbHNlIHJhbmdl KSkpPGJyPi3CoMKgwqAgwqDCoMKgwqDCoCAodMKgwqDCoCDCoMKgwqAgwqDCoMKgIDsgY2FzZSAy PGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAodDxicj4rwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCA7OyBDYXNlIDIgLSBObyAjZWxzZSwganVzdCByZWN1cnNlICNpZlg8YnI+DQoN CsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoaGlmLXJlY3Vyc2Utb24gKGhpZi1yYW5n ZS1zdGFydCByYW5nZSk8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGhpZi1yYW5nZS1lbmQgcmFuZ2UpKSkpPGJyPi3CoMKg wqDCoMKgIChjb25kICgoaGlmLXJhbmdlLWVsc2UgcmFuZ2UpwqDCoMKgIDsgY2FzZSAzPGJyPi3C oMKgwqAgwqDCoMKgwqAgKGhpZi1oaWRlLWxpbmUgKGhpZi1yYW5nZS1lbHNlIHJhbmdlKSk8YnI+ DQoNCi3CoMKgwqAgwqDCoMKgwqAgKGhpZGUtaWZkZWYtcmVnaW9uIChoaWYtcmFuZ2Utc3RhcnQg cmFuZ2UpPGJyPi3CoMKgwqAgwqDCoMKgIMKgwqDCoCDCoMKgwqAgKDEtIChoaWYtcmFuZ2UtZWxz ZSByYW5nZSkpKTxicj4twqDCoMKgIMKgwqDCoMKgIChoaWYtcmVjdXJzZS1vbiAoaGlmLXJhbmdl LWVsc2UgcmFuZ2UpPGJyPi3CoMKgwqAgwqDCoMKgIMKgwqDCoCDCoMKgwqDCoCAoaGlmLXJhbmdl LWVuZCByYW5nZSkpKTxicj4twqDCoMKgIMKgwqDCoCAodMKgwqDCoCDCoMKgwqAgwqDCoMKgIMKg wqDCoCA7IGNhc2UgNDxicj4NCg0KLcKgwqDCoCDCoMKgwqDCoCAoaGlkZS1pZmRlZi1yZWdpb24g KHBvaW50KTxicj4twqDCoMKgIMKgwqDCoCDCoMKgwqAgwqDCoMKgICgxLSAoaGlmLXJhbmdlLWVu ZCByYW5nZSkpKSkpKTxicj4rwqDCoMKgwqDCoMKgwqAgKHNldHEgY29tcGxldGUgdCkpPGJyPivC oMKgwqDCoMKgIChzZXRxIGlmLXBhcnQgbmlsKSk8YnI+Kzxicj4rwqDCoMKgIDs7IGNvbXBsZXRl ID0gdDxicj7CoMKgwqDCoCAoaGlmLWhpZGUtbGluZSAoaGlmLXJhbmdlLXN0YXJ0IHJhbmdlKSkg OyBBbHdheXMgaGlkZSBzdGFydC48YnI+DQoNCsKgwqDCoMKgIChnb3RvLWNoYXIgKGhpZi1yYW5n ZS1lbmQgcmFuZ2UpKTxicj7CoMKgwqDCoCAoZW5kLW9mLWxpbmUpKSk8YnI+wqA8YnI+KyhkZWZ1 biBoaWYtZXZhbHVhdGUtcmVnaW9uIChzdGFydCBlbmQpPGJyPivCoCAobGV0KiAoKHRva2VucyAo aWdub3JlLWVycm9ycyA7IFByZXZlbnQgQyBzdGF0ZW1lbnQgdGhpbmdzIGxpa2U8YnI+K8KgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IDsgJiMzOTtkbyB7IC4uLiB9IHdoaWxlICgwKSYjMzk7PGJyPg0KDQorwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWYtdG9rZW5pemUgc3RhcnQgZW5kKSkpPGJyPivCoMKg wqDCoMKgwqDCoMKgIChleHByIChhbmQgdG9rZW5zPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCAoY29uZGl0aW9uLWNhc2UgbmlsPGJyPivCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWYtcGFyc2UtZXhwIHRva2Vucyk8YnI+ K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoZXJyb3I8YnI+K8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHRva2VucykpKSk8YnI+ DQoNCivCoMKgwqDCoMKgwqDCoMKgIChyZXN1bHQgKGZ1bmNhbGwgaGlkZS1pZmRlZi1ldmFsdWF0 b3IgZXhwcikpKTxicj4rwqDCoMKgIHJlc3VsdCkpPGJyPis8YnI+KyhkZWZ1biBoaWYtZXZhbHVh dGUtbWFjcm8gKHJzdGFydCByZW5kKTxicj4rwqAgJnF1b3Q7RXZhbHVhdGUgdGhlIG1hY3JvIGV4 cGFuc2lvbiByZXN1bHQgZm9yIGEgcmVnaW9uLjxicj4rSWYgbm8gcmVnaW9uIGFjdGl2ZSwgZmlu ZCB0aGUgY3VycmVudCAjaWZkZWZzIGFuZCBldmFsdWF0ZSB0aGUgcmVzdWx0Ljxicj4NCg0KK0N1 cnJlbnRseSBpdCBzdXBwb3J0cyBvbmx5IG1hdGggY2FsY3VsYXRpb25zLCBzdHJpbmdzIG9yIGFy Z3VtZW50ZWQgbWFjcm9zIGNhbjxicj4rbm90IGJlIGV4cGFuZGVkLiZxdW90Ozxicj4rwqAgKGlu dGVyYWN0aXZlICZxdW90O3ImcXVvdDspPGJyPivCoCAobGV0ICgoY2FzZS1mb2xkLXNlYXJjaCBu aWwpKTxicj4rwqDCoMKgIChzYXZlLWV4Y3Vyc2lvbjxicj4rwqDCoMKgwqDCoCAodW5sZXNzIG1h cmstYWN0aXZlPGJyPg0KDQorwqDCoMKgwqDCoMKgwqAgKHNldHEgcnN0YXJ0IG5pbCByZW5kIG5p bCk8YnI+K8KgwqDCoMKgwqDCoMKgIChiZWdpbm5pbmctb2YtbGluZSk8YnI+K8KgwqDCoMKgwqDC oMKgICh3aGVuIChhbmQgKHJlLXNlYXJjaC1mb3J3YXJkIGhpZi1tYWNyby1leHByLXByZWZpeC1y ZWdleHAgbmlsIHQpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKHN0 cmluZz0gJnF1b3Q7ZGVmaW5lJnF1b3Q7IChtYXRjaC1zdHJpbmcgMikpKTxicj4rwqDCoMKgwqDC oMKgwqDCoMKgIChyZS1zZWFyY2gtZm9yd2FyZCBoaWYtbWFjcm9yZWYtcmVnZXhwIG5pbCB0KSkp PGJyPg0KDQorwqDCoMKgwqDCoCAobGV0KiAoKHN0YXJ0IChvciByc3RhcnQgKHBvaW50KSkpPGJy PivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGVuZMKgwqAgKG9yIHJlbmQgKHByb2duIChoaWYt ZW5kLW9mLWxpbmUpIChwb2ludCkpKSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoZGVm aW5lZCBuaWwpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKHNpbXBsZSAmIzM5O3QpPGJy PivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKHRva2VucyAoaWdub3JlLWVycm9ycyA7IFByZXZl bnQgQyBzdGF0ZW1lbnQgdGhpbmdzIGxpa2U8YnI+DQoNCivCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg OyAmIzM5O2RvIHsgLi4uIH0gd2hpbGUgKDApJiMzOTs8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWYtdG9rZW5pemUgc3RhcnQgZW5kKSkpPGJyPivC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGV4cHIgKG9yIChhbmQgKCZsdDs9IChsZW5ndGggdG9r ZW5zKSAxKSA7IFNpbXBsZSB0b2tlbjxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChzZXRxIGRlZmluZWQgKGFzc29jIChjYXIgdG9rZW5z KSBoaWRlLWlmZGVmLWVudikpPGJyPg0KDQorwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChzZXRxIHNpbXBsZSAoYXRvbSAoaGlmLWxvb2t1cCAo Y2FyIHRva2VucykpKSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCAoaGlmLWxvb2t1cCAoY2FyIHRva2VucykpKTxicj4rwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGFuZCB0b2tlbnM8YnI+K8KgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoY29uZGl0 aW9uLWNhc2UgbmlsPGJyPg0KDQorwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGhpZi1wYXJzZS1leHAgdG9rZW5zKTxicj4rwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAo ZXJyb3I8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCBuaWwpKSkpKTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChyZXN1 bHQgKGZ1bmNhbGwgaGlkZS1pZmRlZi1ldmFsdWF0b3IgZXhwcikpPGJyPivCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgKGV4cHJzdHJpbmcgKHJlcGxhY2UtcmVnZXhwLWluLXN0cmluZzxicj4NCg0K K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDs7IFRy aW0gb2ZmIGxlYWRpbmcvdHJhaWxpbmcgd2hpdGVzPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAmcXVvdDteWyBcdF0qXFwoW14gXHRdK1xcKVsg XHRdKiZxdW90OyAmcXVvdDtcXDEmcXVvdDs8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChyZXBsYWNlLXJlZ2V4cC1pbi1zdHJpbmc8YnI+K8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgJnF1b3Q7 XFwoLy8uKlxcKSZxdW90OyAmcXVvdDsmcXVvdDsgOyBUcmltIG9mZiBlbmQtb2YtbGluZSBjb21t ZW50czxicj4NCg0KK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgKGJ1ZmZlci1zdWJzdHJpbmctbm8tcHJvcGVydGllcyBzdGFydCBlbmQpKSkpKTxi cj4rwqDCoMKgwqDCoMKgwqAgKGNvbmQ8YnI+K8KgwqDCoMKgwqDCoMKgwqAgKChhbmQgKCZsdDs9 IChsZW5ndGggdG9rZW5zKSAxKSBzaW1wbGUpIDsgU2ltcGxlIHRva2VuPGJyPivCoMKgwqDCoMKg wqDCoMKgwqAgKGlmIGRlZmluZWQ8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChtZXNz YWdlICZxdW90OyVTICZsdDs9IGAlcyYjMzk7JnF1b3Q7IHJlc3VsdCBleHByc3RyaW5nKTxicj4N Cg0KK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKG1lc3NhZ2UgJnF1b3Q7YCVzJiMzOTsgaXMgbm90 IGRlZmluZWQmcXVvdDsgZXhwcnN0cmluZykpKTxicj4rwqDCoMKgwqDCoMKgwqDCoCAoKGludGVn ZXJwIHJlc3VsdCk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoCAoaWYgKG9yICg9IDAgcmVzdWx0KSAo PSAxIHJlc3VsdCkpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAobWVzc2FnZSAmcXVv dDslUyAmbHQ7PSBgJXMmIzM5OyZxdW90OyByZXN1bHQgZXhwcnN0cmluZyk8YnI+DQoNCivCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIChtZXNzYWdlICZxdW90OyVTICgweCV4KSAmbHQ7PSBgJXMmIzM5 OyZxdW90OyByZXN1bHQgcmVzdWx0IGV4cHJzdHJpbmcpKSk8YnI+K8KgwqDCoMKgwqDCoMKgwqAg KChudWxsIHJlc3VsdCkgKG1lc3NhZ2UgJnF1b3Q7JVMgJmx0Oz0gYCVzJiMzOTsmcXVvdDsgJiMz OTtmYWxzZSBleHByc3RyaW5nKSk8YnI+K8KgwqDCoMKgwqDCoMKgwqAgKChlcSB0IHJlc3VsdCkg KG1lc3NhZ2UgJnF1b3Q7JVMgJmx0Oz0gYCVzJiMzOTsmcXVvdDsgJiMzOTt0cnVlIGV4cHJzdHJp bmcpKTxicj4NCg0KK8KgwqDCoMKgwqDCoMKgwqAgKHQgKG1lc3NhZ2UgJnF1b3Q7JVMgJmx0Oz0g YCVzJiMzOTsmcXVvdDsgcmVzdWx0IGV4cHJzdHJpbmcpKSk8YnI+K8KgwqDCoMKgwqDCoMKgIHJl c3VsdCkpKSk8YnI+Kzxicj7CoChkZWZ1biBoaWYtcGFyc2UtbWFjcm8tYXJnbGlzdCAoc3RyKTxi cj7CoMKgICZxdW90O1BhcnNlIGFyZ3VtZW50IGxpc3QgZm9ybWF0dGVkIGFzICYjMzk7KCBhcmcx IFsgLCBhcmduXSBbLi4uXSApJiMzOTsuPGJyPg0KDQrCoFRoZSAmIzM5Oy4uLiYjMzk7IGlzIGFs c28gaW5jbHVkZWQuwqAgUmV0dXJuIGEgbGlzdCBvZiB0aGUgYXJndW1lbnRzLCBpZiAmIzM5Oy4u LiYjMzk7IGV4aXN0cyB0aGU8YnI+QEAgLTE1MzAsNyArMTc1NSwxMiBAQCBmaXJzdCBhcmcgd2ls bCBiZSBgaGlmLWV0YyYjMzk7LiZxdW90Ozxicj7CoEl0IGRvZXMgbm90IGRvIHRoZSB3b3JrIHRo YXQmIzM5O3MgcG9pbnRsZXNzIHRvIHJlZG8gb24gYSByZWN1cnNpdmUgZW50cnkuJnF1b3Q7PGJy Pg0KDQrCoMKgIDs7IChtZXNzYWdlICZxdW90O2hpZGUtaWZkZWYtZ3V0cyZxdW90Oyk8YnI+wqDC oCAoc2F2ZS1leGN1cnNpb248YnI+LcKgwqDCoCAobGV0ICgoY2FzZS1mb2xkLXNlYXJjaCBuaWwp PGJyPivCoMKgwqAgKGxldCogKChjYXNlLWZvbGQtc2VhcmNoIHQpIDsgSWdub3JlIGNhc2UgZm9y IGBoaWRlLWlmZGVmLWhlYWRlci1yZWdleHAmIzM5Ozxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqAg KGV4cGFuZC1oZWFkZXIgKGFuZCBoaWRlLWlmZGVmLWV4cGFuZC1yZWluY2x1c2lvbi1wcm90ZWN0 aW9uPGJyPg0KDQorwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIChzdHJpbmctbWF0Y2ggaGlkZS1pZmRlZi1oZWFkZXItcmVnZXhwPGJy PivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChidWZmZXItZmlsZS1uYW1lKSk8YnI+ K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoCAoemVyb3AgaGlmLXJlY3Vyc2UtbGV2ZWwpKSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKg IChjYXNlLWZvbGQtc2VhcmNoIG5pbCk8YnI+DQoNCsKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgbWlu IG1heCk8YnI+wqDCoMKgwqDCoMKgIChnb3RvLWNoYXIgKHBvaW50LW1pbikpPGJyPsKgwqDCoMKg wqDCoCAoc2V0ZiBtaW4gKHBvaW50KSk8YnI+QEAgLTE1MzgsNyArMTc2OCw3IEBAIEl0IGRvZXMg bm90IGRvIHRoZSB3b3JrIHRoYXQmIzM5O3MgcG9pbnRsZXNzIHRvIHJlZG8gb24gYSByZWN1cnNp dmUgZW50cnkuJnF1b3Q7PGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoc2V0ZiBt YXggKGhpZi1maW5kLWFueS1pZlgpKTxicj4NCg0KwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIChoaWYtYWRkLW5ldy1kZWZpbmVzIG1pbiBtYXgpPGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCAoaWYgbWF4PGJyPi3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgKGhpZi1wb3NzaWJseS1oaWRlKSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCAoaGlmLXBvc3NpYmx5LWhpZGUgZXhwYW5kLWhlYWRlcikpPGJyPsKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCAoc2V0ZiBtaW4gKHBvaW50KSk8YnI+wqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIHdoaWxlIG1heCkpKSk8YnI+DQoNCsKgPGJyPkBAIC0xNTg1LDE3ICsx ODE1LDMwIEBAIEl0IGRvZXMgbm90IGRvIHRoZSB3b3JrIHRoYXQmIzM5O3MgcG9pbnRsZXNzIHRv IHJlZG8gb24gYSByZWN1cnNpdmUgZW50cnkuJnF1b3Q7PGJyPsKgwqDCoMKgIMKgIChvdmVybGF5 LXB1dCBvdmVybGF5ICYjMzk7ZmFjZSBuaWwpPGJyPsKgwqDCoMKgIMKgIChvdmVybGF5LXB1dCBv dmVybGF5ICYjMzk7aW52aXNpYmxlICYjMzk7aGlkZS1pZmRlZikpKSkpKTxicj4NCg0KwqA8YnI+ LShkZWZ1biBoaWRlLWlmZGVmLWRlZmluZSAodmFyKTxicj4twqAgJnF1b3Q7RGVmaW5lIGEgVkFS IHNvIHRoYXQgI2lmZGVmIFZBUiB3b3VsZCBiZSBpbmNsdWRlZC4mcXVvdDs8YnI+LcKgIChpbnRl cmFjdGl2ZSAmcXVvdDtTRGVmaW5lIHdoYXQ/ICZxdW90Oyk8YnI+LcKgIChoaWYtc2V0LXZhciB2 YXIgMSk8YnI+KyhkZWZ1biBoaWRlLWlmZGVmLWRlZmluZSAodmFyICZhbXA7b3B0aW9uYWwgdmFs KTxicj4NCg0KK8KgICZxdW90O0RlZmluZSBhIFZBUiB0byBWQUwgKGRlZmF1bHQgMSkgaW4gYGhp ZGUtaWZkZWYtZW52JiMzOTsuPGJyPitUaGlzIGFsbG93cyAjaWZkZWYgVkFSIHRvIGJlIGhpZGRl bi4mcXVvdDs8YnI+K8KgIChpbnRlcmFjdGl2ZTxicj4rwqDCoCAobGV0KiAoKGRlZmF1bHQgKHNh dmUtZXhjdXJzaW9uPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IChiZWdpbm5pbmctb2YtbGluZSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgKGNvbmQgKChsb29raW5nLWF0IGhpZi1pZngtZWxzZS1lbmRpZi1yZWdleHApPGJy Pg0KDQorwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIChmb3J3YXJkLXdvcmQgMik8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoY3VycmVudC13b3JkICYjMzk7c3RyaWN0KSk8YnI+K8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKHQ8YnI+ K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBu aWwpKSkpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqAgKHZhciAocmVhZC1taW5pYnVmZmVyICZxdW90 O0RlZmluZSB3aGF0PyAmcXVvdDsgZGVmYXVsdCkpPGJyPg0KDQorwqDCoMKgwqDCoMKgwqDCoMKg ICh2YWwgKHJlYWQtZnJvbS1taW5pYnVmZmVyIChmb3JtYXQgJnF1b3Q7U2V0ICVzIHRvPyAoZGVm YXVsdCAxKTogJnF1b3Q7IHZhcik8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBuaWwgbmlsIHQgbmlsICZx dW90OzEmcXVvdDspKSk8YnI+K8KgwqDCoMKgIChsaXN0IHZhciB2YWwpKSk8YnI+K8KgIChoaWYt c2V0LXZhciB2YXIgKG9yIHZhbCAxKSk8YnI+DQoNCivCoCAobWVzc2FnZSAmcXVvdDslcyBzZXQg dG8gJXMmcXVvdDsgdmFyIChvciB2YWwgMSkpPGJyPivCoCAoc2xlZXAtZm9yIDEpPGJyPsKgwqAg KGlmIGhpZGUtaWZkZWYtaGlkaW5nIChoaWRlLWlmZGVmcykpKTxicj7CoDxicj7CoChkZWZ1biBo aWYtdW5kZWZpbmUtc3ltYm9sICh2YXIpPGJyPsKgwqAgKHNldHEgaGlkZS1pZmRlZi1lbnY8YnI+ wqDCoMKgwqDCoMKgwqDCoCAoZGVsZXRlIChhc3NvYyB2YXIgaGlkZS1pZmRlZi1lbnYpIGhpZGUt aWZkZWYtZW52KSkpPGJyPg0KDQrCoDxicj4tPGJyPsKgKGRlZnVuIGhpZGUtaWZkZWYtdW5kZWYg KHN0YXJ0IGVuZCk8YnI+wqDCoCAmcXVvdDtVbmRlZmluZSBhIFZBUiBzbyB0aGF0ICNpZmRlZiBW QVIgd291bGQgbm90IGJlIGluY2x1ZGVkLiZxdW90Ozxicj7CoMKgIChpbnRlcmFjdGl2ZSAmcXVv dDtyJnF1b3Q7KTxicj5AQCAtMTYxNiwyMCArMTg1OSwyMyBAQCBJdCBkb2VzIG5vdCBkbyB0aGUg d29yayB0aGF0JiMzOTtzIHBvaW50bGVzcyB0byByZWRvIG9uIGEgcmVjdXJzaXZlIGVudHJ5LiZx dW90Ozxicj4NCg0KwqBBc3N1bWUgdGhhdCBkZWZpbmVkIHN5bWJvbHMgaGF2ZSBiZWVuIGFkZGVk IHRvIGBoaWRlLWlmZGVmLWVudiYjMzk7Ljxicj7CoFRoZSB0ZXh0IGhpZGRlbiBpcyB0aGUgdGV4 dCB0aGF0IHdvdWxkIG5vdCBiZSBpbmNsdWRlZCBieSB0aGUgQzxicj7CoHByZXByb2Nlc3NvciBp ZiBpdCB3ZXJlIGdpdmVuIHRoZSBmaWxlIHdpdGggdGhvc2Ugc3ltYm9scyBkZWZpbmVkLjxicj4r V2l0aCBwcmVmaXggY29tbWFuZCBwcmVzZW50cyBpdCB3aWxsIGFsc28gaGlkZSB0aGUgI2lmZGVm cyB0aGVtc2VsdmVzLjxicj4NCg0KwqA8YnI+wqBUdXJuIG9mZiBoaWRpbmcgYnkgY2FsbGluZyBg c2hvdy1pZmRlZnMmIzM5Oy4mcXVvdDs8YnI+wqA8YnI+wqDCoCAoaW50ZXJhY3RpdmUpPGJyPi3C oCAobWVzc2FnZSAmcXVvdDtIaWRpbmcuLi4mcXVvdDspPGJyPivCoCAobGV0ICgoaGlkZS1pZmRl Zi1saW5lcyBjdXJyZW50LXByZWZpeC1hcmcpKTxicj4rwqDCoMKgIChvciBub21zZzxicj4rwqDC oMKgwqDCoMKgwqAgKG1lc3NhZ2UgJnF1b3Q7SGlkaW5nLi4uJnF1b3Q7KSk8YnI+DQoNCsKgwqDC oMKgIChzZXRxIGhpZi1vdXRzaWRlLXJlYWQtb25seSBidWZmZXItcmVhZC1vbmx5KTxicj4twqAg KHVubGVzcyBoaWRlLWlmZGVmLW1vZGUgKGhpZGUtaWZkZWYtbW9kZSAxKSkgOyB0dXJuIG9uIGhp ZGUtaWZkZWYtbW9kZTxicj4rwqDCoMKgICh1bmxlc3MgaGlkZS1pZmRlZi1tb2RlIChoaWRlLWlm ZGVmLW1vZGUgMSkpIDsgVHVybiBvbiBoaWRlLWlmZGVmLW1vZGU8YnI+wqDCoMKgwqAgKGlmIGhp ZGUtaWZkZWYtaGlkaW5nPGJyPg0KDQrCoMKgwqDCoMKgwqDCoMKgIChzaG93LWlmZGVmcykpwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgOyBPdGhlcndpc2UsIGRlZXAgY29u ZnVzaW9uLjxicj7CoMKgwqDCoCAoc2V0cSBoaWRlLWlmZGVmLWhpZGluZyB0KTxicj7CoMKgwqDC oCAoaGlkZS1pZmRlZi1ndXRzKTxicj7CoMKgwqDCoCAoc2V0cSBidWZmZXItcmVhZC1vbmx5IChv ciBoaWRlLWlmZGVmLXJlYWQtb25seSBoaWYtb3V0c2lkZS1yZWFkLW9ubHkpKTxicj7CoMKgwqDC oCAob3Igbm9tc2c8YnI+DQoNCi3CoMKgwqDCoMKgIChtZXNzYWdlICZxdW90O0hpZGluZyBkb25l JnF1b3Q7KSkpPGJyPivCoMKgwqDCoMKgwqDCoCAobWVzc2FnZSAmcXVvdDtIaWRpbmcgZG9uZSZx dW90OykpKSk8YnI+wqA8YnI+wqA8YnI+wqAoZGVmdW4gc2hvdy1pZmRlZnMgKCk8YnI+QEAgLTE2 NjEsOSArMTkwNywxNSBAQCBSZXR1cm4gYXMgKFRPUCAuIEJPVFRPTSkgdGhlIGV4dGVudCBvZiBp ZmRlZiBibG9jay4mcXVvdDs8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAobWluIG1h eC1ib3R0b20gKDEtIChwb2ludCkpKSkpKSk8YnI+DQoNCsKgPGJyPsKgPGJyPi0oZGVmdW4gaGlk ZS1pZmRlZi1ibG9jayAoKTxicj4twqAgJnF1b3Q7SGlkZSB0aGUgaWZkZWYgYmxvY2sgKHRydWUg b3IgZmFsc2UgcGFydCkgZW5jbG9zaW5nIG9yIGJlZm9yZSB0aGUgY3Vyc29yLiZxdW90Ozxicj4t wqAgKGludGVyYWN0aXZlKTxicj4rKGRlZnVuIGhpZGUtaWZkZWYtYmxvY2sgKCZhbXA7b3B0aW9u YWwgYXJnIHN0YXJ0IGVuZCk8YnI+K8KgICZxdW90O0hpZGUgdGhlIGlmZGVmIGJsb2NrICh0cnVl IG9yIGZhbHNlIHBhcnQpIGVuY2xvc2luZyBvciBiZWZvcmUgdGhlIGN1cnNvci48YnI+DQoNCitX aXRoIG9wdGlvbmFsIHByZWZpeCBhZ3VtZW50IEFSRywgYWxzbyBoaWRlIHRoZSAjaWZkZWZzIHRo ZW1zZWx2ZXMuJnF1b3Q7PGJyPivCoCAoaW50ZXJhY3RpdmUgJnF1b3Q7UFxuciZxdW90Oyk8YnI+ K8KgIChsZXQgKChoaWRlLWlmZGVmLWxpbmVzIGFyZykpPGJyPivCoMKgwqAgKGlmIG1hcmstYWN0 aXZlPGJyPivCoMKgwqDCoMKgwqDCoCAobGV0ICgoaGlmLXJlY3Vyc2UtbGV2ZWwgKDErIGhpZi1y ZWN1cnNlLWxldmVsKSkpPGJyPg0KDQorwqDCoMKgwqDCoMKgwqDCoMKgIChoaWYtcmVjdXJzZS1v biBzdGFydCBlbmQgdCk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoCAoc2V0cSBtYXJrLWFjdGl2ZSBu aWwpKTxicj7CoMKgwqDCoMKgwqAgKHVubGVzcyBoaWRlLWlmZGVmLW1vZGUgKGhpZGUtaWZkZWYt bW9kZSAxKSk8YnI+wqDCoMKgwqDCoMKgIChsZXQgKCh0b3AtYm90dG9tIChoaWYtZmluZC1pZmRl Zi1ibG9jaykpKTxicj7CoMKgwqDCoMKgwqDCoMKgIChoaWRlLWlmZGVmLXJlZ2lvbiAoY2FyIHRv cC1ib3R0b20pIChjZHIgdG9wLWJvdHRvbSkpPGJyPg0KDQpAQCAtMTY3MSwxMiArMTkyMywyNiBA QCBSZXR1cm4gYXMgKFRPUCAuIEJPVFRPTSkgdGhlIGV4dGVudCBvZiBpZmRlZiBibG9jay4mcXVv dDs8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqAgKGhpZi1oaWRlLWxpbmUgKGNhciB0b3AtYm90dG9t KSk8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqAgKGhpZi1oaWRlLWxpbmUgKDErIChjZHIgdG9wLWJv dHRvbSkpKSk8YnI+wqDCoMKgwqDCoMKgwqDCoCAoc2V0cSBoaWRlLWlmZGVmLWhpZGluZyB0KSk8 YnI+DQoNCi3CoCAoc2V0cSBidWZmZXItcmVhZC1vbmx5IChvciBoaWRlLWlmZGVmLXJlYWQtb25s eSBoaWYtb3V0c2lkZS1yZWFkLW9ubHkpKSk8YnI+K8KgwqDCoMKgwqAgKHNldHEgYnVmZmVyLXJl YWQtb25seTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAob3IgaGlkZS1pZmRlZi1yZWFkLW9u bHkgaGlmLW91dHNpZGUtcmVhZC1vbmx5KSkpKSk8YnI+wqA8YnI+LShkZWZ1biBzaG93LWlmZGVm LWJsb2NrICgpPGJyPisoZGVmdW4gc2hvdy1pZmRlZi1ibG9jayAoJmFtcDtvcHRpb25hbCBzdGFy dCBlbmQpPGJyPg0KDQrCoMKgICZxdW90O1Nob3cgdGhlIGlmZGVmIGJsb2NrICh0cnVlIG9yIGZh bHNlIHBhcnQpIGVuY2xvc2luZyBvciBiZWZvcmUgdGhlIGN1cnNvci4mcXVvdDs8YnI+LcKgIChp bnRlcmFjdGl2ZSk8YnI+LcKgIChsZXQgKCh0b3AtYm90dG9tIChoaWYtZmluZC1pZmRlZi1ibG9j aykpKTxicj4rwqAgKGludGVyYWN0aXZlICZxdW90O3ImcXVvdDspPGJyPivCoCAoaWYgbWFyay1h Y3RpdmU8YnI+K8KgwqDCoMKgwqAgKHByb2duPGJyPg0KDQorwqDCoMKgwqDCoMKgwqAgKGRvbGlz dCAobyAob3ZlcmxheXMtaW4gc3RhcnQgZW5kKSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoCAoaWYg KG92ZXJsYXktZ2V0IG8gJiMzOTtoaWRlLWlmZGVmKTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgKGRlbGV0ZS1vdmVybGF5IG8pKSk8YnI+K8KgwqDCoMKgwqDCoMKgIChzZXRxIG1hcmst YWN0aXZlIG5pbCkpPGJyPivCoMKgwqAgKGxldCAoKHRvcC1ib3R0b20gKGNvbmRpdGlvbi1jYXNl IG5pbDxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgKGhpZi1maW5kLWlmZGVmLWJsb2NrKTxicj4NCg0KK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGVycm9yPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgbmlsKSkpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqAg KG92cnMgKG92ZXJsYXlzLWluIChtYXggKHBvaW50LW1pbikgKDEtIChwb2ludCkpKTxicj4rwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKG1p biAocG9pbnQtbWF4KSAoMSsgKHBvaW50KSkpKSk8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoCAoZGVs IG5pbCkpPGJyPg0KDQorwqDCoMKgwqDCoCAoaWYgdG9wLWJvdHRvbTxicj7CoMKgwqDCoCAoaWYg aGlkZS1pZmRlZi1saW5lczxicj7CoMKgwqDCoMKgwqDCoMKgIChoaWYtc2hvdy1pZmRlZi1yZWdp b248YnI+wqDCoMKgwqDCoMKgwqDCoMKgIChzYXZlLWV4Y3Vyc2lvbjxicj5AQCAtMTY4NCw3ICsx OTUwLDE1IEBAIFJldHVybiBhcyAoVE9QIC4gQk9UVE9NKSB0aGUgZXh0ZW50IG9mIGlmZGVmIGJs b2NrLiZxdW90Ozxicj7CoMKgwqDCoMKgwqDCoMKgwqAgKHNhdmUtZXhjdXJzaW9uPGJyPg0KDQrC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIChnb3RvLWNoYXIgKDErIChjZHIgdG9wLWJvdHRvbSkpKTxi cj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChoaWYtZW5kLW9mLWxpbmUpIChwb2ludCkpKTxicj4t wqDCoMKgwqDCoCAoaGlmLXNob3ctaWZkZWYtcmVnaW9uICgxLSAoY2FyIHRvcC1ib3R0b20pKSAo Y2RyIHRvcC1ib3R0b20pKSkpKTxicj4rwqDCoMKgwqDCoCAoc2V0ZiBkZWwgKGhpZi1zaG93LWlm ZGVmLXJlZ2lvbjxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKDEtIChjYXIg dG9wLWJvdHRvbSkpIChjZHIgdG9wLWJvdHRvbSkpKSkpPGJyPg0KDQorwqDCoMKgwqDCoCAoaWYg KG5vdCAoYW5kIHRvcC1ib3R0b208YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIGRlbCkpPGJyPivCoMKgwqDCoMKgwqDCoMKgwqAgKGRvbGlzdCAobyBvdnJzKTxicj4r wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCA7Oyhkb2xpc3QgKG8gKG92ZXJsYXlzLWluICgxLSAocG9p bnQpKSAoMSsgKHBvaW50KSkpKTxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCA7O8KgwqAgKGlm IChvdmVybGF5LWdldCBvICYjMzk7aGlkZS1pZmRlZikgKG1lc3NhZ2UgJnF1b3Q7JVMmcXVvdDsg bykpKTxicj4NCg0KK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGlmIChvdmVybGF5LWdldCBvICYj Mzk7aGlkZS1pZmRlZik8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoZGVsZXRl LW92ZXJsYXkgbykpKSkpKSk8YnI+wqA8YnI+wqA8YnI+wqA7OzvCoCBkZWZpbml0aW9uIGFsaXN0 IHN1cHBvcnQgPGJyPjxicj4NCjwvZGl2PjwvZGl2PjwvZGl2Pg0K --047d7bf0d57885d56104fd40e578--