From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Thor Nordstrand Newsgroups: gmane.emacs.help Subject: SV: Post script printing from emacs Date: Fri, 4 Jan 2008 13:42:47 +0100 (MET) Message-ID: <27135590.2493421199450567640.JavaMail.adm-moff@moffice5.nsc.no> References: <10914157.2347121199106997805.JavaMail.adm-moff@moffice3.nsc.no> <13353527.1670351199343550657.JavaMail.adm-moff@moffice8.nsc.no> <9D74C25E-D939-4AAE-9410-4DF75B3CA97F@Web.DE> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_252221_12725027.1199450567569" X-Trace: ger.gmane.org 1199451518 2552 80.91.229.12 (4 Jan 2008 12:58:38 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 4 Jan 2008 12:58:38 +0000 (UTC) Cc: help-gnu-emacs@gnu.org To: Peter Dyballa Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Fri Jan 04 13:55:58 2008 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1JAlul-0003oO-Be for geh-help-gnu-emacs@m.gmane.org; Fri, 04 Jan 2008 13:55:58 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JAluG-0001T8-Ui for geh-help-gnu-emacs@m.gmane.org; Fri, 04 Jan 2008 07:44:13 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JAltA-0001SS-7v for help-gnu-emacs@gnu.org; Fri, 04 Jan 2008 07:43:04 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JAlt9-0001Rx-8o for help-gnu-emacs@gnu.org; Fri, 04 Jan 2008 07:43:03 -0500 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JAlt8-0001Rd-LA for help-gnu-emacs@gnu.org; Fri, 04 Jan 2008 07:43:03 -0500 Original-Received: from mail46.e.nsc.no ([193.213.115.46]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1JAlt1-0008T9-6x for help-gnu-emacs@gnu.org; Fri, 04 Jan 2008 07:43:02 -0500 Original-Received: from moffice5.nsc.no (moffice5.e.nsc.no [193.213.115.69]) by mail46.nsc.no (8.13.8/8.13.5) with ESMTP id m04CglDW013311; Fri, 4 Jan 2008 13:42:47 +0100 (MET) In-Reply-To: <9D74C25E-D939-4AAE-9410-4DF75B3CA97F@Web.DE> X-Priority: 3 (Normal) X-Mailer: Mobile Office v1.44 (Telenor Nordic) X-detected-kernel: by monty-python.gnu.org: Solaris 10 (beta) X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:50489 Archived-At: ------=_Part_252221_12725027.1199450567569 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 7bit It looks as if both "ps-number-of-columns" and "ps-landscape-mode" is defined in the files vhdl-mode.elc and vhdl-mode.el (both enclosed). Unfortunately it looks as if the vhdl-mode.elc settings are the master and it is not so easy to change the values here. Do you know how to override these settings from my .emacs file? Should I go into my vhdl-mode.elc to make the changes, changes in the vhdl-mode.el file does not seem to have any effect? Best Regards Thor Nordstrand > From: Peter Dyballa [Peter_Dyballa@Web.DE] > Sent: 2008-01-03 23:53:09 CET > To: Thor Nordstrand [thnords@online.no] > Cc: help-gnu-emacs@gnu.org > Subject: Re: SV: Post script printing from emacs > > > Am 03.01.2008 um 07:59 schrieb Thor Nordstrand: > > > I am using GNU Emacs 20.7.1 for VHDL coding. > > > I'm not sure whether your problem is really an Emacs problem ? I have > an old Emacs 20.7 ... and I can't make it happen! So I assume two > causes: > > ? your system's printing subsystem > ? VHDL mode > > Third cause can be > > ? your own or your system's customisation > > The tests are simple. For example, still in VHDL, print a buffer not > with the ps-print- command, but use the ps-spool- same> command, i.e. "print" substituted with "spool." This will > create a *PostScript* buffer instead of putting the output into the > printer queue. This buffer you can save as .ps. Using gv > or whatever you can check what the Emacs print output looks like > before it was fed into the printer queue. If you see a difference, > then it's due to the printing subsystem, i.e. filters in that printer > queue, or some "mode" in the physical printer (which one is it?), > cause that the queue input's two (or more) pages in portrait mode get > printed side by side on one sheet of paper in landscape mode. (You > might also be able to stop the printer queue from sending its > contents to the printer. Then you could inspect the queue's contents > and compare that with what you've saved in Emacs. For both you'll > need system administrator's privileges, i.e. root access.) > > If the PS file looks exactly like the sheet of paper, then you should > try to print some simple text or some dired or the *Messages* or > *shell* buffer, again with the spool command, to save some paper. > Again two pages on one sheet of landscape paper? Then it must be your > customisation. > > Launching GNU Emacs with -q or --no-init-file will disable it from > loading your init file. Then spool something *before* you opened any > VHDL file. How does it look? If it's still in landscape, then it's > likely that the system's init file is doing something. It's name is > site-init.el, somewhere in load-path. If not, then it's likely your > own customisation. > > I don't have any VHDL by hand so I can't do all the tests myself ... > > -- > Greetings > > Pete > > I love deadlines. I love the whooshing noise they make as they go by. > ? Douglas Adams > > > ------=_Part_252221_12725027.1199450567569 Content-Type: application/octet-stream; name=vhdl-mode.el Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=vhdl-mode.el ;;; vhdl-mode.el --- major mode for editing VHDL code ;; Copyright (C) 1992,93,94,95,96,97,98,99 Free Software Foundation, Inc. ;; Authors: Reto Zimmermann ;; ;; Rodney J. Whitby ;; ;; Maintainer: VHDL Mode Maintainers ;; ;; Version: 3.29 ;; Keywords: languages vhdl ;; This file is part of GNU Emacs. ;; GNU Emacs is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Commentary: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; This package provides an Emacs major mode for editing VHDL code. ;; It includes the following features: ;; - Highlighting of VHDL syntax ;; - Indentation based on versatile syntax analysis ;; - Template insertion (electrification) for most VHDL constructs ;; - Insertion of customizable VHDL file headers ;; - Insertion of user-specified models ;; - Word completion (dynamic abbreviations) ;; - Comprehensive menu ;; - File browser (using Speedbar or index/sources menu) ;; - Design hierarchy browser (using Speedbar) ;; - Source file compilation (syntax analysis) ;; - Postscript printing with fontification ;; - Lower and upper case keywords ;; - Hiding code of design units ;; - Code beautification ;; - Port translation and test bench generation ;; - VHDL'87/'93 and VHDL-AMS supported ;; - Fully customizable ;; - Works under GNU Emacs (Unix and Windows NT/95) and XEmacs ;; (GNU Emacs is preferred due to higher robustness and functionality) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Usage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; see below (comment in `vhdl-mode' function) or type `C-c C-h' in Emacs. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Emacs Versions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; supported: Emacs 20.X (Unix and Windows NT/95), XEmacs 20.X ;; tested on: Emacs 20.3, XEmacs 20.4 (marginally) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Acknowledgements ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Electrification ideas by Bob Pack ;; and Steve Grout. ;; Fontification approach suggested by Ken Wood . ;; Ideas about alignment from John Wiegley . ;; Many thanks to all the users who sent me bug reports and enhancement ;; requests. Colin Marquardt, will you never stop asking for new features :-? ;; Thanks to Dan Nicolaescu for reviewing the code and for his valuable hints. ;; Thanks to Ulf Klaperski for the indentation speedup hint. ;; Special thanks go to Wolfgang Fichtner and the crew from the Integrated ;; Systems Laboratory, Swiss Federal Institute of Technology Zurich, for ;; giving me the opportunity to develop this code. ;; This work has been funded in part by MICROSWISS, a Microelectronics Program ;; of the Swiss Government. ;;; Code: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; help function (defun vhdl-custom-set (variable value &rest functions) "Set variables as in `custom-set-default' and call FUNCTIONS afterwards." (if (fboundp 'custom-set-default) (custom-set-default variable value) (set-default variable value)) (while functions (when (fboundp (car functions)) (funcall (car functions))) (setq functions (cdr functions)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; User variables (defgroup vhdl nil "Customizations for VHDL Mode." :prefix "vhdl-" :group 'languages :version "20.4" ; comment out for XEmacs ) (defgroup vhdl-mode nil "Customizations for modes." :group 'vhdl) (defcustom vhdl-electric-mode t "*Non-nil enables electrification (automatic template generation). If nil, template generators can still be invoked through key bindings and menu. Is indicated in the modeline by `/e' after the mode name and can be toggled by `\\[vhdl-electric-mode]'." :type 'boolean :group 'vhdl-mode) (defcustom vhdl-stutter-mode t "*Non-nil enables stuttering. Is indicated in the modeline by `/s' after the mode name and can be toggled by `\\[vhdl-stutter-mode]'." :type 'boolean :group 'vhdl-mode) (defcustom vhdl-indent-tabs-mode nil "*Non-nil means indentation can insert tabs. Overrides local variable `indent-tabs-mode'." :type 'boolean :group 'vhdl-mode) (defgroup vhdl-project nil "Customizations for projects." :group 'vhdl) (defcustom vhdl-project-alist '(("example 1" "Project with individual source files" ("~/example1/vhdl/system.vhd" "~/example1/vhdl/component_*.vhd") "\ ------------------------------------------------------------------------------- -- This is a multi-line project description -- that can be used as a project dependent part of the file header. ") ("example 2" "Project where source files are located in two directories" ("$EXAMPLE2/vhdl/components/" "$EXAMPLE2/vhdl/system/") "") ("example 3" "Project where source files are located in some directory trees" ("-r ~/example3/*/vhdl/") "")) "*List of projects and their properties. Name : name of project Title : title of project (one-line string) Sources : a) source files : path + \"/\" + file name b) directory : path + \"/\" c) directory tree: \"-r \" + path + \"/\" Description: description of project (multi-line string) Project name and description are used to insert into the file header (see variable `vhdl-file-header'). Path and file name can contain wildcards `*' and `?'. Environment variables \(e.g. \"$EXAMPLE2\") are resolved. The hierarchy browser shows the hierarchy of the design units found in `Sources'. If no directories or files are specified, the current directory is shown. NOTE: Reflect the new setting in the choice list of variable `vhdl-project' by restarting Emacs." :type '(repeat (list :tag "Project" :indent 2 (string :tag "Name ") (string :tag "Title") (repeat :tag "Sources" :indent 4 (string :format "%v")) (string :tag "Description: (type `C-j' for newline)" :format "%t\n%v"))) :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-update-mode-menu)) :group 'vhdl-project) (defcustom vhdl-project "" "*Specifies the default for the current project. Select a project name from the ones defined in variable `vhdl-project-alist'. Is used to determine the project title and description to be inserted in file headers and the source files/directories to be scanned in the hierarchy browser. The current project can also be changed temporarily in the menu." :type (let ((project-alist vhdl-project-alist) choice-list) (while project-alist (setq choice-list (cons (list 'const (car (car project-alist))) choice-list)) (setq project-alist (cdr project-alist))) (append '(choice (const :tag "None" "") (const :tag "--")) (nreverse choice-list))) :group 'vhdl-project) (defgroup vhdl-compile nil "Customizations for compilation." :group 'vhdl) (defcustom vhdl-compiler-alist '( ;; Cadence Design Systems: cv -file test.vhd ;; duluth: *E,430 (test.vhd,13): identifier (POSITIV) is not declared ("Cadence" "cv -file" "" "" "./" ("duluth: \\*E,[0-9]+ (\\(.+\\),\\([0-9]+\\)):" 1 2) ("" 0)) ;; Ikos Voyager: analyze test.vhd ;; analyze sdrctl.vhd ;; E L4/C5: this library unit is inaccessible ("Ikos" "analyze" "" "" "./" ("E L\\([0-9]+\\)/C[0-9]+:" 0 1) ("^analyze +\\(.+ +\\)*\\(.+\\)$" 2)) ;; ModelSim, Model Technology: vcom test.vhd ;; ERROR: test.vhd(14): Unknown identifier: positiv ;; WARNING[2]: test.vhd(85): Possible infinite loop ("ModelSim" "vcom" "" "vmake > Makefile" "./" ("\\(ERROR\\|WARNING\\)[^:]*: \\(.+\\)(\\([0-9]+\\)):" 2 3) ("" 0)) ;; QuickHDL, Mentor Graphics: qvhcom test.vhd ;; ERROR: test.vhd(24): near "dnd": expecting: END ;; WARNING[4]: test.vhd(30): A space is required between ... ("QuickHDL" "qvhcom" "" "qhmake >! Makefile" "./" ("\\(ERROR\\|WARNING\\)[^:]*: \\(.+\\)(\\([0-9]+\\)):" 2 3) ("" 0)) ;; Synopsys, VHDL Analyzer: vhdlan test.vhd ;; **Error: vhdlan,703 test.vhd(22): OTHERS is not legal in this context. ("Synopsys" "vhdlan" "" "" "./" ("\\*\\*Error: vhdlan,[0-9]+ \\(.+\\)(\\([0-9]+\\)):" 1 2) ("" 0)) ;; Vantage: analyze -libfile vsslib.ini -src test.vhd ;; Compiling "pcu.vhd" line 1... ;; **Error: LINE 499 *** No aggregate value is valid in this context. ("Vantage" "analyze -libfile vsslib.ini -src" "" "" "./" ("\\*\\*Error: LINE \\([0-9]+\\) \\*\\*\\*" 0 1) ("^ *Compiling \"\\(.+\\)\" " 1)) ;; Viewlogic: analyze -libfile vsslib.ini -src test.vhd ;; Compiling "pcu.vhd" line 1... ;; **Error: LINE 499 *** No aggregate value is valid in this context. ("Viewlogic" "analyze -libfile vsslib.ini -src" "" "" "./" ("\\*\\*Error: LINE \\([0-9]+\\) \\*\\*\\*" 0 1) ("^ *Compiling \"\\(.+\\)\" " 1)) ) "*List of available VHDL compilers and their properties. Each list entry specifies the following items for a compiler: Compiler: Compiler Name : name used in variable `vhdl-compiler' to choose compiler Compile Command : command including options used for syntax analysis Make Command : command including options used instead of `make' (default) Generate Makefile: command to generate a Makefile (used by `make' command) From Directory : directory where compilation is run (must end with '/') Error Message: Regexp : regular expression to match error messages File Subexp Index: index of subexpression that matches the file name Line Subexp Index: index of subexpression that matches the line number File Message: Regexp : regular expression to match a file name message File Subexp Index: index of subexpression that matches the file name See also variable `vhdl-compiler-options' to add options to the compile command. Some compilers do not include the file name in the error message, but print out a file name message in advance. In this case, set \"File Subexp Index\" to 0 and fill out the \"File Message\" entries. A compiler is selected for syntax analysis (`\\[vhdl-compile]') by assigning its name to variable `vhdl-compiler'. NOTE: Reflect the new setting in the choice list of variable `vhdl-compiler' by restarting Emacs." :type '(repeat (list :tag "Compiler" :indent 2 (string :tag "Compiler Name ") (string :tag "Compile Command ") (string :tag "Make Command ") (string :tag "Generate Makefile") (string :tag "From Directory " "./") (list :tag "Error Message" :indent 4 (regexp :tag "Regexp ") (integer :tag "File Subexp Index") (integer :tag "Line Subexp Index")) (list :tag "File Message" :indent 4 (regexp :tag "Regexp ") (integer :tag "File Subexp Index")))) :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-update-mode-menu)) :group 'vhdl-compile) (defcustom vhdl-compiler "ModelSim" "*Specifies the VHDL compiler to be used for syntax analysis. Select a compiler name from the ones defined in variable `vhdl-compiler-alist'." :type (let ((compiler-alist vhdl-compiler-alist) choice-list) (while compiler-alist (setq choice-list (cons (list 'const (car (car compiler-alist))) choice-list)) (setq compiler-alist (cdr compiler-alist))) (append '(choice) (nreverse choice-list))) :group 'vhdl-compile) (defcustom vhdl-compiler-options "" "*Options to be added to the compile command." :type 'string :group 'vhdl-compile) (defgroup vhdl-style nil "Customizations for code styles." :group 'vhdl) (defcustom vhdl-standard '(87 nil) "*VHDL standards used. Basic standard: VHDL'87 : IEEE Std 1076-1987 VHDL'93 : IEEE Std 1076-1993 Additional standards: VHDL-AMS : IEEE Std 1076.1 (analog-mixed-signal) Math Packages: IEEE Std 1076.2 (`math_real', `math_complex') NOTE: Activate the new setting in a VHDL buffer using the menu entry \"Activate New Customizations\"." :type '(list (choice :tag "Basic standard" (const :tag "VHDL'87" 87) (const :tag "VHDL'93" 93)) (set :tag "Additional standards" :indent 2 (const :tag "VHDL-AMS" ams) (const :tag "Math Packages" math))) :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-template-map-init 'vhdl-mode-abbrev-table-init 'vhdl-template-construct-alist-init 'vhdl-template-package-alist-init 'vhdl-update-mode-menu 'vhdl-words-init 'vhdl-font-lock-init)) :group 'vhdl-style) (defcustom vhdl-basic-offset 2 "*Amount of basic offset used for indentation. This value is used by + and - symbols in `vhdl-offsets-alist'." :type 'integer :group 'vhdl-style) (defcustom vhdl-upper-case-keywords nil "*Non-nil means convert keywords to upper case. This is done when typed or expanded or by the fix case functions." :type 'boolean :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-abbrev-list-init)) :group 'vhdl-style) (defcustom vhdl-upper-case-types nil "*Non-nil means convert standardized types to upper case. This is done when expanded or by the fix case functions." :type 'boolean :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-abbrev-list-init)) :group 'vhdl-style) (defcustom vhdl-upper-case-attributes nil "*Non-nil means convert standardized attributes to upper case. This is done when expanded or by the fix case functions." :type 'boolean :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-abbrev-list-init)) :group 'vhdl-style) (defcustom vhdl-upper-case-enum-values nil "*Non-nil means convert standardized enumeration values to upper case. This is done when expanded or by the fix case functions." :type 'boolean :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-abbrev-list-init)) :group 'vhdl-style) (defcustom vhdl-upper-case-constants t "*Non-nil means convert standardized constants to upper case. This is done when expanded." :type 'boolean :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-abbrev-list-init)) :group 'vhdl-style) (defgroup vhdl-electric nil "Customizations for electrification." :group 'vhdl) (defcustom vhdl-electric-keywords '(vhdl user) "*Type of keywords for which electrification is enabled. VHDL keywords: invoke built-in templates User keywords: invoke user models (see variable `vhdl-model-alist')" :type '(set (const :tag "VHDL keywords" vhdl) (const :tag "User keywords" user)) :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-mode-abbrev-table-init)) :group 'vhdl-electric) (defcustom vhdl-optional-labels 'process "*Constructs for which labels are to be queried. Template generators prompt for optional labels for: None : no constructs Processes only: processes only (also procedurals in VHDL-AMS) All constructs: all constructs with optional labels and keyword END" :type '(choice (const :tag "None" none) (const :tag "Processes only" process) (const :tag "All constructs" all)) :group 'vhdl-electric) (defcustom vhdl-insert-empty-lines 'unit "*Specifies whether to insert empty lines in some templates. This improves readability of code. Empty lines are inserted in: None : no constructs Design units only: entities, architectures, configurations, packages only All constructs : also all constructs with BEGIN...END parts Replaces variable `vhdl-additional-empty-lines'." :type '(choice (const :tag "None" none) (const :tag "Design units only" unit) (const :tag "All constructs" all)) :group 'vhdl-electric) (defcustom vhdl-argument-list-indent nil "*Non-nil means indent argument lists relative to opening parenthesis. That is, argument, association, and port lists start on the same line as the opening parenthesis and subsequent lines are indented accordingly. Otherwise, lists start on a new line and are indented as normal code." :type 'boolean :group 'vhdl-electric) (defcustom vhdl-association-list-with-formals t "*Non-nil means write association lists with formal parameters. In templates, you are prompted for formal and actual parameters. If nil, only a list of actual parameters is entered." :type 'boolean :group 'vhdl-electric) (defcustom vhdl-conditions-in-parenthesis nil "*Non-nil means place parenthesis around condition expressions." :type 'boolean :group 'vhdl-electric) (defcustom vhdl-zero-string "'0'" "*String to use for a logic zero." :type 'string :group 'vhdl-electric) (defcustom vhdl-one-string "'1'" "*String to use for a logic one." :type 'string :group 'vhdl-electric) (defgroup vhdl-header nil "Customizations for file header." :group 'vhdl-electric) (defcustom vhdl-file-header "\ ------------------------------------------------------------------------------- -- Title : -- Project : <project> ------------------------------------------------------------------------------- -- File : <filename> -- Author : <author> -- Company : <company> -- Last update: <date> -- Platform : <platform> <projectdesc>------------------------------------------------------------------------------- -- Description: <cursor> ------------------------------------------------------------------------------- -- Revisions : -- Date Version Author Description -- <date> 1.0 <login>\tCreated ------------------------------------------------------------------------------- " "*String or file to insert as file header. If the string specifies an existing file name, the contents of the file is inserted, otherwise the string itself is inserted as file header. Type `C-j' for newlines. If the header contains RCS keywords, they may be written as <RCS>Keyword<RCS> if the header needs to be version controlled. The following keywords for template generation are supported: <filename> : replaced by the name of the buffer <author> : replaced by the user name and email address (customize `mail-host-address' or `user-mail-address' if required) <login> : replaced by user login name <company> : replaced by contents of variable `vhdl-company-name' <date> : replaced by the current date <project> : replaced by title of current project (`vhdl-project') <projectdesc>: replaced by description of current project (`vhdl-project') <platform> : replaced by contents of variable `vhdl-platform-spec' <... string> : replaced by a queried string (... is the prompt word) <cursor> : final cursor position The (multi-line) project description <projectdesc> can be used as a project dependent part of the file header and can also contain the above keywords." :type 'string :group 'vhdl-header) (defcustom vhdl-file-footer "" "*String or file to insert as file footer. If the string specifies an existing file name, the contents of the file is inserted, otherwise the string itself is inserted as file footer (i.e. at the end of the file). Type `C-j' for newlines." :type 'string :group 'vhdl-header) (defcustom vhdl-company-name "" "*Name of company to insert in file header." :type 'string :group 'vhdl-header) (defcustom vhdl-platform-spec "" "*Specification of VHDL platform to insert in file header. The platform specification should contain names and versions of the simulation and synthesis tools used." :type 'string :group 'vhdl-header) (defcustom vhdl-date-format "%Y/%m/%d" "*Specifies the date format to use in the header. This string is passed as argument to the command `format-time-string'. For more information on format strings, see the documentation for the `format-time-string' command (C-h f `format-time-string')." :type 'string :group 'vhdl-header) (defcustom vhdl-modify-date-prefix-string "-- Last update: " "*Prefix string of modification date in VHDL file header. If actualization of the modification date is called (menu, `\\[vhdl-template-modify]'), this string is searched and the rest of the line replaced by the current date." :type 'string :group 'vhdl-header) (defcustom vhdl-modify-date-on-saving t "*Non-nil means update the modification date when the buffer is saved. Calls function `\\[vhdl-template-modify]'). NOTE: Activate the new setting in a VHDL buffer using the menu entry \"Activate New Customizations\"" :type 'boolean :group 'vhdl-header) (defgroup vhdl-sequential-process nil "Customizations for sequential processes." :group 'vhdl-electric) (defcustom vhdl-reset-kind 'async "*Specifies which kind of reset to use in sequential processes." :type '(choice (const :tag "None" none) (const :tag "Synchronous" sync) (const :tag "Asynchronous" async)) :group 'vhdl-sequential-process) (defcustom vhdl-reset-active-high nil "*Non-nil means reset in sequential processes is active high. Nil means active low." :type 'boolean :group 'vhdl-sequential-process) (defcustom vhdl-clock-rising-edge t "*Non-nil means rising edge of clock triggers sequential processes. Nil means falling edge." :type 'boolean :group 'vhdl-sequential-process) (defcustom vhdl-clock-edge-condition 'standard "*Syntax of the clock edge condition. Standard: \"clk'event and clk = '1'\" Function: \"rising_edge(clk)\"" :type '(choice (const :tag "Standard" standard) (const :tag "Function" function)) :group 'vhdl-sequential-process) (defcustom vhdl-clock-name "" "*Name of clock signal to use in templates." :type 'string :group 'vhdl-sequential-process) (defcustom vhdl-reset-name "" "*Name of reset signal to use in templates." :type 'string :group 'vhdl-sequential-process) (defgroup vhdl-model nil "Customizations for user models." :group 'vhdl) (defcustom vhdl-model-alist '(("example model" "<label> : process (<clock>, <reset>) begin -- process <label> if <reset> = '0' then -- asynchronous reset (active low) <cursor> elsif <clock>'event and <clock> = '1' then -- rising clock edge if <enable> = '1' then -- synchronous load end if; end if; end process <label>;" "e" "")) "*List of user models. VHDL models (templates) can be specified by the user in this list. They can be invoked from the menu, through key bindings (`C-c C-m ...'), or by keyword electrification (i.e. overriding existing or creating new keywords, see variable `vhdl-electric-keywords'). Name : name of model (string of words and spaces) String : string or name of file to be inserted as model (newline: `C-j') Key Binding: key binding to invoke model, added to prefix `C-c C-m' (must be in double-quotes, examples: \"i\", \"\\C-p\", \"\\M-s\") Keyword : keyword to invoke model The models can contain prompts to be queried. A prompt is of the form \"<...>\". A prompt that appears several times is queried once and replaced throughout the model. Special prompts are: <clock> : name specified in `vhdl-clock-name' (if not empty) <reset> : name specified in `vhdl-reset-name' (if not empty) <cursor>: final cursor position If the string specifies an existing file name, the contents of the file is inserted, otherwise the string itself is inserted. The code within the models should be correctly indented. Type `C-j' for newlines. NOTE: Activate the new setting in a VHDL buffer using the menu entry \"Activate New Customizations\"" :type '(repeat (list :tag "Model" :indent 2 (string :tag "Name ") (string :tag "String : (type `C-j' for newline)" :format "%t\n%v") (sexp :tag "Key Binding" x) (string :tag "Keyword "))) :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-model-map-init 'vhdl-model-defun 'vhdl-mode-abbrev-table-init 'vhdl-update-mode-menu)) :group 'vhdl-model) (defgroup vhdl-port nil "Customizations for port transformation functions." :group 'vhdl) (defcustom vhdl-include-port-comments nil "*Non-nil means include port comments when a port is pasted." :type 'boolean :group 'vhdl-port) (defcustom vhdl-include-direction-comments nil "*Non-nil means include signal direction in instantiations as comments." :type 'boolean :group 'vhdl-port) (defconst vhdl-name-doc-string " FROM REGEXP is a regular expression matching the formal port name: `.*' matches the entire name `\\(...\\)' matches a substring TO STRING specifies the string to be inserted as actual port name: `\\&' means substitute original matched text `\\N' means substitute what matched the Nth `\\(...\\)' Examples: `.*' `\\&' leaves name as it is `.*' `\\&_i' attaches `_i' to original name `\\(.*\\)_[io]$' `\\1' strips off `_i' or `_o' from original name `.*' `' leaves name empty") (defcustom vhdl-actual-port-name '(".*" . "\\&_i") (concat "*Specifies how actual port names are obtained from formal port names. In a component instantiation, an actual port name can be obtained by modifying the formal port name (e.g. attaching or stripping off a substring)." vhdl-name-doc-string) :type '(cons (regexp :tag "From Regexp") (string :tag "To String ")) :group 'vhdl-port) (defcustom vhdl-instance-name '(".*" . "") (concat "*Specifies how an instance name is obtained. The instance name can be obtained by modifying the name of the component to be instantiated (e.g. attaching or stripping off a substring). If TO STRING is empty, the instance name is queried." vhdl-name-doc-string) :type '(cons (regexp :tag "From Regexp") (string :tag "To String ")) :group 'vhdl-port) (defcustom vhdl-testbench-entity-name '(".*" . "\\&_tb") (concat "*Specifies how the test bench entity name is obtained. The entity name of a test bench can be obtained by modifying the name of the component to be tested (e.g. attaching or stripping off a substring)." vhdl-name-doc-string) :type '(cons (regexp :tag "From Regexp") (string :tag "To String ")) :group 'vhdl-port) (defcustom vhdl-testbench-architecture-name '(".*" . "") (concat "*Specifies how the test bench architecture name is obtained. The test bench architecture name can be obtained by modifying the name of the component to be tested (e.g. attaching or stripping off a substring). If TO STRING is empty, the architecture name is queried." vhdl-name-doc-string) :type '(cons (regexp :tag "From Regexp") (string :tag "To String ")) :group 'vhdl-port) (defcustom vhdl-testbench-dut-name '(".*" . "DUT") (concat "*Specifies how a DUT instance name is obtained. The design-under-test instance name (i.e. the component instantiated in the test bench) can be obtained by modifying the component name (e.g. attaching or stripping off a substring)." vhdl-name-doc-string) :type '(cons (regexp :tag "From Regexp") (string :tag "To String ")) :group 'vhdl-port) (defcustom vhdl-testbench-entity-header "" "*String or file to be inserted as test bench entity header. If the string specifies an existing file name, the contents of the file is inserted, otherwise the string itself is inserted at the beginning of the test bench entity template. Type `C-j' for newlines." :type 'string :group 'vhdl-port) (defcustom vhdl-testbench-architecture-header "" "*String or file to be inserted as test bench architecture header. If the string specifies an existing file name, the contents of the file is inserted, otherwise the string itself is inserted at the beginning of the test bench architecture template, if a separate file is created for the architecture. Type `C-j' for newlines." :type 'string :group 'vhdl-port) (defcustom vhdl-testbench-declarations "" "*String or file to be inserted in the test bench declarative part. If the string specifies an existing file name, the contents of the file is inserted, otherwise the string itself is inserted in the test bench architecture before the BEGIN keyword. Type `C-j' for newlines." :type 'string :group 'vhdl-port) (defcustom vhdl-testbench-statements "" "*String or file to be inserted in the test bench statement part. If the string specifies an existing file name, the contents of the file is inserted, otherwise the string itself is inserted in the test bench architecture before the END keyword. Type `C-j' for newlines." :type 'string :group 'vhdl-port) (defcustom vhdl-testbench-initialize-signals nil "*Non-nil means initialize signals with `0' when declared in test bench." :type 'boolean :group 'vhdl-port) (defcustom vhdl-testbench-create-files 'single "*Specifies whether new files should be created for the test bench. Test bench entity and architecture are inserted: None : in current buffer Single file : in new single file Separate files: in two separate files Note that the files have the same name as the contained design unit." :type '(choice (const :tag "None" none) (const :tag "Single file" single) (const :tag "Separate files" separate)) :group 'vhdl-port) (defgroup vhdl-comment nil "Customizations for comments." :group 'vhdl) (defcustom vhdl-self-insert-comments t "*Non-nil means various templates automatically insert help comments." :type 'boolean :group 'vhdl-comment) (defcustom vhdl-prompt-for-comments t "*Non-nil means various templates prompt for user definable comments." :type 'boolean :group 'vhdl-comment) (defcustom vhdl-inline-comment-column 40 "*Column to indent inline comments to. Overrides local variable `comment-column'. NOTE: Activate the new setting in a VHDL buffer using the menu entry \"Activate New Customizations\"" :type 'integer :group 'vhdl-comment) (defcustom vhdl-end-comment-column 79 "*End of comment column. Comments that exceed this column number are wrapped. NOTE: Activate the new setting in a VHDL buffer using the menu entry \"Activate New Customizations\"" :type 'integer :group 'vhdl-comment) (defvar end-comment-column) (defgroup vhdl-align nil "Customizations for alignment." :group 'vhdl) (defcustom vhdl-auto-align t "*Non-nil means align some templates automatically after generation." :type 'boolean :group 'vhdl-align) (defcustom vhdl-align-groups t "*Non-nil means align groups of code lines separately. A group of code lines is a region of lines with no empty lines inbetween." :type 'boolean :group 'vhdl-align) (defgroup vhdl-highlight nil "Customizations for highlighting." :group 'vhdl) (defcustom vhdl-highlight-keywords t "*Non-nil means highlight VHDL keywords and other standardized words. The following faces are used: `font-lock-keyword-face' : keywords `font-lock-type-face' : standardized types `vhdl-font-lock-attribute-face' : standardized attributes `vhdl-font-lock-enumvalue-face' : standardized enumeration values `vhdl-font-lock-function-face' : standardized function and package names NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu entry \"Fontify Buffer\"). XEmacs: turn off and on font locking." :type 'boolean :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-font-lock-init)) :group 'vhdl-highlight) (defcustom vhdl-highlight-names t "*Non-nil means highlight declaration names and construct labels. The following faces are used: `font-lock-function-name-face' : names in declarations of units, subprograms, components, as well as labels of VHDL constructs `font-lock-type-face' : names in type/nature declarations `vhdl-font-lock-attribute-face' : names in attribute declarations `font-lock-variable-name-face' : names in declarations of signals, variables, constants, subprogram parameters, generics, and ports NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu entry \"Fontify Buffer\"). XEmacs: turn off and on font locking." :type 'boolean :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-font-lock-init)) :group 'vhdl-highlight) (defcustom vhdl-highlight-special-words nil "*Non-nil means highlight words with special syntax. The words with syntax and color specified in variable `vhdl-special-syntax-alist' are highlighted accordingly. Can be used for visual support of naming conventions. NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu entry \"Fontify Buffer\"). XEmacs: turn off and on font locking." :type 'boolean :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-font-lock-init)) :group 'vhdl-highlight) (defcustom vhdl-highlight-forbidden-words nil "*Non-nil means highlight forbidden words. The reserved words specified in variable `vhdl-forbidden-words' or having the syntax specified in variable `vhdl-forbidden-syntax' are highlighted in a warning color (face `vhdl-font-lock-reserved-words-face') to indicate not to use them. NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu entry \"Fontify Buffer\"). XEmacs: turn off and on font locking." :type 'boolean :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-words-init 'vhdl-font-lock-init)) :group 'vhdl-highlight) (defcustom vhdl-highlight-verilog-keywords nil "*Non-nil means highlight Verilog keywords as reserved words. Verilog keywords are highlighted in a warning color (face `vhdl-font-lock-reserved-words-face') to indicate not to use them. NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu entry \"Fontify Buffer\"). XEmacs: turn off and on font locking." :type 'boolean :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-words-init 'vhdl-font-lock-init)) :group 'vhdl-highlight) (defcustom vhdl-highlight-translate-off nil "*Non-nil means background-highlight code excluded from translation. That is, all code between \"-- pragma translate_off\" and \"-- pragma translate_on\" is highlighted using a different background color \(face `vhdl-font-lock-translate-off-face'). Note: this might slow down on-the-fly fontification (and thus editing). NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu entry \"Fontify Buffer\"). XEmacs: turn off and on font locking." :type 'boolean :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-font-lock-init)) :group 'vhdl-highlight) (defcustom vhdl-highlight-case-sensitive nil "*Non-nil means consider case for highlighting. Possible trade-off: non-nil also upper-case VHDL words are highlighted, but case of words with special syntax is not considered nil only lower-case VHDL words are highlighted, but case of words with special syntax is considered Overrides local variable `font-lock-keywords-case-fold-search'. NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu entry \"Fontify Buffer\"). XEmacs: turn off and on font locking." :type 'boolean :group 'vhdl-highlight) (defcustom vhdl-special-syntax-alist nil "*List of special syntax to be highlighted. If variable `vhdl-highlight-special-words' is non-nil, words with the specified syntax (as regular expression) are highlighted in the corresponding color. Name : string of words and spaces Regexp : regular expression describing word syntax (e.g. \"\\\w+_c\" matches word with suffix \"_c\") Color (light): foreground color for light background (matching color examples: Gold3, Grey50, LimeGreen, Tomato, LightSeaGreen, DodgerBlue, Gold, PaleVioletRed) Color (dark) : foreground color for dark background (matching color examples: BurlyWood1, Grey80, Green, Coral, AquaMarine2, LightSkyBlue1, Yellow, PaleVioletRed1) Can be used for visual support of naming conventions, such as highlighting different kinds of signals (e.g. \"Clk_c\", \"Rst_r\") or objects (e.g. \"Signal_s\", \"Variable_v\", \"Constant_c\") by distinguishing them using name suffices. For each entry, a new face is generated with the specified colors and name \"vhdl-font-lock-\" + name + \"-face\". NOTE: Activate a changed regexp in a VHDL buffer by re-fontifying it (menu entry \"Fontify Buffer\"). XEmacs: turn off and on font locking. All other changes require restarting Emacs." :type '(repeat (list :tag "Face" :indent 2 (string :tag "Name ") (regexp :tag "Regexp " "\\w+_") (string :tag "Color (light)") (string :tag "Color (dark) "))) :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-font-lock-init)) :group 'vhdl-highlight) (defcustom vhdl-forbidden-words '() "*List of forbidden words to be highlighted. If variable `vhdl-highlight-forbidden-words' is non-nil, these reserved words are highlighted in a warning color to indicate not to use them. NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu entry \"Fontify Buffer\"). XEmacs: turn off and on font locking." :type '(repeat (string :format "%v")) :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-words-init 'vhdl-font-lock-init)) :group 'vhdl-highlight) (defcustom vhdl-forbidden-syntax "" "*Syntax of forbidden words to be highlighted. If variable `vhdl-highlight-forbidden-words' is non-nil, words with this syntax are highlighted in a warning color to indicate not to use them. Can be used to highlight too long identifiers (e.g. \"\\w\\w\\w\\w\\w\\w\\w\\w\\w\\w+\" highlights identifiers with 10 or more characters). NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu entry \"Fontify Buffer\"). XEmacs: turn off and on font locking." :type 'regexp :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-words-init 'vhdl-font-lock-init)) :group 'vhdl-highlight) (defgroup vhdl-menu nil "Customizations for speedbar and menues." :group 'vhdl) (defcustom vhdl-speedbar nil "*Non-nil means open the speedbar automatically at startup. Alternatively, the speedbar can be opened from the VHDL menu." :type 'boolean :group 'vhdl-menu) (defcustom vhdl-speedbar-show-hierarchy nil "*Non-nil means open the speedbar as hierarchy browser at startup. Otherwise, the speedbar is opened as normal file browser." :type 'boolean :group 'vhdl-menu) (defcustom vhdl-speedbar-hierarchy-indent 1 "*Amount of indentation in hierarchy display of subcomponent." :type 'integer :group 'vhdl-menu) (defcustom vhdl-index-menu nil "*Non-nil means add an index menu for a source file when loading. Alternatively, the speedbar can be used. Note that the index menu scans a file when it is opened, while speedbar only scans the file upon request. Does not work under XEmacs." :type 'boolean :group 'vhdl-menu) (defcustom vhdl-source-file-menu nil "*Non-nil means add a menu of all source files in current directory. Alternatively, the speedbar can be used." :type 'boolean :group 'vhdl-menu) (defcustom vhdl-hideshow-menu nil "*Non-nil means add hideshow menu and functionality. Hideshow allows hiding code of VHDL design units. Does not work under XEmacs. NOTE: Activate the new setting in a VHDL buffer using the menu entry \"Activate New Customizations\"" :type 'boolean :group 'vhdl-menu) (defcustom vhdl-hide-all-init nil "*Non-nil means hide all design units initially after a file is loaded." :type 'boolean :group 'vhdl-menu) (defgroup vhdl-print nil "Customizations for printing." :group 'vhdl) (defcustom vhdl-print-two-column t "*Non-nil means print code in two columns and landscape format. NOTE: Activate the new setting by restarting Emacs. Overrides `ps-print' settings locally." :type 'boolean :group 'vhdl-print) (defcustom vhdl-print-customize-faces t "*Non-nil means use an optimized set of faces for postscript printing. NOTE: Activate the new setting by restarting Emacs. Overrides `ps-print' settings locally." :type 'boolean :group 'vhdl-print) (defgroup vhdl-misc nil "Miscellaneous customizations." :group 'vhdl) (defcustom vhdl-intelligent-tab t "*Non-nil means `TAB' does indentation, word completion and tab insertion. That is, if preceeding character is part of a word then complete word, else if not at beginning of line then insert tab, else if last command was a `TAB' or `RET' then dedent one step, else indent current line (i.e. `TAB' is bound to `vhdl-electric-tab'). If nil, TAB always indents current line (i.e. `TAB' is bound to `vhdl-indent-line'). NOTE: Activate the new setting in a VHDL buffer using the menu entry \"Activate New Customizations\"" :type 'boolean :group 'vhdl-misc) (defcustom vhdl-word-completion-case-sensitive nil "*Non-nil means word completion using `TAB' is case sensitive. That is, `TAB' completes words that start with the same letters and case. Otherwise, case is ignored." :type 'boolean :group 'vhdl-misc) (defcustom vhdl-word-completion-in-minibuffer t "*Non-nil enables word completion in minibuffer (for template prompts). NOTE: Activate the new setting by restarting Emacs." :type 'boolean :group 'vhdl-misc) (defcustom vhdl-underscore-is-part-of-word nil "*Non-nil means consider the underscore character `_' as part of word. An identifier containing underscores is then treated as a single word in select and move operations. All parts of an identifier separated by underscore are treated as single words otherwise. NOTE: Activate the new setting in a VHDL buffer using the menu entry \"Activate New Customizations\"" :type 'boolean :set (lambda (variable value) (vhdl-custom-set variable value 'vhdl-mode-syntax-table-init)) :group 'vhdl-misc) (defgroup vhdl-related nil "Related general customizations." :group 'vhdl) ;; add related general customizations (custom-add-to-group 'vhdl-related 'line-number-mode 'custom-variable) (if (string-match "XEmacs" emacs-version) (custom-add-to-group 'vhdl-related 'paren-mode 'custom-variable) (custom-add-to-group 'vhdl-related 'paren-showing 'custom-group)) (unless (string-match "XEmacs" emacs-version) (custom-add-to-group 'vhdl-related 'transient-mark-mode 'custom-variable)) (custom-add-to-group 'vhdl-related 'ps-print 'custom-group) (custom-add-to-group 'vhdl-related 'mail-host-address 'custom-variable) (custom-add-to-group 'vhdl-related 'user-mail-address 'custom-variable) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Internal variables (defconst vhdl-version "3.29" "VHDL Mode version number.") (defvar vhdl-progress-interval 1 "*Interval used to update progress status during long operations. If a number, percentage complete gets updated after each interval of that many seconds. To inhibit all messages, set this variable to nil.") (defvar vhdl-inhibit-startup-warnings-p nil "*If non-nil, inhibits start up compatibility warnings.") (defvar vhdl-strict-syntax-p nil "*If non-nil, all syntactic symbols must be found in `vhdl-offsets-alist'. If the syntactic symbol for a particular line does not match a symbol in the offsets alist, an error is generated, otherwise no error is reported and the syntactic symbol is ignored.") (defvar vhdl-echo-syntactic-information-p nil "*If non-nil, syntactic info is echoed when the line is indented.") (defconst vhdl-offsets-alist-default '((string . -1000) (block-open . 0) (block-close . 0) (statement . 0) (statement-cont . vhdl-lineup-statement-cont) (statement-block-intro . +) (statement-case-intro . +) (case-alternative . +) (comment . vhdl-lineup-comment) (arglist-intro . +) (arglist-cont . 0) (arglist-cont-nonempty . vhdl-lineup-arglist) (arglist-close . vhdl-lineup-arglist) (entity . 0) (configuration . 0) (package . 0) (architecture . 0) (package-body . 0) ) "Default settings for offsets of syntactic elements. Do not change this constant! See the variable `vhdl-offsets-alist' for more information.") (defvar vhdl-offsets-alist (copy-alist vhdl-offsets-alist-default) "*Association list of syntactic element symbols and indentation offsets. As described below, each cons cell in this list has the form: (SYNTACTIC-SYMBOL . OFFSET) When a line is indented, `vhdl-mode' first determines the syntactic context of the line by generating a list of symbols called syntactic elements. This list can contain more than one syntactic element and the global variable `vhdl-syntactic-context' contains the context list for the line being indented. Each element in this list is actually a cons cell of the syntactic symbol and a buffer position. This buffer position is call the relative indent point for the line. Some syntactic symbols may not have a relative indent point associated with them. After the syntactic context list for a line is generated, `vhdl-mode' calculates the absolute indentation for the line by looking at each syntactic element in the list. First, it compares the syntactic element against the SYNTACTIC-SYMBOL's in `vhdl-offsets-alist'. When it finds a match, it adds the OFFSET to the column of the relative indent point. The sum of this calculation for each element in the syntactic list is the absolute offset for line being indented. If the syntactic element does not match any in the `vhdl-offsets-alist', an error is generated if `vhdl-strict-syntax-p' is non-nil, otherwise the element is ignored. Actually, OFFSET can be an integer, a function, a variable, or one of the following symbols: `+', `-', `++', or `--'. These latter designate positive or negative multiples of `vhdl-basic-offset', respectively: *1, *-1, *2, and *-2. If OFFSET is a function, it is called with a single argument containing the cons of the syntactic element symbol and the relative indent point. The function should return an integer offset. Here is the current list of valid syntactic element symbols: string -- inside multi-line string block-open -- statement block open block-close -- statement block close statement -- a VHDL statement statement-cont -- a continuation of a VHDL statement statement-block-intro -- the first line in a new statement block statement-case-intro -- the first line in a case alternative block case-alternative -- a case statement alternative clause comment -- a line containing only a comment arglist-intro -- the first line in an argument list arglist-cont -- subsequent argument list lines when no arguments follow on the same line as the the arglist opening paren arglist-cont-nonempty -- subsequent argument list lines when at least one argument follows on the same line as the arglist opening paren arglist-close -- the solo close paren of an argument list entity -- inside an entity declaration configuration -- inside a configuration declaration package -- inside a package declaration architecture -- inside an architecture body package-body -- inside a package body") (defvar vhdl-comment-only-line-offset 0 "*Extra offset for line which contains only the start of a comment. Can contain an integer or a cons cell of the form: (NON-ANCHORED-OFFSET . ANCHORED-OFFSET) Where NON-ANCHORED-OFFSET is the amount of offset given to non-column-zero anchored comment-only lines, and ANCHORED-OFFSET is the amount of offset to give column-zero anchored comment-only lines. Just an integer as value is equivalent to (<val> . 0)") (defvar vhdl-special-indent-hook nil "*Hook for user defined special indentation adjustments. This hook gets called after a line is indented by the mode.") (defvar vhdl-style-alist '(("IEEE" (vhdl-basic-offset . 4) (vhdl-offsets-alist . ()) ) ) "Styles of Indentation. Elements of this alist are of the form: (STYLE-STRING (VARIABLE . VALUE) [(VARIABLE . VALUE) ...]) where STYLE-STRING is a short descriptive string used to select a style, VARIABLE is any `vhdl-mode' variable, and VALUE is the intended value for that variable when using the selected style. There is one special case when VARIABLE is `vhdl-offsets-alist'. In this case, the VALUE is a list containing elements of the form: (SYNTACTIC-SYMBOL . VALUE) as described in `vhdl-offsets-alist'. These are passed directly to `vhdl-set-offset' so there is no need to set every syntactic symbol in your style, only those that are different from the default.") ;; dynamically append the default value of most variables (or (assoc "Default" vhdl-style-alist) (let* ((varlist '(vhdl-inhibit-startup-warnings-p vhdl-strict-syntax-p vhdl-echo-syntactic-information-p vhdl-basic-offset vhdl-offsets-alist vhdl-comment-only-line-offset)) (default (cons "Default" (mapcar (function (lambda (var) (cons var (symbol-value var)))) varlist)))) (setq vhdl-style-alist (cons default vhdl-style-alist)))) (defvar vhdl-mode-hook nil "*Hook called by `vhdl-mode'.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Compatibility (defvar vhdl-startup-warnings nil "Warnings to tell the user during start up.") (defun vhdl-print-warnings () "Print out messages in variable `vhdl-startup-warnings'." (let ((warnings vhdl-startup-warnings)) (while warnings (message (concat "WARNING: " (car warnings))) (setq warnings (cdr warnings)))) (when (> (length vhdl-startup-warnings) 1) (message "WARNING: See warning messages in *Messages* buffer."))) (defun vhdl-add-warning (string) "Add STRING to warning list `vhdl-startup-warnings'." (setq vhdl-startup-warnings (cons string vhdl-startup-warnings))) ;; Perform compatibility checks. (when (not (stringp vhdl-compiler)) ; changed format of `vhdl-compiler' (setq vhdl-compiler "ModelSim") (vhdl-add-warning "Variable `vhdl-compiler' has changed format; customize again")) (when (not (listp vhdl-standard)) ; changed format of `vhdl-standard' (setq vhdl-standard '(87 nil)) (vhdl-add-warning "Variable `vhdl-standard' has changed format; customize again")) (when (= (length (car vhdl-model-alist)) 3) (let ((old-alist vhdl-model-alist) ; changed format of `vhdl-model-alist' new-alist) (while old-alist (setq new-alist (cons (append (car old-alist) '("")) new-alist)) (setq old-alist (cdr old-alist))) (setq vhdl-model-alist (nreverse new-alist)))) (when (= (length (car vhdl-project-alist)) 3) (let ((old-alist vhdl-project-alist) ; changed format of `vhdl-project-alist' new-alist) (while old-alist (setq new-alist (cons (append (car old-alist) '("")) new-alist)) (setq old-alist (cdr old-alist))) (setq vhdl-project-alist (nreverse new-alist)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Help functions (defsubst vhdl-standard-p (standard) "Check if STANDARD is specified as used standard." (or (eq standard (car vhdl-standard)) (memq standard (cadr vhdl-standard)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Required packages (require 'assoc) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Emacs variant handling ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; active regions (defun vhdl-keep-region-active () "Do whatever is necessary to keep the region active in XEmacs. Ignore byte-compiler warnings you might see." (and (boundp 'zmacs-region-stays) (setq zmacs-region-stays t))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; XEmacs hacks (unless (fboundp 'wildcard-to-regexp) (defun wildcard-to-regexp (wildcard) "Simplified version of `wildcard-to-regexp' from Emacs' `files.el'." (let* ((i (string-match "[*?]" wildcard)) (result (substring wildcard 0 i)) (len (length wildcard))) (when i (while (< i len) (let ((ch (aref wildcard i))) (setq result (concat result (cond ((eq ch ?*) "[^\000]*") ((eq ch ??) "[^\000]") (t (char-to-string ch))))) (setq i (1+ i))))) (concat "\\`" result "\\'")))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Bindings ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Key bindings (defvar vhdl-template-map () "Keymap for VHDL templates.") (defun vhdl-template-map-init () "Initialize `vhdl-template-map'." (setq vhdl-template-map (make-sparse-keymap)) ;; key bindings for VHDL templates (define-key vhdl-template-map "al" 'vhdl-template-alias) (define-key vhdl-template-map "ar" 'vhdl-template-architecture) (define-key vhdl-template-map "at" 'vhdl-template-assert) (define-key vhdl-template-map "ad" 'vhdl-template-attribute-decl) (define-key vhdl-template-map "as" 'vhdl-template-attribute-spec) (define-key vhdl-template-map "bl" 'vhdl-template-block) (define-key vhdl-template-map "ca" 'vhdl-template-case-is) (define-key vhdl-template-map "cd" 'vhdl-template-component-decl) (define-key vhdl-template-map "ci" 'vhdl-template-component-inst) (define-key vhdl-template-map "cs" 'vhdl-template-conditional-signal-asst) (define-key vhdl-template-map "Cb" 'vhdl-template-block-configuration) (define-key vhdl-template-map "Cc" 'vhdl-template-component-conf) (define-key vhdl-template-map "Cd" 'vhdl-template-configuration-decl) (define-key vhdl-template-map "Cs" 'vhdl-template-configuration-spec) (define-key vhdl-template-map "co" 'vhdl-template-constant) (define-key vhdl-template-map "di" 'vhdl-template-disconnect) (define-key vhdl-template-map "el" 'vhdl-template-else) (define-key vhdl-template-map "ei" 'vhdl-template-elsif) (define-key vhdl-template-map "en" 'vhdl-template-entity) (define-key vhdl-template-map "ex" 'vhdl-template-exit) (define-key vhdl-template-map "fi" 'vhdl-template-file) (define-key vhdl-template-map "fg" 'vhdl-template-for-generate) (define-key vhdl-template-map "fl" 'vhdl-template-for-loop) (define-key vhdl-template-map "\C-f" 'vhdl-template-footer) (define-key vhdl-template-map "fb" 'vhdl-template-function-body) (define-key vhdl-template-map "fd" 'vhdl-template-function-decl) (define-key vhdl-template-map "ge" 'vhdl-template-generic) (define-key vhdl-template-map "gd" 'vhdl-template-group-decl) (define-key vhdl-template-map "gt" 'vhdl-template-group-template) (define-key vhdl-template-map "\C-h" 'vhdl-template-header) (define-key vhdl-template-map "ig" 'vhdl-template-if-generate) (define-key vhdl-template-map "it" 'vhdl-template-if-then) (define-key vhdl-template-map "li" 'vhdl-template-library) (define-key vhdl-template-map "lo" 'vhdl-template-bare-loop) (define-key vhdl-template-map "\C-m" 'vhdl-template-modify) (define-key vhdl-template-map "\C-t" 'vhdl-template-insert-date) (define-key vhdl-template-map "ma" 'vhdl-template-map) (define-key vhdl-template-map "ne" 'vhdl-template-next) (define-key vhdl-template-map "ot" 'vhdl-template-others) (define-key vhdl-template-map "Pd" 'vhdl-template-package-decl) (define-key vhdl-template-map "Pb" 'vhdl-template-package-body) (define-key vhdl-template-map "(" 'vhdl-template-paired-parens) (define-key vhdl-template-map "po" 'vhdl-template-port) (define-key vhdl-template-map "pb" 'vhdl-template-procedure-body) (define-key vhdl-template-map "pd" 'vhdl-template-procedure-decl) (define-key vhdl-template-map "pc" 'vhdl-template-process-comb) (define-key vhdl-template-map "ps" 'vhdl-template-process-seq) (define-key vhdl-template-map "rp" 'vhdl-template-report) (define-key vhdl-template-map "rt" 'vhdl-template-return) (define-key vhdl-template-map "ss" 'vhdl-template-selected-signal-asst) (define-key vhdl-template-map "si" 'vhdl-template-signal) (define-key vhdl-template-map "su" 'vhdl-template-subtype) (define-key vhdl-template-map "ty" 'vhdl-template-type) (define-key vhdl-template-map "us" 'vhdl-template-use) (define-key vhdl-template-map "va" 'vhdl-template-variable) (define-key vhdl-template-map "wa" 'vhdl-template-wait) (define-key vhdl-template-map "wl" 'vhdl-template-while-loop) (define-key vhdl-template-map "wi" 'vhdl-template-with) (define-key vhdl-template-map "wc" 'vhdl-template-clocked-wait) (define-key vhdl-template-map "\C-pb" 'vhdl-template-package-numeric-bit) (define-key vhdl-template-map "\C-pn" 'vhdl-template-package-numeric-std) (define-key vhdl-template-map "\C-ps" 'vhdl-template-package-std-logic-1164) (define-key vhdl-template-map "\C-pA" 'vhdl-template-package-std-logic-arith) (define-key vhdl-template-map "\C-pM" 'vhdl-template-package-std-logic-misc) (define-key vhdl-template-map "\C-pS" 'vhdl-template-package-std-logic-signed) (define-key vhdl-template-map "\C-pT" 'vhdl-template-package-std-logic-textio) (define-key vhdl-template-map "\C-pU" 'vhdl-template-package-std-logic-unsigned) (define-key vhdl-template-map "\C-pt" 'vhdl-template-package-textio) (define-key vhdl-template-map "\C-dn" 'vhdl-template-directive-translate-on) (define-key vhdl-template-map "\C-df" 'vhdl-template-directive-translate-off) (define-key vhdl-template-map "\C-dN" 'vhdl-template-directive-synthesis-on) (define-key vhdl-template-map "\C-dF" 'vhdl-template-directive-synthesis-off) (define-key vhdl-template-map "\C-q" 'vhdl-template-search-prompt) (when (vhdl-standard-p 'ams) (define-key vhdl-template-map "br" 'vhdl-template-break) (define-key vhdl-template-map "cu" 'vhdl-template-case-use) (define-key vhdl-template-map "iu" 'vhdl-template-if-use) (define-key vhdl-template-map "lm" 'vhdl-template-limit) (define-key vhdl-template-map "na" 'vhdl-template-nature) (define-key vhdl-template-map "pa" 'vhdl-template-procedural) (define-key vhdl-template-map "qf" 'vhdl-template-quantity-free) (define-key vhdl-template-map "qb" 'vhdl-template-quantity-branch) (define-key vhdl-template-map "qs" 'vhdl-template-quantity-source) (define-key vhdl-template-map "sn" 'vhdl-template-subnature) (define-key vhdl-template-map "te" 'vhdl-template-terminal) ) (when (vhdl-standard-p 'math) (define-key vhdl-template-map "\C-pc" 'vhdl-template-package-math-complex) (define-key vhdl-template-map "\C-pr" 'vhdl-template-package-math-real) )) ;; initialize template map for VHDL Mode (vhdl-template-map-init) (defun vhdl-function-name (prefix string &optional postfix) "Generate a Lisp function name. PREFIX, STRING and optional POSTFIX are concatenated by '-' and spaces in STRING are replaced by `-' and substrings are converted to lower case." (let ((name prefix)) (while (string-match "\\(\\w+\\)\\s-*\\(.*\\)" string) (setq name (concat name "-" (downcase (substring string 0 (match-end 1))))) (setq string (substring string (match-beginning 2)))) (when postfix (setq name (concat name "-" postfix))) (intern name))) (defvar vhdl-model-map () "Keymap for VHDL models.") (defun vhdl-model-map-init () "Initialize `vhdl-model-map'." (setq vhdl-model-map (make-sparse-keymap)) ;; key bindings for VHDL models (let ((model-alist vhdl-model-alist) model) (while model-alist (setq model (car model-alist)) (define-key vhdl-model-map (nth 2 model) (vhdl-function-name "vhdl-model" (nth 0 model))) (setq model-alist (cdr model-alist))))) ;; initialize user model map for VHDL Mode (vhdl-model-map-init) (defvar vhdl-mode-map () "Keymap for VHDL Mode.") (defun vhdl-mode-map-init () "Initialize `vhdl-mode-map'." (setq vhdl-mode-map (make-sparse-keymap)) ;; template key bindings (define-key vhdl-mode-map "\C-c\C-t" vhdl-template-map) ;; model key bindings (define-key vhdl-mode-map "\C-c\C-m" vhdl-model-map) ;; standard key bindings (define-key vhdl-mode-map "\M-a" 'vhdl-beginning-of-statement) (define-key vhdl-mode-map "\M-e" 'vhdl-end-of-statement) (define-key vhdl-mode-map "\M-\C-f" 'vhdl-forward-sexp) (define-key vhdl-mode-map "\M-\C-b" 'vhdl-backward-sexp) (define-key vhdl-mode-map "\M-\C-u" 'vhdl-backward-up-list) (define-key vhdl-mode-map "\M-\C-a" 'vhdl-beginning-of-defun) (define-key vhdl-mode-map "\M-\C-e" 'vhdl-end-of-defun) (define-key vhdl-mode-map "\M-\C-h" 'vhdl-mark-defun) (define-key vhdl-mode-map "\M-\C-q" 'vhdl-indent-sexp) ;; backspace/delete key bindings (define-key vhdl-mode-map [backspace] 'backward-delete-char-untabify) (define-key vhdl-mode-map [delete] 'delete-char) (unless (string-match "XEmacs" emacs-version) (define-key vhdl-mode-map [M-delete] 'kill-word)) ;; mode specific key bindings (define-key vhdl-mode-map "\C-c\C-e" 'vhdl-electric-mode) (define-key vhdl-mode-map "\C-c\C-s" 'vhdl-stutter-mode) (define-key vhdl-mode-map "\C-c\C-k" 'vhdl-compile) (define-key vhdl-mode-map "\C-c\M-\C-k" 'vhdl-make) (define-key vhdl-mode-map "\C-c\C-p\C-w" 'vhdl-port-copy) (define-key vhdl-mode-map "\C-c\C-p\M-w" 'vhdl-port-copy) (define-key vhdl-mode-map "\C-c\C-p\C-e" 'vhdl-port-paste-entity) (define-key vhdl-mode-map "\C-c\C-p\C-c" 'vhdl-port-paste-component) (define-key vhdl-mode-map "\C-c\C-p\C-i" 'vhdl-port-paste-instance) (define-key vhdl-mode-map "\C-c\C-p\C-s" 'vhdl-port-paste-signals) (define-key vhdl-mode-map "\C-c\C-p\M-c" 'vhdl-port-paste-constants) (if (string-match "XEmacs" emacs-version) ; `... C-g' not allowed in XEmacs (define-key vhdl-mode-map "\C-c\C-p\M-g" 'vhdl-port-paste-generic-map) (define-key vhdl-mode-map "\C-c\C-p\C-g" 'vhdl-port-paste-generic-map)) (define-key vhdl-mode-map "\C-c\C-p\C-t" 'vhdl-port-paste-testbench) (define-key vhdl-mode-map "\C-c\C-p\C-f" 'vhdl-port-flatten) (define-key vhdl-mode-map "\C-c\C-c" 'vhdl-comment-uncomment-region) (define-key vhdl-mode-map "\C-c-" 'vhdl-comment-append-inline) (define-key vhdl-mode-map "\C-c\M--" 'vhdl-comment-display-line) (define-key vhdl-mode-map "\C-c\M-\C-i" 'vhdl-indent-line) (define-key vhdl-mode-map "\M-\C-\\" 'vhdl-indent-region) (define-key vhdl-mode-map "\C-c\C-a" 'vhdl-align-group) (define-key vhdl-mode-map "\C-c\C-r\C-a" 'vhdl-align-noindent-region) (define-key vhdl-mode-map "\C-c\M-\C-a" 'vhdl-align-inline-comment-group) (define-key vhdl-mode-map "\C-c\C-r\M-\C-a" 'vhdl-align-inline-comment-region) (define-key vhdl-mode-map "\C-c\C-w" 'vhdl-fixup-whitespace-region) (define-key vhdl-mode-map "\C-c\C-l\C-w" 'vhdl-line-kill) (define-key vhdl-mode-map "\C-c\C-l\M-w" 'vhdl-line-copy) (define-key vhdl-mode-map "\C-c\C-l\C-y" 'vhdl-line-yank) (define-key vhdl-mode-map "\C-c\C-l\t" 'vhdl-line-expand) (define-key vhdl-mode-map "\C-c\C-l\C-n" 'vhdl-line-transpose-next) (define-key vhdl-mode-map "\C-c\C-l\C-p" 'vhdl-line-transpose-previous) (define-key vhdl-mode-map "\C-c\C-l\C-o" 'vhdl-line-open) (define-key vhdl-mode-map "\C-c\C-l\C-g" 'goto-line) (define-key vhdl-mode-map "\C-c\C-l\C-c" 'vhdl-comment-uncomment-line) (define-key vhdl-mode-map "\C-c\C-r\C-u" 'vhdl-fix-case-region) (define-key vhdl-mode-map "\C-c\C-u" 'vhdl-fix-case-buffer) (define-key vhdl-mode-map "\C-c\C-f" 'vhdl-fontify-buffer) (define-key vhdl-mode-map "\C-c\C-x" 'vhdl-show-syntactic-information) (define-key vhdl-mode-map "\C-c\C-h" 'vhdl-doc-mode) (define-key vhdl-mode-map "\C-c\C-v" 'vhdl-version) (define-key vhdl-mode-map "\C-c\C-r\C-b" 'vhdl-beautify-region) (define-key vhdl-mode-map "\C-c\C-b" 'vhdl-beautify-buffer) (define-key vhdl-mode-map "\M-\t" 'tab-to-tab-stop) ;; insert commands bindings (define-key vhdl-mode-map "\C-c\C-i\C-c" 'vhdl-template-insert-construct) (define-key vhdl-mode-map "\C-c\C-i\C-p" 'vhdl-template-insert-package) (define-key vhdl-mode-map "\C-c\C-i\C-d" 'vhdl-template-insert-directive) (define-key vhdl-mode-map "\C-c\C-i\C-m" 'vhdl-model-insert) ;; electric key bindings (define-key vhdl-mode-map " " 'vhdl-electric-space) (if vhdl-intelligent-tab (define-key vhdl-mode-map "\t" 'vhdl-electric-tab) (define-key vhdl-mode-map "\t" 'vhdl-indent-line)) (define-key vhdl-mode-map "\r" 'vhdl-electric-return) (define-key vhdl-mode-map "-" 'vhdl-electric-dash) (define-key vhdl-mode-map "[" 'vhdl-electric-open-bracket) (define-key vhdl-mode-map "]" 'vhdl-electric-close-bracket) (define-key vhdl-mode-map "'" 'vhdl-electric-quote) (define-key vhdl-mode-map ";" 'vhdl-electric-semicolon) (define-key vhdl-mode-map "," 'vhdl-electric-comma) (define-key vhdl-mode-map "." 'vhdl-electric-period) (when (vhdl-standard-p 'ams) (define-key vhdl-mode-map "=" 'vhdl-electric-equal))) ;; initialize mode map for VHDL Mode (vhdl-mode-map-init) ;; define special minibuffer keymap for enabling word completion in minibuffer ;; (useful in template generator prompts) (defvar vhdl-minibuffer-local-map (copy-keymap minibuffer-local-map) "Keymap for minibuffer used in VHDL Mode.") (when vhdl-word-completion-in-minibuffer (define-key vhdl-minibuffer-local-map "\t" 'vhdl-minibuffer-tab)) ;; set up electric character functions to work with ;; `delete-selection-mode' (Emacs) and `pending-delete-mode' (XEmacs) (mapcar (function (lambda (sym) (put sym 'delete-selection t) ; for `delete-selection-mode' (Emacs) (put sym 'pending-delete t))) ; for `pending-delete-mode' (XEmacs) '(vhdl-electric-space vhdl-electric-tab vhdl-electric-return vhdl-electric-dash vhdl-electric-open-bracket vhdl-electric-close-bracket vhdl-electric-quote vhdl-electric-semicolon vhdl-electric-comma vhdl-electric-period vhdl-electric-equal)) ;; syntax table (defvar vhdl-mode-syntax-table nil "Syntax table used in `vhdl-mode' buffers.") (defun vhdl-mode-syntax-table-init () "Initialize `vhdl-mode-syntax-table'." (setq vhdl-mode-syntax-table (make-syntax-table)) ;; define punctuation (modify-syntax-entry ?\# "." vhdl-mode-syntax-table) (modify-syntax-entry ?\$ "." vhdl-mode-syntax-table) (modify-syntax-entry ?\% "." vhdl-mode-syntax-table) (modify-syntax-entry ?\& "." vhdl-mode-syntax-table) (modify-syntax-entry ?\' "." vhdl-mode-syntax-table) (modify-syntax-entry ?\* "." vhdl-mode-syntax-table) (modify-syntax-entry ?\+ "." vhdl-mode-syntax-table) (modify-syntax-entry ?\. "." vhdl-mode-syntax-table) (modify-syntax-entry ?\/ "." vhdl-mode-syntax-table) (modify-syntax-entry ?\: "." vhdl-mode-syntax-table) (modify-syntax-entry ?\; "." vhdl-mode-syntax-table) (modify-syntax-entry ?\< "." vhdl-mode-syntax-table) (modify-syntax-entry ?\= "." vhdl-mode-syntax-table) (modify-syntax-entry ?\> "." vhdl-mode-syntax-table) (modify-syntax-entry ?\\ "." vhdl-mode-syntax-table) (modify-syntax-entry ?\| "." vhdl-mode-syntax-table) ;; define string (modify-syntax-entry ?\" "\"" vhdl-mode-syntax-table) ;; define underscore (when vhdl-underscore-is-part-of-word (modify-syntax-entry ?_ "w" vhdl-mode-syntax-table)) ;; a single hyphen is punctuation, but a double hyphen starts a comment (modify-syntax-entry ?\- ". 12" vhdl-mode-syntax-table) ;; and \n and \^M end a comment (modify-syntax-entry ?\n ">" vhdl-mode-syntax-table) (modify-syntax-entry ?\^M ">" vhdl-mode-syntax-table) ;; define parentheses to match (modify-syntax-entry ?\( "()" vhdl-mode-syntax-table) (modify-syntax-entry ?\) ")(" vhdl-mode-syntax-table) (modify-syntax-entry ?\[ "(]" vhdl-mode-syntax-table) (modify-syntax-entry ?\] ")[" vhdl-mode-syntax-table) (modify-syntax-entry ?\{ "(}" vhdl-mode-syntax-table) (modify-syntax-entry ?\} "){" vhdl-mode-syntax-table)) ;; initialize syntax table for VHDL Mode (vhdl-mode-syntax-table-init) (defmacro vhdl-ext-syntax-table (&rest body) "Execute BODY with syntax table that includes `_' in word class." (` (let (result) (modify-syntax-entry ?_ "w" vhdl-mode-syntax-table) (setq result (progn (,@ body))) (when (not vhdl-underscore-is-part-of-word) (modify-syntax-entry ?_ "_" vhdl-mode-syntax-table)) result))) (defvar vhdl-syntactic-context nil "Buffer local variable containing syntactic analysis list.") (make-variable-buffer-local 'vhdl-syntactic-context) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Abbrev hook bindings (defvar vhdl-mode-abbrev-table nil "Abbrev table to use in `vhdl-mode' buffers.") (defun vhdl-mode-abbrev-table-init () "Initialize `vhdl-mode-abbrev-table'." (when vhdl-mode-abbrev-table (clear-abbrev-table vhdl-mode-abbrev-table)) (define-abbrev-table 'vhdl-mode-abbrev-table (append (when (memq 'vhdl vhdl-electric-keywords) ;; VHDL'93 keywords '( ("--" "" vhdl-template-display-comment-hook 0) ("abs" "" vhdl-template-default-hook 0) ("access" "" vhdl-template-default-hook 0) ("after" "" vhdl-template-default-hook 0) ("alias" "" vhdl-template-alias-hook 0) ("all" "" vhdl-template-default-hook 0) ("and" "" vhdl-template-default-hook 0) ("arch" "" vhdl-template-architecture-hook 0) ("architecture" "" vhdl-template-architecture-hook 0) ("array" "" vhdl-template-default-hook 0) ("assert" "" vhdl-template-assert-hook 0) ("attr" "" vhdl-template-attribute-hook 0) ("attribute" "" vhdl-template-attribute-hook 0) ("begin" "" vhdl-template-default-indent-hook 0) ("block" "" vhdl-template-block-hook 0) ("body" "" vhdl-template-default-hook 0) ("buffer" "" vhdl-template-default-hook 0) ("bus" "" vhdl-template-default-hook 0) ("case" "" vhdl-template-case-hook 0) ("comp" "" vhdl-template-component-hook 0) ("component" "" vhdl-template-component-hook 0) ("cond" "" vhdl-template-conditional-signal-asst-hook 0) ("conditional" "" vhdl-template-conditional-signal-asst-hook 0) ("conf" "" vhdl-template-configuration-hook 0) ("configuration" "" vhdl-template-configuration-hook 0) ("cons" "" vhdl-template-constant-hook 0) ("constant" "" vhdl-template-constant-hook 0) ("disconnect" "" vhdl-template-disconnect-hook 0) ("downto" "" vhdl-template-default-hook 0) ("else" "" vhdl-template-else-hook 0) ("elseif" "" vhdl-template-elsif-hook 0) ("elsif" "" vhdl-template-elsif-hook 0) ("end" "" vhdl-template-default-indent-hook 0) ("entity" "" vhdl-template-entity-hook 0) ("exit" "" vhdl-template-exit-hook 0) ("file" "" vhdl-template-file-hook 0) ("for" "" vhdl-template-for-hook 0) ("func" "" vhdl-template-function-hook 0) ("function" "" vhdl-template-function-hook 0) ("generic" "" vhdl-template-generic-hook 0) ("group" "" vhdl-template-group-hook 0) ("guarded" "" vhdl-template-default-hook 0) ("if" "" vhdl-template-if-hook 0) ("impure" "" vhdl-template-default-hook 0) ("in" "" vhdl-template-default-hook 0) ("inertial" "" vhdl-template-default-hook 0) ("inout" "" vhdl-template-default-hook 0) ("inst" "" vhdl-template-instance-hook 0) ("instance" "" vhdl-template-instance-hook 0) ("is" "" vhdl-template-default-hook 0) ("label" "" vhdl-template-default-hook 0) ("library" "" vhdl-template-library-hook 0) ("linkage" "" vhdl-template-default-hook 0) ("literal" "" vhdl-template-default-hook 0) ("loop" "" vhdl-template-bare-loop-hook 0) ("map" "" vhdl-template-map-hook 0) ("mod" "" vhdl-template-default-hook 0) ("nand" "" vhdl-template-default-hook 0) ("new" "" vhdl-template-default-hook 0) ("next" "" vhdl-template-next-hook 0) ("nor" "" vhdl-template-default-hook 0) ("not" "" vhdl-template-default-hook 0) ("null" "" vhdl-template-default-hook 0) ("of" "" vhdl-template-default-hook 0) ("on" "" vhdl-template-default-hook 0) ("open" "" vhdl-template-default-hook 0) ("or" "" vhdl-template-default-hook 0) ("others" "" vhdl-template-default-hook 0) ("out" "" vhdl-template-default-hook 0) ("pack" "" vhdl-template-package-hook 0) ("package" "" vhdl-template-package-hook 0) ("port" "" vhdl-template-port-hook 0) ("postponed" "" vhdl-template-default-hook 0) ("procedure" "" vhdl-template-procedure-hook 0) ("process" "" vhdl-template-process-hook 0) ("pure" "" vhdl-template-default-hook 0) ("range" "" vhdl-template-default-hook 0) ("record" "" vhdl-template-default-hook 0) ("register" "" vhdl-template-default-hook 0) ("reject" "" vhdl-template-default-hook 0) ("rem" "" vhdl-template-default-hook 0) ("report" "" vhdl-template-report-hook 0) ("return" "" vhdl-template-return-hook 0) ("rol" "" vhdl-template-default-hook 0) ("ror" "" vhdl-template-default-hook 0) ("select" "" vhdl-template-selected-signal-asst-hook 0) ("severity" "" vhdl-template-default-hook 0) ("shared" "" vhdl-template-default-hook 0) ("sig" "" vhdl-template-signal-hook 0) ("signal" "" vhdl-template-signal-hook 0) ("sla" "" vhdl-template-default-hook 0) ("sll" "" vhdl-template-default-hook 0) ("sra" "" vhdl-template-default-hook 0) ("srl" "" vhdl-template-default-hook 0) ("subtype" "" vhdl-template-subtype-hook 0) ("then" "" vhdl-template-default-hook 0) ("to" "" vhdl-template-default-hook 0) ("transport" "" vhdl-template-default-hook 0) ("type" "" vhdl-template-type-hook 0) ("unaffected" "" vhdl-template-default-hook 0) ("units" "" vhdl-template-default-hook 0) ("until" "" vhdl-template-default-hook 0) ("use" "" vhdl-template-use-hook 0) ("var" "" vhdl-template-variable-hook 0) ("variable" "" vhdl-template-variable-hook 0) ("wait" "" vhdl-template-wait-hook 0) ("when" "" vhdl-template-when-hook 0) ("while" "" vhdl-template-while-loop-hook 0) ("with" "" vhdl-template-with-hook 0) ("xnor" "" vhdl-template-default-hook 0) ("xor" "" vhdl-template-default-hook 0) )) ;; VHDL-AMS keywords (when (and (memq 'vhdl vhdl-electric-keywords) (vhdl-standard-p 'ams)) '( ("across" "" vhdl-template-default-hook 0) ("break" "" vhdl-template-break-hook 0) ("limit" "" vhdl-template-limit-hook 0) ("nature" "" vhdl-template-nature-hook 0) ("noise" "" vhdl-template-default-hook 0) ("procedural" "" vhdl-template-procedural-hook 0) ("quantity" "" vhdl-template-quantity-hook 0) ("reference" "" vhdl-template-default-hook 0) ("spectrum" "" vhdl-template-default-hook 0) ("subnature" "" vhdl-template-subnature-hook 0) ("terminal" "" vhdl-template-terminal-hook 0) ("through" "" vhdl-template-default-hook 0) ("tolerance" "" vhdl-template-default-hook 0) )) ;; user model keywords (when (memq 'user vhdl-electric-keywords) (let ((alist vhdl-model-alist) abbrev-list keyword) (while alist (setq keyword (nth 3 (car alist))) (unless (equal keyword "") (setq abbrev-list (cons (list keyword "" (vhdl-function-name "vhdl-model" (nth 0 (car alist)) "hook") 0) abbrev-list))) (setq alist (cdr alist))) abbrev-list))))) ;; initialize abbrev table for VHDL Mode (vhdl-mode-abbrev-table-init) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Template completion lists (defvar vhdl-template-construct-alist nil "List of built-in construct templates.") (defun vhdl-template-construct-alist-init () "Initialize `vhdl-template-construct-alist'." (setq vhdl-template-construct-alist (append '( ("alias declaration" vhdl-template-alias) ("architecture body" vhdl-template-architecture) ("assertion" vhdl-template-assert) ("attribute declaration" vhdl-template-attribute-decl) ("attribute specification" vhdl-template-attribute-spec) ("block configuration" vhdl-template-block-configuration) ("block statement" vhdl-template-block) ("case statement" vhdl-template-case-is) ("component configuration" vhdl-template-component-conf) ("component declaration" vhdl-template-component-decl) ("component instantiation statement" vhdl-template-component-inst) ("conditional signal assignment" vhdl-template-conditional-signal-asst) ("configuration declaration" vhdl-template-configuration-decl) ("configuration specification" vhdl-template-configuration-spec) ("constant declaration" vhdl-template-constant) ("disconnection specification" vhdl-template-disconnect) ("entity declaration" vhdl-template-entity) ("exit statement" vhdl-template-exit) ("file declaration" vhdl-template-file) ("generate statement" vhdl-template-generate) ("generic clause" vhdl-template-generic) ("group declaration" vhdl-template-group-decl) ("group template declaration" vhdl-template-group-template) ("if statement" vhdl-template-if-then) ("library clause" vhdl-template-library) ("loop statement" vhdl-template-loop) ("next statement" vhdl-template-next) ("package declaration" vhdl-template-package-decl) ("package body" vhdl-template-package-body) ("port clause" vhdl-template-port) ("process statement" vhdl-template-process) ("report statement" vhdl-template-report) ("return statement" vhdl-template-return) ("selected signal assignment" vhdl-template-selected-signal-asst) ("signal declaration" vhdl-template-signal) ("subprogram declaration" vhdl-template-subprogram-decl) ("subprogram body" vhdl-template-subprogram-body) ("subtype declaration" vhdl-template-subtype) ("type declaration" vhdl-template-type) ("use clause" vhdl-template-use) ("variable declaration" vhdl-template-variable) ("wait statement" vhdl-template-wait) ) (when (vhdl-standard-p 'ams) '( ("break statement" vhdl-template-break) ("nature declaration" vhdl-template-nature) ("quantity declaration" vhdl-template-quantity) ("simultaneous case statement" vhdl-template-case-use) ("simultaneous if statement" vhdl-template-if-use) ("simultaneous procedural statement" vhdl-template-procedural) ("step limit specification" vhdl-template-limit) ("subnature declaration" vhdl-template-subnature) ("terminal declaration" vhdl-template-terminal) ))))) ;; initialize for VHDL Mode (vhdl-template-construct-alist-init) (defvar vhdl-template-package-alist nil "List of built-in package templates.") (defun vhdl-template-package-alist-init () "Initialize `vhdl-template-package-alist'." (setq vhdl-template-package-alist (append '( ("numeric_bit" vhdl-template-package-numeric-bit) ("numeric_std" vhdl-template-package-numeric-std) ("std_logic_1164" vhdl-template-package-std-logic-1164) ("std_logic_arith" vhdl-template-package-std-logic-arith) ("std_logic_misc" vhdl-template-package-std-logic-misc) ("std_logic_signed" vhdl-template-package-std-logic-signed) ("std_logic_textio" vhdl-template-package-std-logic-textio) ("std_logic_unsigned" vhdl-template-package-std-logic-unsigned) ("textio" vhdl-template-package-textio) ) (when (vhdl-standard-p 'math) '( ("math_complex" vhdl-template-package-math-complex) ("math_real" vhdl-template-package-math-real) ))))) ;; initialize for VHDL Mode (vhdl-template-package-alist-init) (defvar vhdl-template-directive-alist (append '( ("translate_on" vhdl-template-directive-translate-on) ("translate_off" vhdl-template-directive-translate-off) ("synthesis_on" vhdl-template-directive-synthesis-on) ("synthesis_off" vhdl-template-directive-synthesis-off) )) "List of built-in directive templates.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Menues ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; VHDL menu (using `easy-menu.el') (defun vhdl-customize () "Call the customize function with `vhdl' as argument." (interactive) (customize-browse 'vhdl)) (defun vhdl-create-customize-menu () "Create a full customization menu for VHDL, insert it into the menu." (interactive) (if (fboundp 'customize-menu-create) (easy-menu-change '("VHDL") "Customize" `(["Browse VHDL Group..." vhdl-customize t] ,(customize-menu-create 'vhdl) "--" ["Activate New Customizations" vhdl-activate-customizations t])) (error "Cannot expand menu (outdated version of cus-edit.el)"))) (defun vhdl-create-mode-menu () "Create VHDL Mode menu." (list "VHDL" '("Mode" ["Electric" vhdl-electric-mode :style toggle :selected vhdl-electric-mode] ["Stutter" vhdl-stutter-mode :style toggle :selected vhdl-stutter-mode] ) "--" (append '("Project" ["None" (vhdl-project-switch "") :style radio :selected (equal vhdl-project "")] "--" ) ;; add menu entries for defined projects (let ((project-alist vhdl-project-alist) menu-alist name) (while project-alist (setq name (car (car project-alist))) (setq menu-alist (cons (vector name (list 'vhdl-project-switch name) :style 'radio :selected (list 'equal 'vhdl-project name)) menu-alist)) (setq project-alist (cdr project-alist))) (setq menu-alist (cons '["Add Project..." (customize-variable 'vhdl-project-alist) t] (cons "--" menu-alist))) (nreverse menu-alist))) "--" (list "Compile" ["Compile Buffer" vhdl-compile t] ["Stop Compilation" kill-compilation t] "--" ["Make" vhdl-make t] ["Generate Makefile" vhdl-generate-makefile t] "--" ["Next Error" next-error t] ["Previous Error" previous-error t] ["First Error" first-error t] "--" (append '("Compiler") ;; add menu entries for defined compilers (let ((comp-alist vhdl-compiler-alist) menu-alist name) (while comp-alist (setq name (car (car comp-alist))) (setq menu-alist (cons (vector name (list 'setq 'vhdl-compiler name) :style 'radio :selected (list 'equal 'vhdl-compiler name)) menu-alist)) (setq comp-alist (cdr comp-alist))) (setq menu-alist (cons '["Add Compiler..." (customize-variable 'vhdl-compiler-alist) t] (cons "--" menu-alist))) (nreverse menu-alist)))) "--" (append '("Template" ("VHDL Construct 1" ["Alias" vhdl-template-alias t] ["Architecture" vhdl-template-architecture t] ["Assert" vhdl-template-assert t] ["Attribute (Decl)" vhdl-template-attribute-decl t] ["Attribute (Spec)" vhdl-template-attribute-spec t] ["Block" vhdl-template-block t] ["Case" vhdl-template-case-is t] ["Component (Decl)" vhdl-template-component-decl t] ["(Component) Instance" vhdl-template-component-inst t] ["Conditional (Signal Asst)" vhdl-template-conditional-signal-asst t] ["Configuration (Block)"vhdl-template-block-configuration t] ["Configuration (Comp)" vhdl-template-component-conf t] ["Configuration (Decl)" vhdl-template-configuration-decl t] ["Configuration (Spec)" vhdl-template-configuration-spec t] ["Constant" vhdl-template-constant t] ["Disconnect" vhdl-template-disconnect t] ["Else" vhdl-template-else t] ["Elsif" vhdl-template-elsif t] ["Entity" vhdl-template-entity t] ["Exit" vhdl-template-exit t] ["File" vhdl-template-file t] ["For (Generate)" vhdl-template-for-generate t] ["For (Loop)" vhdl-template-for-loop t] ["Function (Body)" vhdl-template-function-body t] ["Function (Decl)" vhdl-template-function-decl t] ["Generic" vhdl-template-generic t] ["Group (Decl)" vhdl-template-group-decl t] ["Group (Template)" vhdl-template-group-template t] ) ("VHDL Construct 2" ["If (Generate)" vhdl-template-if-generate t] ["If (Then)" vhdl-template-if-then t] ["Library" vhdl-template-library t] ["Loop" vhdl-template-bare-loop t] ["Map" vhdl-template-map t] ["Next" vhdl-template-next t] ["(Others)" vhdl-template-others t] ["Package (Decl)" vhdl-template-package-decl t] ["Package (Body)" vhdl-template-package-body t] ["Port" vhdl-template-port t] ["Procedure (Body)" vhdl-template-procedure-body t] ["Procedure (Decl)" vhdl-template-procedure-decl t] ["Process (Comb)" vhdl-template-process-comb t] ["Process (Seq)" vhdl-template-process-seq t] ["Report" vhdl-template-report t] ["Return" vhdl-template-return t] ["Select" vhdl-template-selected-signal-asst t] ["Signal" vhdl-template-signal t] ["Subtype" vhdl-template-subtype t] ["Type" vhdl-template-type t] ["Use" vhdl-template-use t] ["Variable" vhdl-template-variable t] ["Wait" vhdl-template-wait t] ["(Clocked Wait)" vhdl-template-clocked-wait t] ["When" vhdl-template-when t] ["While (Loop)" vhdl-template-while-loop t] ["With" vhdl-template-with t] )) (when (vhdl-standard-p 'ams) '(("VHDL-AMS Construct" ["Break" vhdl-template-break t] ["Case (Use)" vhdl-template-case-use t] ["If (Use)" vhdl-template-if-use t] ["Limit" vhdl-template-limit t] ["Nature" vhdl-template-nature t] ["Procedural" vhdl-template-procedural t] ["Quantity (Free)" vhdl-template-quantity-free t] ["Quantity (Branch)" vhdl-template-quantity-branch t] ["Quantity (Source)" vhdl-template-quantity-source t] ["Subnature" vhdl-template-subnature t] ["Terminal" vhdl-template-terminal t] ))) '(["Insert Construct" vhdl-template-insert-construct :keys "C-c C-i C-c"] "--") (list (append '("Package") (when (vhdl-standard-p 'math) '( ["math_complex" vhdl-template-package-math-complex t] ["math_real" vhdl-template-package-math-real t] )) '( ["numeric_bit" vhdl-template-package-numeric-bit t] ["numeric_std" vhdl-template-package-numeric-std t] ["std_logic_1164" vhdl-template-package-std-logic-1164 t] ["textio" vhdl-template-package-textio t] "--" ["std_logic_arith" vhdl-template-package-std-logic-arith t] ["std_logic_signed" vhdl-template-package-std-logic-signed t] ["std_logic_unsigned" vhdl-template-package-std-logic-unsigned t] ["std_logic_misc" vhdl-template-package-std-logic-misc t] ["std_logic_textio" vhdl-template-package-std-logic-textio t] "--" ["Insert Package" vhdl-template-insert-package :keys "C-c C-i C-p"] ))) '(("Directive" ["translate_on" vhdl-template-directive-translate-on t] ["translate_off" vhdl-template-directive-translate-off t] ["synthesis_on" vhdl-template-directive-synthesis-on t] ["synthesis_off" vhdl-template-directive-synthesis-off t] "--" ["Insert Directive" vhdl-template-insert-directive :keys "C-c C-i C-d"] ) "--" ["Insert Header" vhdl-template-header :keys "C-c C-t C-h"] ["Insert Footer" vhdl-template-footer t] ["Insert Date" vhdl-template-insert-date t] ["Modify Date" vhdl-template-modify :keys "C-c C-t C-m"] "--" ["Query Next Prompt" vhdl-template-search-prompt t] )) (append '("Model") ;; add menu entries for defined models (let ((model-alist vhdl-model-alist) menu-alist model) (while model-alist (setq model (car model-alist)) (setq menu-alist (cons (vector (nth 0 model) (vhdl-function-name "vhdl-model" (nth 0 model)) :keys (concat "C-c C-m " (key-description (nth 2 model)))) menu-alist)) (setq model-alist (cdr model-alist))) (setq menu-alist (append (nreverse menu-alist) '("--" ["Insert Model" vhdl-model-insert :keys "C-c C-i C-m"] ["Add Model..." (customize-variable 'vhdl-model-alist) t]))) menu-alist)) '("Port" ["Copy" vhdl-port-copy t] "--" ["Paste As Entity" vhdl-port-paste-entity vhdl-port-list] ["Paste As Component" vhdl-port-paste-component vhdl-port-list] ["Paste As Instance" vhdl-port-paste-instance :keys "C-c C-p C-i" :active vhdl-port-list] ["Paste As Signals" vhdl-port-paste-signals vhdl-port-list] ["Paste As Constants" vhdl-port-paste-constants vhdl-port-list] ["Paste As Generic Map" vhdl-port-paste-generic-map vhdl-port-list] ["Paste As Test Bench" vhdl-port-paste-testbench vhdl-port-list] "--" ["Flatten" vhdl-port-flatten vhdl-port-list] ) "--" '("Comment" ["(Un)Comment Out Region" vhdl-comment-uncomment-region (mark)] "--" ["Insert Inline Comment" vhdl-comment-append-inline t] ["Insert Horizontal Line" vhdl-comment-display-line t] ["Insert Display Comment" vhdl-comment-display t] "--" ["Fill Comment" fill-paragraph t] ["Fill Comment Region" fill-region (mark)] ["Kill Comment Region" vhdl-comment-kill-region (mark)] ["Kill Inline Comment Region" vhdl-comment-kill-inline-region (mark)] ) '("Line" ["Kill" vhdl-line-kill t] ["Copy" vhdl-line-copy t] ["Yank" vhdl-line-yank t] ["Expand" vhdl-line-expand t] "--" ["Transpose Next" vhdl-line-transpose-next t] ["Transpose Prev" vhdl-line-transpose-previous t] ["Open" vhdl-line-open t] ["Join" delete-indentation t] "--" ["Goto" goto-line t] ["(Un)Comment Out" vhdl-comment-uncomment-line t] ) '("Move" ["Forward Statement" vhdl-end-of-statement t] ["Backward Statement" vhdl-beginning-of-statement t] ["Forward Expression" vhdl-forward-sexp t] ["Backward Expression" vhdl-backward-sexp t] ["Forward Function" vhdl-end-of-defun t] ["Backward Function" vhdl-beginning-of-defun t] ["Mark Function" vhdl-mark-defun t] ) "--" '("Indent" ["Line" vhdl-indent-line t] ["Region" vhdl-indent-region (mark)] ["Buffer" vhdl-indent-buffer t] ) '("Align" ["Group" vhdl-align-group t] ["Region" vhdl-align-noindent-region (mark)] ["Buffer" vhdl-align-noindent-buffer t] "--" ["Inline Comment Group" vhdl-align-inline-comment-group t] ["Inline Comment Region" vhdl-align-inline-comment-region (mark)] ["Inline Comment Buffer" vhdl-align-inline-comment-buffer t] "--" ["Fixup Whitespace Region" vhdl-fixup-whitespace-region (mark)] ["Fixup Whitespace Buffer" vhdl-fixup-whitespace-buffer t] ) '("Fix Case" ["Region" vhdl-fix-case-region (mark)] ["Buffer" vhdl-fix-case-buffer t] ) '("Beautify" ["Beautify Region" vhdl-beautify-region (mark)] ["Beautify Buffer" vhdl-beautify-buffer t] ) "--" ["Fontify Buffer" vhdl-fontify-buffer t] ["Syntactic Info" vhdl-show-syntactic-information t] "--" '("Documentation" ["VHDL Mode" vhdl-doc-mode :keys "C-c C-h"] ["Reserved Words" (vhdl-doc-variable 'vhdl-doc-keywords) t] ["Coding Style" (vhdl-doc-variable 'vhdl-doc-coding-style) t] ) ["Version" vhdl-version t] ["Bug Report..." vhdl-submit-bug-report t] "--" '("Speedbar" ["Open/Close" vhdl-speedbar t] "--" ["Show Hierarchy" vhdl-speedbar-toggle-hierarchy :style toggle :selected (and (boundp 'speedbar-initial-expansion-list-name) (equal speedbar-initial-expansion-list-name "vhdl hierarchy")) :active (and (boundp 'speedbar-frame) speedbar-frame)] ) "--" '("Customize" ["Browse VHDL Group..." vhdl-customize t] ["Build Customize Menu" vhdl-create-customize-menu (fboundp 'customize-menu-create)] "--" ["Activate New Customizations" vhdl-activate-customizations t]) )) (defvar vhdl-mode-menu-list (vhdl-create-mode-menu) "VHDL Mode menu.") (defun vhdl-update-mode-menu () "Update VHDL mode menu." (interactive) (easy-menu-remove vhdl-mode-menu-list) ; for XEmacs (setq vhdl-mode-menu-list (vhdl-create-mode-menu)) (easy-menu-add vhdl-mode-menu-list) ; for XEmacs (easy-menu-define vhdl-mode-menu vhdl-mode-map "Menu keymap for VHDL Mode." vhdl-mode-menu-list)) (require 'easymenu) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Index menu (using `imenu.el'), also used for speedbar (using `speedbar.el') (defvar vhdl-imenu-generic-expression '( ("Subprogram" "^\\s-*\\(\\(\\(impure\\|pure\\)\\s-+\\|\\)function\\|procedure\\)\\s-+\\(\"?\\(\\w\\|\\s_\\)+\"?\\)" 4) ("Instance" "^\\s-*\\(\\(\\w\\|\\s_\\)+\\s-*:\\(\\s-\\|\n\\)*\\(\\w\\|\\s_\\)+\\)\\(\\s-\\|\n\\)+\\(generic\\|port\\)\\s-+map\\>" 1) ("Component" "^\\s-*\\(component\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\)" 2) ("Procedural" "^\\s-*\\(\\(\\w\\|\\s_\\)+\\)\\s-*:\\(\\s-\\|\n\\)*\\(procedural\\)" 1) ("Process" "^\\s-*\\(\\(\\w\\|\\s_\\)+\\)\\s-*:\\(\\s-\\|\n\\)*\\(\\(postponed\\s-+\\|\\)process\\)" 1) ("Block" "^\\s-*\\(\\(\\w\\|\\s_\\)+\\)\\s-*:\\(\\s-\\|\n\\)*\\(block\\)" 1) ("Package" "^\\s-*\\(package\\( body\\|\\)\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\)" 3) ("Configuration" "^\\s-*\\(configuration\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\s-+of\\s-+\\(\\w\\|\\s_\\)+\\)" 2) ("Architecture" "^\\s-*\\(architecture\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\s-+of\\s-+\\(\\w\\|\\s_\\)+\\)" 2) ("Entity" "^\\s-*\\(entity\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\)" 2) ) "Imenu generic expression for VHDL Mode. See `imenu-generic-expression'.") (defun vhdl-index-menu-init () "Initialize index menu." (set (make-local-variable 'imenu-case-fold-search) t) (set (make-local-variable 'imenu-generic-expression) vhdl-imenu-generic-expression) (when (and vhdl-index-menu (not (string-match "XEmacs" emacs-version))) (if (or (not (boundp 'font-lock-maximum-size)) (> font-lock-maximum-size (buffer-size))) (imenu-add-to-menubar "Index") (message "Scanning buffer for index...buffer too big")))) ;; ############################################################################ ;; Source file menu (using `easy-menu.el') (defvar vhdl-sources-menu nil) (defun vhdl-directory-files (directory &optional full match) "Call `directory-files' if DIRECTORY exists, otherwise generate error message." (if (file-directory-p directory) (directory-files directory full match) (message "No such directory: \"%s\"" directory) nil)) (defun vhdl-get-source-files (&optional full directory) "Get list of VHDL source files in DIRECTORY or current directory." (let ((mode-alist auto-mode-alist) filename-regexp) ;; create regular expressions for matching file names (setq filename-regexp ".*\\(") (while mode-alist (when (eq (cdr (car mode-alist)) 'vhdl-mode) (setq filename-regexp (concat filename-regexp (car (car mode-alist)) "\\|"))) (setq mode-alist (cdr mode-alist))) (setq filename-regexp (concat (substring filename-regexp 0 (string-match "\\\\|$" filename-regexp)) "\\)")) ;; find files (nreverse (vhdl-directory-files (or directory default-directory) full filename-regexp)))) (defun vhdl-add-source-files-menu () "Scan directory for all VHDL source files and generate menu. The directory of the current source file is scanned." (interactive) (message "Scanning directory for source files ...") (let ((newmap (current-local-map)) (mode-alist auto-mode-alist) (file-list (vhdl-get-source-files)) menu-list found) ;; Create list for menu (setq found nil) (while file-list (setq found t) (setq menu-list (cons (vector (car file-list) (list 'find-file (car file-list)) t) menu-list)) (setq file-list (cdr file-list))) (setq menu-list (vhdl-menu-split menu-list 25)) (when found (setq menu-list (cons "--" menu-list))) (setq menu-list (cons ["*Rescan*" vhdl-add-source-files-menu t] menu-list)) (setq menu-list (cons "Sources" menu-list)) ;; Create menu (easy-menu-add menu-list) (easy-menu-define vhdl-sources-menu newmap "VHDL source files menu" menu-list)) (message "")) (defun vhdl-menu-split (list n) "Split menu LIST into several submenues, if number of elements > N." (if (> (length list) n) (let ((remain list) (result '()) (sublist '()) (menuno 1) (i 0)) (while remain (setq sublist (cons (car remain) sublist)) (setq remain (cdr remain)) (setq i (+ i 1)) (if (= i n) (progn (setq result (cons (cons (format "Sources %s" menuno) (nreverse sublist)) result)) (setq i 0) (setq menuno (+ menuno 1)) (setq sublist '())))) (and sublist (setq result (cons (cons (format "Sources %s" menuno) (nreverse sublist)) result))) (nreverse result)) list)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; VHDL Mode definition ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; performs all buffer local initializations ;;;###autoload (defun vhdl-mode () "Major mode for editing VHDL code. Usage: ------ - TEMPLATE INSERTION (electrification): After typing a VHDL keyword and entering `\\[vhdl-electric-space]', you are prompted for arguments while a template is generated for that VHDL construct. Typing `\\[vhdl-electric-return]' or `\\[keyboard-quit]' at the first (mandatory) prompt aborts the current template generation. Optional arguments are indicated by square brackets and removed if the queried string is left empty. Prompts for mandatory arguments remain in the code if the queried string is left empty. They can be queried again by `\\[vhdl-template-search-prompt]'. Typing `\\[just-one-space]' after a keyword inserts a space without calling the template generator. Automatic template generation (i.e. electrification) can be disabled (enabled) by typing `\\[vhdl-electric-mode]' or by setting custom variable `vhdl-electric-mode' (see CUSTOMIZATION). Enabled electrification is indicated by `/e' in the modeline. Template generators can be invoked from the VHDL menu, by key bindings, by typing `C-c C-i C-c' and choosing a construct, or by typing the keyword (i.e. first word of menu entry not in parenthesis) and `\\[vhdl-electric-space]'. The following abbreviations can also be used: arch, attr, cond, conf, comp, cons, func, inst, pack, sig, var. Template styles can be customized in customization group `vhdl-electric' \(see CUSTOMIZATION). - HEADER INSERTION: A file header can be inserted by `\\[vhdl-template-header]'. A file footer (template at the end of the file) can be inserted by `\\[vhdl-template-footer]'. See customization group `vhdl-header'. - STUTTERING: Double striking of some keys inserts cumbersome VHDL syntax elements. Stuttering can be disabled (enabled) by typing `\\[vhdl-stutter-mode]' or by variable `vhdl-stutter-mode'. Enabled stuttering is indicated by `/s' in the modeline. The stuttering keys and their effects are: ;; --> \" : \" [ --> ( -- --> comment ;;; --> \" := \" [[ --> [ --CR --> comment-out code .. --> \" => \" ] --> ) --- --> horizontal line ,, --> \" <= \" ]] --> ] ---- --> display comment == --> \" == \" '' --> \\\" - WORD COMPLETION: Typing `\\[vhdl-electric-tab]' after a (not completed) word looks for a VHDL keyword or a word in the buffer that starts alike, inserts it and adjusts case. Re-typing `\\[vhdl-electric-tab]' toggles through alternative word completions. This also works in the minibuffer (i.e. in template generator prompts). Typing `\\[vhdl-electric-tab]' after `(' looks for and inserts complete parenthesized expressions (e.g. for array index ranges). All keywords as well as standard types and subprograms of VHDL have predefined abbreviations (e.g. type \"std\" and `\\[vhdl-electric-tab]' will toggle through all standard types beginning with \"std\"). Typing `\\[vhdl-electric-tab]' after a non-word character indents the line if at the beginning of a line (i.e. no preceding non-blank characters),and inserts a tabulator stop otherwise. `\\[tab-to-tab-stop]' always inserts a tabulator stop. - COMMENTS: `--' puts a single comment. `---' draws a horizontal line for separating code segments. `----' inserts a display comment, i.e. two horizontal lines with a comment in between. `--CR' comments out code on that line. Re-hitting CR comments out following lines. `\\[vhdl-comment-uncomment-region]' comments out a region if not commented out, uncomments a region if already commented out. You are prompted for comments after object definitions (i.e. signals, variables, constants, ports) and after subprogram and process specifications if variable `vhdl-prompt-for-comments' is non-nil. Comments are automatically inserted as additional labels (e.g. after begin statements) and as help comments if `vhdl-self-insert-comments' is non-nil. Inline comments (i.e. comments after a piece of code on the same line) are indented at least to `vhdl-inline-comment-column'. Comments go at maximum to `vhdl-end-comment-column'. `\\[vhdl-electric-return]' after a space in a comment will open a new comment line. Typing beyond `vhdl-end-comment-column' in a comment automatically opens a new comment line. `\\[fill-paragraph]' re-fills multi-line comments. - INDENTATION: `\\[vhdl-electric-tab]' indents a line if at the beginning of the line. The amount of indentation is specified by variable `vhdl-basic-offset'. `\\[vhdl-indent-line]' always indents the current line (is bound to `TAB' if variable `vhdl-intelligent-tab' is nil). Indentation can be done for an entire region \(`\\[vhdl-indent-region]') or buffer (menu). Argument and port lists are indented normally \(nil) or relative to the opening parenthesis (non-nil) according to variable `vhdl-argument-list-indent'. If variable `vhdl-indent-tabs-mode' is nil, spaces are used instead of tabs. `\\[tabify]' and `\\[untabify]' allow to convert spaces to tabs and vice versa. - ALIGNMENT: The alignment functions align operators, keywords, and inline comment to beautify argument lists, port maps, etc. `\\[vhdl-align-group]' aligns a group of consecutive lines separated by blank lines. `\\[vhdl-align-noindent-region]' aligns an entire region. If variable `vhdl-align-groups' is non-nil, groups of code lines separated by empty lines are aligned individually. `\\[vhdl-align-inline-comment-group]' aligns inline comments for a group of lines, and `\\[vhdl-align-inline-comment-region]' for a region. Some templates are automatically aligned after generation if custom variable `vhdl-auto-align' is non-nil. `\\[vhdl-fixup-whitespace-region]' fixes up whitespace in a region. That is, operator symbols are surrounded by one space, and multiple spaces are eliminated. - PORT TRANSLATION: Generic and port clauses from entity or component declarations can be copied (`\\[vhdl-port-copy]') and pasted as entity and component declarations, as component instantiations and corresponding internal constants and signals, as a generic map with constants as actual parameters, and as a test bench (menu). A clause with several generic/port names on the same line can be flattened (`\\[vhdl-port-flatten]') so that only one name per line exists. Names for actual ports, instances, test benches, and design-under-test instances can be derived from existing names according to variables `vhdl-...-name'. Variables `vhdl-testbench-...' allow the insertion of additional templates into a test bench. New files are created for the test bench entity and architecture according to variable `vhdl-testbench-create-files'. See customization group `vhdl-port'. - TEST BENCH GENERATION: See PORT TRANSLATION. - KEY BINDINGS: Key bindings (`C-c ...') exist for most commands (see in menu). - VHDL MENU: All commands can be invoked from the VHDL menu. - FILE BROWSER: The speedbar allows browsing of directories and file contents. It can be accessed from the VHDL menu and is automatically opened if variable `vhdl-speedbar' is non-nil. In speedbar, open files and directories with `mouse-2' on the name and browse/rescan their contents with `mouse-2'/`S-mouse-2' on the `+'. - DESIGN HIERARCHY BROWSER: The speedbar can also be used for browsing the hierarchy of design units contained in the source files of the current directory or in the source files/directories specified for a project (see variable `vhdl-project-alist'). The speedbar can be switched between file and hierarchy browsing mode in the VHDL menu or by typing `f' and `h' in speedbar. In speedbar, open design units with `mouse-2' on the name and browse their hierarchy with `mouse-2' on the `+'. The hierarchy can be rescanned and ports directly be copied from entities by using the speedbar menu. - PROJECTS: Projects can be defined in variable `vhdl-project-alist' and a current project be selected using variable `vhdl-project' (permanently) or from the menu (temporarily). For each project, a title string (for the file headers) and source files/directories (for the hierarchy browser) can be specified. - SPECIAL MENUES: As an alternative to the speedbar, an index menu can be added (set variable `vhdl-index-menu' to non-nil) or made accessible as a mouse menu (e.g. add \"(global-set-key '[S-down-mouse-3] 'imenu)\" to your start-up file) for browsing the file contents. Also, a source file menu can be added (set variable `vhdl-source-file-menu' to non-nil) for browsing the current directory for VHDL source files. - SOURCE FILE COMPILATION: The syntax of the current buffer can be analyzed by calling a VHDL compiler (menu, `\\[vhdl-compile]'). The compiler to be used is specified by variable `vhdl-compiler'. The available compilers are listed in variable `vhdl-compiler-alist' including all required compilation command, destination directory, and error message syntax information. New compilers can be added. Additional compile command options can be set in variable `vhdl-compiler-options'. An entire hierarchy of source files can be compiled by the `make' command \(menu, `\\[vhdl-make]'). This only works if an appropriate Makefile exists. The make command itself as well as a command to generate a Makefile can also be specified in variable `vhdl-compiler-alist'. - VHDL STANDARDS: The VHDL standards to be used are specified in variable `vhdl-standard'. Available standards are: VHDL'87/'93, VHDL-AMS, Math Packages. - KEYWORD CASE: Lower and upper case for keywords and standardized types, attributes, and enumeration values is supported. If the variable `vhdl-upper-case-keywords' is set to non-nil, keywords can be typed in lower case and are converted into upper case automatically (not for types, attributes, and enumeration values). The case of keywords, types, attributes,and enumeration values can be fixed for an entire region (menu) or buffer (`\\[vhdl-fix-case-buffer]') according to the variables `vhdl-upper-case-{keywords,types,attributes,enum-values}'. - HIGHLIGHTING (fontification): Keywords and standardized types, attributes, enumeration values, and function names (controlled by variable `vhdl-highlight-keywords'), as well as comments, strings, and template prompts are highlighted using different colors. Unit, subprogram, signal, variable, constant, parameter and generic/port names in declarations as well as labels are highlighted if variable `vhdl-highlight-names' is non-nil. Additional reserved words or words with a forbidden syntax (e.g. words that should be avoided) can be specified in variable `vhdl-forbidden-words' or `vhdl-forbidden-syntax' and be highlighted in a warning color (variable `vhdl-highlight-forbidden-words'). Verilog keywords are highlighted as forbidden words if variable `vhdl-highlight-verilog-keywords' is non-nil. Words with special syntax can be highlighted by specifying their syntax and color in variable `vhdl-special-syntax-alist' and by setting variable `vhdl-highlight-special-words' to non-nil. This allows to establish some naming conventions (e.g. to distinguish different kinds of signals or other objects by using name suffices) and to support them visually. Variable `vhdl-highlight-case-sensitive' can be set to non-nil in order to support case-sensitive highlighting. However, keywords are then only highlighted if written in lower case. Code between \"translate_off\" and \"translate_on\" pragmas is highlighted using a different background color if variable `vhdl-highlight-translate-off' is non-nil. All colors can be customized by command `\\[customize-face]'. For highlighting of matching parenthesis, see customization group `paren-showing' (`\\[customize-group]'). - USER MODELS: VHDL models (templates) can be specified by the user and made accessible in the menu, through key bindings (`C-c C-m ...'), or by keyword electrification. See custom variable `vhdl-model-alist'. - HIDE/SHOW: The code of entire VHDL design units can be hidden using the `Hide/Show' menu or by pressing `S-mouse-2' within the code (variable `vhdl-hideshow-menu'). - PRINTING: Postscript printing with different faces (an optimized set of faces is used if `vhdl-print-customize-faces' is non-nil) or colors \(if `ps-print-color-p' is non-nil) is possible using the standard Emacs postscript printing commands. Variable `vhdl-print-two-column' defines appropriate default settings for nice landscape two-column printing. The paper format can be set by variable `ps-paper-type'. Do not forget to switch `ps-print-color-p' to nil for printing on black-and-white printers. - CUSTOMIZATION: All variables can easily be customized using the `Customize' menu entry or `\\[customize-option]' (`\\[customize-group]' for groups). Some customizations only take effect after some action (read the NOTE in the variable documentation). Customization can also be done globally (i.e. site-wide, read the INSTALL file). - FILE EXTENSIONS: As default, files with extensions \".vhd\" and \".vhdl\" are automatically recognized as VHDL source files. To add an extension \".xxx\", add the following line to your Emacs start-up file (`.emacs'): \(setq auto-mode-alist (cons '(\"\\\\.xxx\\\\'\" . vhdl-mode) auto-mode-alist)) - HINTS: - Type `\\[keyboard-quit] \\[keyboard-quit]' to interrupt long operations or if Emacs hangs. Maintenance: ------------ To submit a bug report, enter `\\[vhdl-submit-bug-report]' within VHDL Mode. Add a description of the problem and include a reproducible test case. Questions and enhancement requests can be sent to <vhdl-mode@geocities.com>. The `vhdl-mode-announce' mailing list informs about new VHDL Mode releases. The `vhdl-mode-victims' mailing list informs about new VHDL Mode beta releases. You are kindly invited to participate in beta testing. Subscribe to above mailing lists by sending an email to <vhdl-mode@geocities.com>. VHDL Mode is officially distributed on the Emacs VHDL Mode Home Page <http://www.geocities.com/SiliconValley/Peaks/8287>, where the latest version and release notes can be found. Bugs and Limitations: --------------------- - Re-indenting large regions or expressions can be slow. - Indentation bug in simultaneous if- and case-statements (VHDL-AMS). - Hideshow does not work under XEmacs. - Index menu and file tagging in speedbar do not work under XEmacs. - Parsing compilation error messages for Ikos and Viewlogic VHDL compilers does not work under XEmacs. The VHDL Mode Maintainers Reto Zimmermann and Rod Whitby Key bindings: ------------- \\{vhdl-mode-map}" (interactive) (kill-all-local-variables) (setq major-mode 'vhdl-mode) (setq mode-name "VHDL") ;; set maps and tables (use-local-map vhdl-mode-map) (set-syntax-table vhdl-mode-syntax-table) (setq local-abbrev-table vhdl-mode-abbrev-table) ;; set local variable values (set (make-local-variable 'paragraph-start) "\\s-*\\(--+\\s-*$\\|[^ -]\\|$\\)") (set (make-local-variable 'paragraph-separate) paragraph-start) (set (make-local-variable 'paragraph-ignore-fill-prefix) t) (set (make-local-variable 'require-final-newline) t) (set (make-local-variable 'parse-sexp-ignore-comments) t) (set (make-local-variable 'indent-line-function) 'vhdl-indent-line) (set (make-local-variable 'comment-start) "--") (set (make-local-variable 'comment-end) "") (set (make-local-variable 'comment-column) vhdl-inline-comment-column) (set (make-local-variable 'end-comment-column) vhdl-end-comment-column) (set (make-local-variable 'comment-start-skip) "--+\\s-*") (set (make-local-variable 'comment-multi-line) nil) (set (make-local-variable 'indent-tabs-mode) vhdl-indent-tabs-mode) (set (make-local-variable 'hippie-expand-only-buffers) '(vhdl-mode)) (set (make-local-variable 'hippie-expand-verbose) nil) ;; setup the comment indent variable in a Emacs version portable way ;; ignore any byte compiler warnings you might get here (when (boundp 'comment-indent-function) (make-local-variable 'comment-indent-function) (setq comment-indent-function 'vhdl-comment-indent)) ;; initialize font locking (require 'font-lock) (set (make-local-variable 'font-lock-defaults) (list 'vhdl-font-lock-keywords nil (not vhdl-highlight-case-sensitive) '((?\_ . "w")) 'beginning-of-line '(font-lock-syntactic-keywords . vhdl-font-lock-syntactic-keywords))) (set (make-local-variable 'font-lock-support-mode) 'lazy-lock-mode) (set (make-local-variable 'lazy-lock-defer-contextually) nil) (set (make-local-variable 'lazy-lock-defer-on-the-fly) t) ; (set (make-local-variable 'lazy-lock-defer-time) 0.1) (set (make-local-variable 'lazy-lock-defer-on-scrolling) t) (turn-on-font-lock) ;; variables for source file compilation (require 'compile) (set (make-local-variable 'compilation-error-regexp-alist) nil) (set (make-local-variable 'compilation-file-regexp-alist) nil) ;; add index menu (vhdl-index-menu-init) ;; add source file menu (if vhdl-source-file-menu (vhdl-add-source-files-menu)) ;; add VHDL menu (easy-menu-add vhdl-mode-menu-list) ; for XEmacs (easy-menu-define vhdl-mode-menu vhdl-mode-map "Menu keymap for VHDL Mode." vhdl-mode-menu-list) ;; initialize hideshow and add menu (make-local-variable 'hs-minor-mode-hook) (vhdl-hideshow-init) (run-hooks 'menu-bar-update-hook) ;; add speedbar (when (fboundp 'speedbar) (condition-case () ; due to bug in `speedbar-el' v0.7.2a (progn (when (and vhdl-speedbar (not (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame)))) (speedbar-frame-mode 1) (select-frame speedbar-attached-frame))) (error (vhdl-add-warning "Before using Speedbar, install included `speedbar.el' patch")))) ;; miscellaneous (vhdl-ps-print-init) (vhdl-modify-date-init) (vhdl-mode-line-update) (message "VHDL Mode %s. Type C-c C-h for documentation." vhdl-version) (vhdl-print-warnings) ;; run hooks (run-hooks 'vhdl-mode-hook)) (defun vhdl-activate-customizations () "Activate all customizations on local variables." (interactive) (vhdl-mode-map-init) (use-local-map vhdl-mode-map) (set-syntax-table vhdl-mode-syntax-table) (setq comment-column vhdl-inline-comment-column) (setq end-comment-column vhdl-end-comment-column) (vhdl-modify-date-init) (vhdl-update-mode-menu) (vhdl-hideshow-init) (run-hooks 'menu-bar-update-hook) (vhdl-mode-line-update)) (defun vhdl-modify-date-init () "Add/remove hook for modifying date when buffer is saved." (if vhdl-modify-date-on-saving (add-hook 'local-write-file-hooks 'vhdl-template-modify-noerror) (remove-hook 'local-write-file-hooks 'vhdl-template-modify-noerror))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Documentation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar vhdl-doc-keywords nil "Reserved words in VHDL: VHDL'93 (IEEE Std 1076-1993): `vhdl-93-keywords' : keywords `vhdl-93-types' : standardized types `vhdl-93-attributes' : standardized attributes `vhdl-93-enum-values' : standardized enumeration values `vhdl-93-functions' : standardized functions `vhdl-93-packages' : standardized packages and libraries VHDL-AMS (IEEE Std 1076.1): `vhdl-ams-keywords' : keywords `vhdl-ams-types' : standardized types `vhdl-ams-attributes' : standardized attributes `vhdl-ams-enum-values' : standardized enumeration values `vhdl-ams-functions' : standardized functions Math Packages (IEEE Std 1076.2): `vhdl-math-types' : standardized types `vhdl-math-constants' : standardized constants `vhdl-math-functions' : standardized functions `vhdl-math-packages' : standardized packages Forbidden words: `vhdl-verilog-keywords' : Verilog reserved words NOTE: click `mouse-2' on variable names above (not in XEmacs).") (defvar vhdl-doc-coding-style nil "For VHDL coding style and naming convention guidelines, see the following references: \[1] Ben Cohen. \"VHDL Coding Styles and Methodologies\". Kluwer Academic Publishers, 1999. http://members.aol.com/vhdlcohen/vhdl/ \[2] Michael Keating and Pierre Bricaud. \"Reuse Methodology Manual\". Kluwer Academic Publishers, 1998. http://www.synopsys.com/products/reuse/rmm.html \[3] European Space Agency. \"VHDL Modelling Guidelines\". ftp://ftp.estec.esa.nl/pub/vhdl/doc/ModelGuide.{pdf,ps} Use variables `vhdl-highlight-special-words' and `vhdl-special-syntax-alist' to visually support naming conventions.") (defun vhdl-doc-variable (variable) "Display VARIABLE's documentation in *Help* buffer." (interactive) (with-output-to-temp-buffer "*Help*" (princ (documentation-property variable 'variable-documentation)) (unless (string-match "XEmacs" emacs-version) (help-setup-xref (list #'vhdl-doc-variable variable) (interactive-p))) (save-excursion (set-buffer standard-output) (help-mode)) (print-help-return-message))) (defun vhdl-doc-mode () "Display VHDL mode documentation in *Help* buffer." (interactive) (with-output-to-temp-buffer "*Help*" (princ mode-name) (princ " mode:\n") (princ (documentation 'vhdl-mode)) (unless (string-match "XEmacs" emacs-version) (help-setup-xref (list #'vhdl-doc-mode) (interactive-p))) (save-excursion (set-buffer standard-output) (help-mode)) (print-help-return-message))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Keywords and standardized words ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defconst vhdl-93-keywords '( "abs" "access" "after" "alias" "all" "and" "architecture" "array" "assert" "attribute" "begin" "block" "body" "buffer" "bus" "case" "component" "configuration" "constant" "disconnect" "downto" "else" "elsif" "end" "entity" "exit" "file" "for" "function" "generate" "generic" "group" "guarded" "if" "impure" "in" "inertial" "inout" "is" "label" "library" "linkage" "literal" "loop" "map" "mod" "nand" "new" "next" "nor" "not" "null" "of" "on" "open" "or" "others" "out" "package" "port" "postponed" "procedure" "process" "pure" "range" "record" "register" "reject" "rem" "report" "return" "rol" "ror" "select" "severity" "shared" "signal" "sla" "sll" "sra" "srl" "subtype" "then" "to" "transport" "type" "unaffected" "units" "until" "use" "variable" "wait" "when" "while" "with" "xnor" "xor" ) "List of VHDL'93 keywords.") (defconst vhdl-ams-keywords '( "across" "break" "limit" "nature" "noise" "procedural" "quantity" "reference" "spectrum" "subnature" "terminal" "through" "tolerance" ) "List of VHDL-AMS keywords.") (defconst vhdl-verilog-keywords '( "`define" "`else" "`endif" "`ifdef" "`include" "`timescale" "`undef" "always" "and" "assign" "begin" "buf" "bufif0" "bufif1" "case" "casex" "casez" "cmos" "deassign" "default" "defparam" "disable" "edge" "else" "end" "endattribute" "endcase" "endfunction" "endmodule" "endprimitive" "endspecify" "endtable" "endtask" "event" "for" "force" "forever" "fork" "function" "highz0" "highz1" "if" "initial" "inout" "input" "integer" "join" "large" "macromodule" "makefile" "medium" "module" "nand" "negedge" "nmos" "nor" "not" "notif0" "notif1" "or" "output" "parameter" "pmos" "posedge" "primitive" "pull0" "pull1" "pulldown" "pullup" "rcmos" "real" "realtime" "reg" "release" "repeat" "rnmos" "rpmos" "rtran" "rtranif0" "rtranif1" "scalared" "signed" "small" "specify" "specparam" "strength" "strong0" "strong1" "supply" "supply0" "supply1" "table" "task" "time" "tran" "tranif0" "tranif1" "tri" "tri0" "tri1" "triand" "trior" "trireg" "vectored" "wait" "wand" "weak0" "weak1" "while" "wire" "wor" "xnor" "xor" ) "List of Verilog keywords as candidate for additional reserved words.") (defconst vhdl-93-types '( "boolean" "bit" "bit_vector" "character" "severity_level" "integer" "real" "time" "natural" "positive" "string" "line" "text" "side" "unsigned" "signed" "delay_length" "file_open_kind" "file_open_status" "std_logic" "std_logic_vector" "std_ulogic" "std_ulogic_vector" ) "List of VHDL'93 standardized types.") (defconst vhdl-ams-types '( "domain_type" "real_vector" ) "List of VHDL-AMS standardized types.") (defconst vhdl-math-types '( "complex" "complex_polar" ) "List of Math Packages standardized types.") (defconst vhdl-93-attributes '( "base" "left" "right" "high" "low" "pos" "val" "succ" "pred" "leftof" "rightof" "range" "reverse_range" "length" "delayed" "stable" "quiet" "transaction" "event" "active" "last_event" "last_active" "last_value" "driving" "driving_value" "ascending" "value" "image" "simple_name" "instance_name" "path_name" "foreign" ) "List of VHDL'93 standardized attributes.") (defconst vhdl-ams-attributes '( "across" "through" "reference" "contribution" "tolerance" "dot" "integ" "delayed" "above" "zoh" "ltf" "ztf" "ramp" "slew" ) "List of VHDL-AMS standardized attributes.") (defconst vhdl-93-enum-values '( "true" "false" "note" "warning" "error" "failure" "read_mode" "write_mode" "append_mode" "open_ok" "status_error" "name_error" "mode_error" "fs" "ps" "ns" "us" "ms" "sec" "min" "hr" "right" "left" ) "List of VHDL'93 standardized enumeration values.") (defconst vhdl-ams-enum-values '( "quiescent_domain" "time_domain" "frequency_domain" ) "List of VHDL-AMS standardized enumeration values.") (defconst vhdl-math-constants '( "math_e" "math_1_over_e" "math_pi" "math_two_pi" "math_1_over_pi" "math_half_pi" "math_q_pi" "math_3_half_pi" "math_log_of_2" "math_log_of_10" "math_log2_of_e" "math_log10_of_e" "math_sqrt2" "math_sqrt1_2" "math_sqrt_pi" "math_deg_to_rad" "math_rad_to_deg" "cbase_1" "cbase_j" "czero" ) "List of Math Packages standardized constants.") (defconst vhdl-93-functions '( "now" "resolved" "rising_edge" "falling_edge" "read" "readline" "write" "writeline" "endfile" "resize" "is_X" "std_match" "shift_left" "shift_right" "rotate_left" "rotate_right" "to_unsigned" "to_signed" "to_integer" "to_stdLogicVector" "to_stdULogic" "to_stdULogicVector" "to_bit" "to_bitVector" "to_X01" "to_X01Z" "to_UX01" "to_01" "conv_unsigned" "conv_signed" "conv_integer" "conv_std_logic_vector" "shl" "shr" "ext" "sxt" ) "List of VHDL'93 standardized functions.") (defconst vhdl-ams-functions '( "frequency" ) "List of VHDL-AMS standardized functions.") (defconst vhdl-math-functions '( "sign" "ceil" "floor" "round" "trunc" "fmax" "fmin" "uniform" "sqrt" "cbrt" "exp" "log" "sin" "cos" "tan" "arcsin" "arccos" "arctan" "sinh" "cosh" "tanh" "arcsinh" "arccosh" "arctanh" "cmplx" "complex_to_polar" "polar_to_complex" "arg" "conj" ) "List of Math Packages standardized functions.") (defconst vhdl-93-packages '( "std_logic_1164" "numeric_std" "numeric_bit" "standard" "textio" "std_logic_arith" "std_logic_signed" "std_logic_unsigned" "std_logic_misc" "std_logic_textio" "ieee" "std" "work" ) "List of VHDL'93 standardized packages and libraries.") (defconst vhdl-math-packages '( "math_real" "math_complex" ) "List of Math Packages standardized packages and libraries.") (defvar vhdl-keywords nil "List of VHDL keywords.") (defvar vhdl-types nil "List of VHDL standardized types.") (defvar vhdl-attributes nil "List of VHDL standardized attributes.") (defvar vhdl-enum-values nil "List of VHDL standardized enumeration values.") (defvar vhdl-constants nil "List of VHDL standardized constants.") (defvar vhdl-functions nil "List of VHDL standardized functions.") (defvar vhdl-packages nil "List of VHDL standardized packages and libraries.") (defvar vhdl-reserved-words nil "List of additional reserved words.") (defvar vhdl-keywords-regexp nil "Regexp for VHDL keywords.") (defvar vhdl-types-regexp nil "Regexp for VHDL standardized types.") (defvar vhdl-attributes-regexp nil "Regexp for VHDL standardized attributes.") (defvar vhdl-enum-values-regexp nil "Regexp for VHDL standardized enumeration values.") (defvar vhdl-functions-regexp nil "Regexp for VHDL standardized functions.") (defvar vhdl-packages-regexp nil "Regexp for VHDL standardized packages and libraries.") (defvar vhdl-reserved-words-regexp nil "Regexp for additional reserved words.") (defun vhdl-words-init () "Initialize reserved words." (setq vhdl-keywords (append vhdl-93-keywords (when (vhdl-standard-p 'ams) vhdl-ams-keywords))) (setq vhdl-types (append vhdl-93-types (when (vhdl-standard-p 'ams) vhdl-ams-types) (when (vhdl-standard-p 'math) vhdl-math-types))) (setq vhdl-attributes (append vhdl-93-attributes (when (vhdl-standard-p 'ams) vhdl-ams-attributes))) (setq vhdl-enum-values (append vhdl-93-enum-values (when (vhdl-standard-p 'ams) vhdl-ams-enum-values))) (setq vhdl-constants (append (when (vhdl-standard-p 'math) vhdl-math-constants))) (setq vhdl-functions (append vhdl-93-functions (when (vhdl-standard-p 'ams) vhdl-ams-functions) (when (vhdl-standard-p 'math) vhdl-math-functions))) (setq vhdl-packages (append vhdl-93-packages (when (vhdl-standard-p 'math) vhdl-math-packages))) (setq vhdl-reserved-words (append (when vhdl-highlight-forbidden-words vhdl-forbidden-words) (when vhdl-highlight-verilog-keywords vhdl-verilog-keywords) '(""))) (setq vhdl-keywords-regexp (concat "\\<\\(" (regexp-opt vhdl-keywords) "\\)\\>")) (setq vhdl-types-regexp (concat "\\<\\(" (regexp-opt vhdl-types) "\\)\\>")) (setq vhdl-attributes-regexp (concat "\\<\\(" (regexp-opt vhdl-attributes) "\\)\\>")) (setq vhdl-enum-values-regexp (concat "\\<\\(" (regexp-opt vhdl-enum-values) "\\)\\>")) (setq vhdl-functions-regexp (concat "\\<\\(" (regexp-opt vhdl-functions) "\\)\\>")) (setq vhdl-packages-regexp (concat "\\<\\(" (regexp-opt vhdl-packages) "\\)\\>")) (setq vhdl-reserved-words-regexp (concat "\\<\\(" (unless (equal vhdl-forbidden-syntax "") (concat vhdl-forbidden-syntax "\\|")) (regexp-opt vhdl-reserved-words) "\\)\\>")) (vhdl-abbrev-list-init)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Words to expand (defvar vhdl-abbrev-list nil "Predefined abbreviations for VHDL.") (defun vhdl-abbrev-list-init () (setq vhdl-abbrev-list (append (list vhdl-upper-case-keywords) vhdl-keywords (list vhdl-upper-case-types) vhdl-types (list vhdl-upper-case-attributes) vhdl-attributes (list vhdl-upper-case-enum-values) vhdl-enum-values (list vhdl-upper-case-constants) vhdl-constants (list nil) vhdl-functions (list nil) vhdl-packages))) ;; initialize reserved words for VHDL Mode (vhdl-words-init) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Syntax analysis and indentation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Syntax analysis ;; constant regular expressions for looking at various constructs (defconst vhdl-symbol-key "\\(\\w\\|\\s_\\)+" "Regexp describing a VHDL symbol. We cannot use just `word' syntax class since `_' cannot be in word class. Putting underscore in word class breaks forward word movement behavior that users are familiar with.") (defconst vhdl-case-header-key "case[( \t\n][^;=>]+[) \t\n]is" "Regexp describing a case statement header key.") (defconst vhdl-label-key (concat "\\(" vhdl-symbol-key "\\s-*:\\)[^=]") "Regexp describing a VHDL label.") ;; Macro definitions: (defmacro vhdl-point (position) "Return the value of point at certain commonly referenced POSITIONs. POSITION can be one of the following symbols: bol -- beginning of line eol -- end of line bod -- beginning of defun boi -- back to indentation eoi -- last whitespace on line ionl -- indentation of next line iopl -- indentation of previous line bonl -- beginning of next line bopl -- beginning of previous line This function does not modify point or mark." (or (and (eq 'quote (car-safe position)) (null (cdr (cdr position)))) (error "Bad buffer position requested: %s" position)) (setq position (nth 1 position)) (` (let ((here (point))) (,@ (cond ((eq position 'bol) '((beginning-of-line))) ((eq position 'eol) '((end-of-line))) ((eq position 'bod) '((save-match-data (vhdl-beginning-of-defun)))) ((eq position 'boi) '((back-to-indentation))) ((eq position 'eoi) '((end-of-line)(skip-chars-backward " \t"))) ((eq position 'bonl) '((forward-line 1))) ((eq position 'bopl) '((forward-line -1))) ((eq position 'iopl) '((forward-line -1) (back-to-indentation))) ((eq position 'ionl) '((forward-line 1) (back-to-indentation))) (t (error "Unknown buffer position requested: %s" position)) )) (prog1 (point) (goto-char here)) ;; workaround for an Emacs18 bug -- blech! Well, at least it ;; doesn't hurt for v19 (,@ nil) ))) (defmacro vhdl-safe (&rest body) "Safely execute BODY, return nil if an error occurred." (` (condition-case nil (progn (,@ body)) (error nil)))) (defmacro vhdl-add-syntax (symbol &optional relpos) "A simple macro to append the syntax in SYMBOL to the syntax list. Try to increase performance by using this macro." (` (setq vhdl-syntactic-context (cons (cons (, symbol) (, relpos)) vhdl-syntactic-context)))) (defmacro vhdl-has-syntax (symbol) "A simple macro to return check the syntax list. Try to increase performance by using this macro." (` (assoc (, symbol) vhdl-syntactic-context))) ;; Syntactic element offset manipulation: (defun vhdl-read-offset (langelem) "Read new offset value for LANGELEM from minibuffer. Return a legal value only." (let ((oldoff (format "%s" (cdr-safe (assq langelem vhdl-offsets-alist)))) (errmsg "Offset must be int, func, var, or one of +, -, ++, --: ") (prompt "Offset: ") offset input interned) (while (not offset) (setq input (read-string prompt oldoff) offset (cond ((string-equal "+" input) '+) ((string-equal "-" input) '-) ((string-equal "++" input) '++) ((string-equal "--" input) '--) ((string-match "^-?[0-9]+$" input) (string-to-int input)) ((fboundp (setq interned (intern input))) interned) ((boundp interned) interned) ;; error, but don't signal one, keep trying ;; to read an input value (t (ding) (setq prompt errmsg) nil)))) offset)) (defun vhdl-set-offset (symbol offset &optional add-p) "Change the value of a syntactic element symbol in `vhdl-offsets-alist'. SYMBOL is the syntactic element symbol to change and OFFSET is the new offset for that syntactic element. Optional ADD says to add SYMBOL to `vhdl-offsets-alist' if it doesn't already appear there." (interactive (let* ((langelem (intern (completing-read (concat "Syntactic symbol to change" (if current-prefix-arg " or add" "") ": ") (mapcar (function (lambda (langelem) (cons (format "%s" (car langelem)) nil))) vhdl-offsets-alist) nil (not current-prefix-arg) ;; initial contents tries to be the last element ;; on the syntactic analysis list for the current ;; line (let* ((syntax (vhdl-get-syntactic-context)) (len (length syntax)) (ic (format "%s" (car (nth (1- len) syntax))))) ic) ))) (offset (vhdl-read-offset langelem))) (list langelem offset current-prefix-arg))) ;; sanity check offset (or (eq offset '+) (eq offset '-) (eq offset '++) (eq offset '--) (integerp offset) (fboundp offset) (boundp offset) (error "Offset must be int, func, var, or one of +, -, ++, --: %s" offset)) (let ((entry (assq symbol vhdl-offsets-alist))) (if entry (setcdr entry offset) (if add-p (setq vhdl-offsets-alist (cons (cons symbol offset) vhdl-offsets-alist)) (error "%s is not a valid syntactic symbol" symbol)))) (vhdl-keep-region-active)) (defun vhdl-set-style (style &optional local) "Set `vhdl-mode' variables to use one of several different indentation styles. STYLE is a string representing the desired style and optional LOCAL is a flag which, if non-nil, means to make the style variables being changed buffer local, instead of the default, which is to set the global variables. Interactively, the flag comes from the prefix argument. The styles are chosen from the `vhdl-style-alist' variable." (interactive (list (completing-read "Use which VHDL indentation style? " vhdl-style-alist nil t) current-prefix-arg)) (let ((vars (cdr (assoc style vhdl-style-alist)))) (or vars (error "Invalid VHDL indentation style `%s'" style)) ;; set all the variables (mapcar (function (lambda (varentry) (let ((var (car varentry)) (val (cdr varentry))) (and local (make-local-variable var)) ;; special case for vhdl-offsets-alist (if (not (eq var 'vhdl-offsets-alist)) (set var val) ;; reset vhdl-offsets-alist to the default value first (setq vhdl-offsets-alist (copy-alist vhdl-offsets-alist-default)) ;; now set the langelems that are different (mapcar (function (lambda (langentry) (let ((langelem (car langentry)) (offset (cdr langentry))) (vhdl-set-offset langelem offset) ))) val)) ))) vars)) (vhdl-keep-region-active)) (defun vhdl-get-offset (langelem) "Get offset from LANGELEM which is a cons cell of the form: \(SYMBOL . RELPOS). The symbol is matched against vhdl-offsets-alist and the offset found there is either returned, or added to the indentation at RELPOS. If RELPOS is nil, then the offset is simply returned." (let* ((symbol (car langelem)) (relpos (cdr langelem)) (match (assq symbol vhdl-offsets-alist)) (offset (cdr-safe match))) ;; offset can be a number, a function, a variable, or one of the ;; symbols + or - (cond ((not match) (if vhdl-strict-syntax-p (error "Don't know how to indent a %s" symbol) (setq offset 0 relpos 0))) ((eq offset '+) (setq offset vhdl-basic-offset)) ((eq offset '-) (setq offset (- vhdl-basic-offset))) ((eq offset '++) (setq offset (* 2 vhdl-basic-offset))) ((eq offset '--) (setq offset (* 2 (- vhdl-basic-offset)))) ((and (not (numberp offset)) (fboundp offset)) (setq offset (funcall offset langelem))) ((not (numberp offset)) (setq offset (eval offset))) ) (+ (if (and relpos (< relpos (vhdl-point 'bol))) (save-excursion (goto-char relpos) (current-column)) 0) offset))) ;; Syntactic support functions: ;; Returns `comment' if in a comment, `string' if in a string literal, ;; or nil if not in a literal at all. Optional LIM is used as the ;; backward limit of the search. If omitted, or nil, (point-min) is ;; used. (defun vhdl-in-literal (&optional lim) "Determine if point is in a VHDL literal." (save-excursion (let ((state (parse-partial-sexp (vhdl-point 'bol) (point)))) (cond ((nth 3 state) 'string) ((nth 4 state) 'comment) (t nil))))) ;; This is the best we can do in Win-Emacs. (defun vhdl-win-il (&optional lim) "Determine if point is in a VHDL literal." (save-excursion (let* ((here (point)) (state nil) (match nil) (lim (or lim (vhdl-point 'bod)))) (goto-char lim ) (while (< (point) here) (setq match (and (re-search-forward "--\\|[\"']" here 'move) (buffer-substring (match-beginning 0) (match-end 0)))) (setq state (cond ;; no match ((null match) nil) ;; looking at the opening of a VHDL style comment ((string= "--" match) (if (<= here (progn (end-of-line) (point))) 'comment)) ;; looking at the opening of a double quote string ((string= "\"" match) (if (not (save-restriction ;; this seems to be necessary since the ;; re-search-forward will not work without it (narrow-to-region (point) here) (re-search-forward ;; this regexp matches a double quote ;; which is preceded by an even number ;; of backslashes, including zero "\\([^\\]\\|^\\)\\(\\\\\\\\\\)*\"" here 'move))) 'string)) ;; looking at the opening of a single quote string ((string= "'" match) (if (not (save-restriction ;; see comments from above (narrow-to-region (point) here) (re-search-forward ;; this matches a single quote which is ;; preceded by zero or two backslashes. "\\([^\\]\\|^\\)\\(\\\\\\\\\\)?'" here 'move))) 'string)) (t nil))) ) ; end-while state))) (and (string-match "Win-Emacs" emacs-version) (fset 'vhdl-in-literal 'vhdl-win-il)) ;; Skipping of "syntactic whitespace". Syntactic whitespace is ;; defined as lexical whitespace or comments. Search no farther back ;; or forward than optional LIM. If LIM is omitted, (point-min) is ;; used for backward skipping, (point-max) is used for forward ;; skipping. (defun vhdl-forward-syntactic-ws (&optional lim) "Forward skip of syntactic whitespace." (save-restriction (let* ((lim (or lim (point-max))) (here lim) (hugenum (point-max))) (narrow-to-region lim (point)) (while (/= here (point)) (setq here (point)) (forward-comment hugenum)) ))) ;; This is the best we can do in Win-Emacs. (defun vhdl-win-fsws (&optional lim) "Forward skip syntactic whitespace for Win-Emacs." (let ((lim (or lim (point-max))) stop) (while (not stop) (skip-chars-forward " \t\n\r\f" lim) (cond ;; vhdl comment ((looking-at "--") (end-of-line)) ;; none of the above (t (setq stop t)) )))) (and (string-match "Win-Emacs" emacs-version) (fset 'vhdl-forward-syntactic-ws 'vhdl-win-fsws)) (defun vhdl-backward-syntactic-ws (&optional lim) "Backward skip over syntactic whitespace." (save-restriction (let* ((lim (or lim (point-min))) (here lim) (hugenum (- (point-max)))) (if (< lim (point)) (progn (narrow-to-region lim (point)) (while (/= here (point)) (setq here (point)) (forward-comment hugenum) ))) ))) ;; This is the best we can do in Win-Emacs. (defun vhdl-win-bsws (&optional lim) "Backward skip syntactic whitespace for Win-Emacs." (let ((lim (or lim (vhdl-point 'bod))) stop) (while (not stop) (skip-chars-backward " \t\n\r\f" lim) (cond ;; vhdl comment ((eq (vhdl-in-literal lim) 'comment) (skip-chars-backward "^-" lim) (skip-chars-backward "-" lim) (while (not (or (and (= (following-char) ?-) (= (char-after (1+ (point))) ?-)) (<= (point) lim))) (skip-chars-backward "^-" lim) (skip-chars-backward "-" lim))) ;; none of the above (t (setq stop t)) )))) (and (string-match "Win-Emacs" emacs-version) (fset 'vhdl-backward-syntactic-ws 'vhdl-win-bsws)) ;; Functions to help finding the correct indentation column: (defun vhdl-first-word (point) "If the keyword at POINT is at boi, then return (current-column) at that point, else nil." (save-excursion (and (goto-char point) (eq (point) (vhdl-point 'boi)) (current-column)))) (defun vhdl-last-word (point) "If the keyword at POINT is at eoi, then return (current-column) at that point, else nil." (save-excursion (and (goto-char point) (save-excursion (or (eq (progn (forward-sexp) (point)) (vhdl-point 'eoi)) (looking-at "\\s-*\\(--\\)?"))) (current-column)))) ;; Core syntactic evaluation functions: (defconst vhdl-libunit-re "\\b\\(architecture\\|configuration\\|entity\\|package\\)\\b[^_]") (defun vhdl-libunit-p () (and (save-excursion (forward-sexp) (skip-chars-forward " \t\n") (not (looking-at "is\\b[^_]"))) (save-excursion (backward-sexp) (and (not (looking-at "use\\b[^_]")) (progn (forward-sexp) (vhdl-forward-syntactic-ws) (/= (following-char) ?:)))) )) (defconst vhdl-defun-re "\\b\\(architecture\\|block\\|configuration\\|entity\\|package\\|process\\|procedural\\|procedure\\|function\\)\\b[^_]") (defun vhdl-defun-p () (save-excursion (if (looking-at "block\\|process\\|procedural") ;; "block", "process", "procedural": (save-excursion (backward-sexp) (not (looking-at "end\\s-+\\w"))) ;; "architecture", "configuration", "entity", ;; "package", "procedure", "function": t))) (defun vhdl-corresponding-defun () "If the word at the current position corresponds to a \"defun\" keyword, then return a string that can be used to find the corresponding \"begin\" keyword, else return nil." (save-excursion (and (looking-at vhdl-defun-re) (vhdl-defun-p) (if (looking-at "block\\|process\\|procedural") ;; "block", "process". "procedural: (buffer-substring (match-beginning 0) (match-end 0)) ;; "architecture", "configuration", "entity", "package", ;; "procedure", "function": "is")))) (defconst vhdl-begin-fwd-re "\\b\\(is\\|begin\\|block\\|component\\|generate\\|then\\|else\\|loop\\|process\\|procedural\\|units\\|record\\|for\\)\\b\\([^_]\\|\\'\\)" "A regular expression for searching forward that matches all known \"begin\" keywords.") (defconst vhdl-begin-bwd-re "\\b\\(is\\|begin\\|block\\|component\\|generate\\|then\\|else\\|loop\\|process\\|procedural\\|units\\|record\\|for\\)\\b[^_]" "A regular expression for searching backward that matches all known \"begin\" keywords.") (defun vhdl-begin-p (&optional lim) "Return t if we are looking at a real \"begin\" keyword. Assumes that the caller will make sure that we are looking at vhdl-begin-fwd-re, and are not inside a literal, and that we are not in the middle of an identifier that just happens to contain a \"begin\" keyword." (cond ;; "[architecture|case|configuration|entity|package| ;; procedure|function] ... is": ((and (looking-at "i") (save-excursion ;; Skip backward over first sexp (needed to skip over a ;; procedure interface list, and is harmless in other ;; situations). Note that we need "return" in the ;; following search list so that we don't run into ;; semicolons in the function interface list. (backward-sexp) (let (foundp) (while (and (not foundp) (re-search-backward ";\\|\\b\\(architecture\\|case\\|configuration\\|entity\\|package\\|procedure\\|return\\|is\\|begin\\|process\\|procedural\\|block\\)\\b[^_]" lim 'move)) (if (or (= (preceding-char) ?_) (vhdl-in-literal lim)) (backward-char) (setq foundp t)))) (and (/= (following-char) ?\;) (not (looking-at "is\\|begin\\|process\\|procedural\\|block"))))) t) ;; "begin", "then": ((looking-at "be\\|t") t) ;; "else": ((and (looking-at "e") ;; make sure that the "else" isn't inside a ;; conditional signal assignment. (save-excursion (re-search-backward ";\\|\\bwhen\\b[^_]" lim 'move) (or (eq (following-char) ?\;) (eq (point) lim)))) t) ;; "block", "generate", "loop", "process", "procedural", ;; "units", "record": ((and (looking-at "bl\\|[glpur]") (save-excursion (backward-sexp) (not (looking-at "end\\s-+\\w")))) t) ;; "component": ((and (looking-at "c") (save-excursion (backward-sexp) (not (looking-at "end\\s-+\\w"))) ;; look out for the dreaded entity class in an attribute (save-excursion (vhdl-backward-syntactic-ws lim) (/= (preceding-char) ?:))) t) ;; "for" (inside configuration declaration): ((and (looking-at "f") (save-excursion (backward-sexp) (not (looking-at "end\\s-+\\w"))) (vhdl-has-syntax 'configuration)) t) )) (defun vhdl-corresponding-mid (&optional lim) (cond ((looking-at "is\\|block\\|generate\\|process\\|procedural") "begin") ((looking-at "then") "<else>") (t "end"))) (defun vhdl-corresponding-end (&optional lim) "If the word at the current position corresponds to a \"begin\" keyword, then return a vector containing enough information to find the corresponding \"end\" keyword, else return nil. The keyword to search forward for is aref 0. The column in which the keyword must appear is aref 1 or nil if any column is suitable. Assumes that the caller will make sure that we are not in the middle of an identifier that just happens to contain a \"begin\" keyword." (save-excursion (and (looking-at vhdl-begin-fwd-re) (/= (preceding-char) ?_) (not (vhdl-in-literal lim)) (vhdl-begin-p lim) (cond ;; "is", "generate", "loop": ((looking-at "[igl]") (vector "end" (and (vhdl-last-word (point)) (or (vhdl-first-word (point)) (save-excursion (vhdl-beginning-of-statement-1 lim) (vhdl-backward-skip-label lim) (vhdl-first-word (point))))))) ;; "begin", "else", "for": ((looking-at "be\\|[ef]") (vector "end" (and (vhdl-last-word (point)) (or (vhdl-first-word (point)) (save-excursion (vhdl-beginning-of-statement-1 lim) (vhdl-backward-skip-label lim) (vhdl-first-word (point))))))) ;; "component", "units", "record": ((looking-at "[cur]") ;; The first end found will close the block (vector "end" nil)) ;; "block", "process", "procedural": ((looking-at "bl\\|p") (vector "end" (or (vhdl-first-word (point)) (save-excursion (vhdl-beginning-of-statement-1 lim) (vhdl-backward-skip-label lim) (vhdl-first-word (point)))))) ;; "then": ((looking-at "t") (vector "elsif\\|else\\|end\\s-+if" (and (vhdl-last-word (point)) (or (vhdl-first-word (point)) (save-excursion (vhdl-beginning-of-statement-1 lim) (vhdl-backward-skip-label lim) (vhdl-first-word (point))))))) )))) (defconst vhdl-end-fwd-re "\\b\\(end\\|else\\|elsif\\)\\b\\([^_]\\|\\'\\)") (defconst vhdl-end-bwd-re "\\b\\(end\\|else\\|elsif\\)\\b[^_]") (defun vhdl-end-p (&optional lim) "Return t if we are looking at a real \"end\" keyword. Assumes that the caller will make sure that we are looking at vhdl-end-fwd-re, and are not inside a literal, and that we are not in the middle of an identifier that just happens to contain an \"end\" keyword." (or (not (looking-at "else")) ;; make sure that the "else" isn't inside a conditional signal ;; assignment. (save-excursion (re-search-backward ";\\|\\bwhen\\b[^_]" lim 'move) (or (eq (following-char) ?\;) (eq (point) lim))))) (defun vhdl-corresponding-begin (&optional lim) "If the word at the current position corresponds to an \"end\" keyword, then return a vector containing enough information to find the corresponding \"begin\" keyword, else return nil. The keyword to search backward for is aref 0. The column in which the keyword must appear is aref 1 or nil if any column is suitable. The supplementary keyword to search forward for is aref 2 or nil if this is not required. If aref 3 is t, then the \"begin\" keyword may be found in the middle of a statement. Assumes that the caller will make sure that we are not in the middle of an identifier that just happens to contain an \"end\" keyword." (save-excursion (let (pos) (if (and (looking-at vhdl-end-fwd-re) (not (vhdl-in-literal lim)) (vhdl-end-p lim)) (if (looking-at "el") ;; "else", "elsif": (vector "if\\|elsif" (vhdl-first-word (point)) "then" nil) ;; "end ...": (setq pos (point)) (forward-sexp) (skip-chars-forward " \t\n") (cond ;; "end if": ((looking-at "if\\b[^_]") (vector "else\\|elsif\\|if" (vhdl-first-word pos) "else\\|then" nil)) ;; "end component": ((looking-at "component\\b[^_]") (vector (buffer-substring (match-beginning 1) (match-end 1)) (vhdl-first-word pos) nil nil)) ;; "end units", "end record": ((looking-at "\\(units\\|record\\)\\b[^_]") (vector (buffer-substring (match-beginning 1) (match-end 1)) (vhdl-first-word pos) nil t)) ;; "end block", "end process", "end procedural": ((looking-at "\\(block\\|process\\|procedural\\)\\b[^_]") (vector "begin" (vhdl-first-word pos) nil nil)) ;; "end case": ((looking-at "case\\b[^_]") (vector "case" (vhdl-first-word pos) "is" nil)) ;; "end generate": ((looking-at "generate\\b[^_]") (vector "generate\\|for\\|if" (vhdl-first-word pos) "generate" nil)) ;; "end loop": ((looking-at "loop\\b[^_]") (vector "loop\\|while\\|for" (vhdl-first-word pos) "loop" nil)) ;; "end for" (inside configuration declaration): ((looking-at "for\\b[^_]") (vector "for" (vhdl-first-word pos) nil nil)) ;; "end [id]": (t (vector "begin\\|architecture\\|configuration\\|entity\\|package\\|procedure\\|function" (vhdl-first-word pos) ;; return an alist of (statement . keyword) mappings '( ;; "begin ... end [id]": ("begin" . nil) ;; "architecture ... is ... begin ... end [id]": ("architecture" . "is") ;; "configuration ... is ... end [id]": ("configuration" . "is") ;; "entity ... is ... end [id]": ("entity" . "is") ;; "package ... is ... end [id]": ("package" . "is") ;; "procedure ... is ... begin ... end [id]": ("procedure" . "is") ;; "function ... is ... begin ... end [id]": ("function" . "is") ) nil)) ))) ; "end ..." ))) (defconst vhdl-leader-re "\\b\\(block\\|component\\|process\\|procedural\\|for\\)\\b[^_]") (defun vhdl-end-of-leader () (save-excursion (cond ((looking-at "block\\|process\\|procedural") (if (save-excursion (forward-sexp) (skip-chars-forward " \t\n") (= (following-char) ?\()) (forward-sexp 2) (forward-sexp)) (point)) ((looking-at "component") (forward-sexp 2) (point)) ((looking-at "for") (forward-sexp 2) (skip-chars-forward " \t\n") (while (looking-at "[,:(]") (forward-sexp) (skip-chars-forward " \t\n")) (point)) (t nil) ))) (defconst vhdl-trailer-re "\\b\\(is\\|then\\|generate\\|loop\\)\\b[^_]") (defconst vhdl-statement-fwd-re "\\b\\(if\\|for\\|while\\)\\b\\([^_]\\|\\'\\)" "A regular expression for searching forward that matches all known \"statement\" keywords.") (defconst vhdl-statement-bwd-re "\\b\\(if\\|for\\|while\\)\\b[^_]" "A regular expression for searching backward that matches all known \"statement\" keywords.") (defun vhdl-statement-p (&optional lim) "Return t if we are looking at a real \"statement\" keyword. Assumes that the caller will make sure that we are looking at vhdl-statement-fwd-re, and are not inside a literal, and that we are not in the middle of an identifier that just happens to contain a \"statement\" keyword." (cond ;; "for" ... "generate": ((and (looking-at "f") ;; Make sure it's the start of a parameter specification. (save-excursion (forward-sexp 2) (skip-chars-forward " \t\n") (looking-at "in\\b[^_]")) ;; Make sure it's not an "end for". (save-excursion (backward-sexp) (not (looking-at "end\\s-+\\w")))) t) ;; "if" ... "then", "if" ... "generate", "if" ... "loop": ((and (looking-at "i") ;; Make sure it's not an "end if". (save-excursion (backward-sexp) (not (looking-at "end\\s-+\\w")))) t) ;; "while" ... "loop": ((looking-at "w") t) )) (defconst vhdl-case-alternative-re "when[( \t\n][^;=>]+=>" "Regexp describing a case statement alternative key.") (defun vhdl-case-alternative-p (&optional lim) "Return t if we are looking at a real case alternative. Assumes that the caller will make sure that we are looking at vhdl-case-alternative-re, and are not inside a literal, and that we are not in the middle of an identifier that just happens to contain a \"when\" keyword." (save-excursion (let (foundp) (while (and (not foundp) (re-search-backward ";\\|<=" lim 'move)) (if (or (= (preceding-char) ?_) (vhdl-in-literal lim)) (backward-char) (setq foundp t))) (or (eq (following-char) ?\;) (eq (point) lim))) )) ;; Core syntactic movement functions: (defconst vhdl-b-t-b-re (concat vhdl-begin-bwd-re "\\|" vhdl-end-bwd-re)) (defun vhdl-backward-to-block (&optional lim) "Move backward to the previous \"begin\" or \"end\" keyword." (let (foundp) (while (and (not foundp) (re-search-backward vhdl-b-t-b-re lim 'move)) (if (or (= (preceding-char) ?_) (vhdl-in-literal lim)) (backward-char) (cond ;; "begin" keyword: ((and (looking-at vhdl-begin-fwd-re) (/= (preceding-char) ?_) (vhdl-begin-p lim)) (setq foundp 'begin)) ;; "end" keyword: ((and (looking-at vhdl-end-fwd-re) (/= (preceding-char) ?_) (vhdl-end-p lim)) (setq foundp 'end)) )) ) foundp )) (defun vhdl-forward-sexp (&optional count lim) "Move forward across one balanced expression (sexp). With COUNT, do it that many times." (interactive "p") (let ((count (or count 1)) (case-fold-search t) end-vec target) (save-excursion (while (> count 0) ;; skip whitespace (skip-chars-forward " \t\n") ;; Check for an unbalanced "end" keyword (if (and (looking-at vhdl-end-fwd-re) (/= (preceding-char) ?_) (not (vhdl-in-literal lim)) (vhdl-end-p lim) (not (looking-at "else"))) (error "Containing expression ends prematurely in vhdl-forward-sexp")) ;; If the current keyword is a "begin" keyword, then find the ;; corresponding "end" keyword. (if (setq end-vec (vhdl-corresponding-end lim)) (let ( ;; end-re is the statement keyword to search for (end-re (concat "\\b\\(" (aref end-vec 0) "\\)\\b\\([^_]\\|\\'\\)")) ;; column is either the statement keyword target column ;; or nil (column (aref end-vec 1)) (eol (vhdl-point 'eol)) foundp literal placeholder) ;; Look for the statement keyword. (while (and (not foundp) (re-search-forward end-re nil t) (setq placeholder (match-end 1)) (goto-char (match-beginning 0))) ;; If we are in a literal, or not in the right target ;; column and not on the same line as the begin, then ;; try again. (if (or (and column (/= (current-indentation) column) (> (point) eol)) (= (preceding-char) ?_) (setq literal (vhdl-in-literal lim))) (if (eq literal 'comment) (end-of-line) (forward-char)) ;; An "else" keyword corresponds to both the opening brace ;; of the following sexp and the closing brace of the ;; previous sexp. (if (not (looking-at "else")) (goto-char placeholder)) (setq foundp t)) ) (if (not foundp) (error "Unbalanced keywords in vhdl-forward-sexp")) ) ;; If the current keyword is not a "begin" keyword, then just ;; perform the normal forward-sexp. (forward-sexp) ) (setq count (1- count)) ) (setq target (point))) (goto-char target) nil)) (defun vhdl-backward-sexp (&optional count lim) "Move backward across one balanced expression (sexp). With COUNT, do it that many times. LIM bounds any required backward searches." (interactive "p") (let ((count (or count 1)) (case-fold-search t) begin-vec target) (save-excursion (while (> count 0) ;; Perform the normal backward-sexp, unless we are looking at ;; "else" - an "else" keyword corresponds to both the opening brace ;; of the following sexp and the closing brace of the previous sexp. (if (and (looking-at "else\\b\\([^_]\\|\\'\\)") (/= (preceding-char) ?_) (not (vhdl-in-literal lim))) nil (backward-sexp) (if (and (looking-at vhdl-begin-fwd-re) (/= (preceding-char) ?_) (not (vhdl-in-literal lim)) (vhdl-begin-p lim)) (error "Containing expression ends prematurely in vhdl-backward-sexp"))) ;; If the current keyword is an "end" keyword, then find the ;; corresponding "begin" keyword. (if (and (setq begin-vec (vhdl-corresponding-begin lim)) (/= (preceding-char) ?_)) (let ( ;; begin-re is the statement keyword to search for (begin-re (concat "\\b\\(" (aref begin-vec 0) "\\)\\b[^_]")) ;; column is either the statement keyword target column ;; or nil (column (aref begin-vec 1)) ;; internal-p controls where the statement keyword can ;; be found. (internal-p (aref begin-vec 3)) (last-backward (point)) last-forward foundp literal keyword) ;; Look for the statement keyword. (while (and (not foundp) (re-search-backward begin-re lim t) (setq keyword (buffer-substring (match-beginning 1) (match-end 1)))) ;; If we are in a literal or in the wrong column, ;; then try again. (if (or (and column (and (/= (current-indentation) column) ;; possibly accept current-column as ;; well as current-indentation. (or (not internal-p) (/= (current-column) column)))) (= (preceding-char) ?_) (vhdl-in-literal lim)) (backward-char) ;; If there is a supplementary keyword, then ;; search forward for it. (if (and (setq begin-re (aref begin-vec 2)) (or (not (listp begin-re)) ;; If begin-re is an alist, then find the ;; element corresponding to the actual ;; keyword that we found. (progn (setq begin-re (assoc keyword begin-re)) (and begin-re (setq begin-re (cdr begin-re)))))) (and (setq begin-re (concat "\\b\\(" begin-re "\\)\\b[^_]")) (save-excursion (setq last-forward (point)) ;; Look for the supplementary keyword ;; (bounded by the backward search start ;; point). (while (and (not foundp) (re-search-forward begin-re last-backward t) (goto-char (match-beginning 1))) ;; If we are in a literal, then try again. (if (or (= (preceding-char) ?_) (setq literal (vhdl-in-literal last-forward))) (if (eq literal 'comment) (goto-char (min (vhdl-point 'eol) last-backward)) (forward-char)) ;; We have found the supplementary keyword. ;; Save the position of the keyword in foundp. (setq foundp (point))) ) foundp) ;; If the supplementary keyword was found, then ;; move point to the supplementary keyword. (goto-char foundp)) ;; If there was no supplementary keyword, then ;; point is already at the statement keyword. (setq foundp t))) ) ; end of the search for the statement keyword (if (not foundp) (error "Unbalanced keywords in vhdl-backward-sexp")) )) (setq count (1- count)) ) (setq target (point))) (goto-char target) nil)) (defun vhdl-backward-up-list (&optional count limit) "Move backward out of one level of blocks. With argument, do this that many times." (interactive "p") (let ((count (or count 1)) target) (save-excursion (while (> count 0) (if (looking-at vhdl-defun-re) (error "Unbalanced blocks")) (vhdl-backward-to-block limit) (setq count (1- count))) (setq target (point))) (goto-char target))) (defun vhdl-end-of-defun (&optional count) "Move forward to the end of a VHDL defun." (interactive) (let ((case-fold-search t)) (vhdl-beginning-of-defun) (if (not (looking-at "block\\|process\\|procedural")) (re-search-forward "\\bis\\b")) (vhdl-forward-sexp))) (defun vhdl-mark-defun () "Put mark at end of this \"defun\", point at beginning." (interactive) (let ((case-fold-search t)) (push-mark) (vhdl-beginning-of-defun) (push-mark) (if (not (looking-at "block\\|process\\|procedural")) (re-search-forward "\\bis\\b")) (vhdl-forward-sexp) (exchange-point-and-mark))) (defun vhdl-beginning-of-libunit () "Move backward to the beginning of a VHDL library unit. Returns the location of the corresponding begin keyword, unless search stops due to beginning or end of buffer. Note that if point is between the \"libunit\" keyword and the corresponding \"begin\" keyword, then that libunit will not be recognised, and the search will continue backwards. If point is at the \"begin\" keyword, then the defun will be recognised. The returned point is at the first character of the \"libunit\" keyword." (let ((last-forward (point)) (last-backward ;; Just in case we are actually sitting on the "begin" ;; keyword, allow for the keyword and an extra character, ;; as this will be used when looking forward for the ;; "begin" keyword. (save-excursion (forward-word 1) (1+ (point)))) foundp literal placeholder) ;; Find the "libunit" keyword. (while (and (not foundp) (re-search-backward vhdl-libunit-re nil 'move)) ;; If we are in a literal, or not at a real libunit, then try again. (if (or (= (preceding-char) ?_) (vhdl-in-literal (point-min)) (not (vhdl-libunit-p))) (backward-char) ;; Find the corresponding "begin" keyword. (setq last-forward (point)) (while (and (not foundp) (re-search-forward "\\bis\\b[^_]" last-backward t) (setq placeholder (match-beginning 0))) (if (or (= (preceding-char) ?_) (setq literal (vhdl-in-literal last-forward))) ;; It wasn't a real keyword, so keep searching. (if (eq literal 'comment) (goto-char (min (vhdl-point 'eol) last-backward)) (forward-char)) ;; We have found the begin keyword, loop will exit. (setq foundp placeholder))) ;; Go back to the libunit keyword (goto-char last-forward))) foundp)) (defun vhdl-beginning-of-defun (&optional count) "Move backward to the beginning of a VHDL defun. With argument, do it that many times. Returns the location of the corresponding begin keyword, unless search stops due to beginning or end of buffer." ;; Note that if point is between the "defun" keyword and the ;; corresponding "begin" keyword, then that defun will not be ;; recognised, and the search will continue backwards. If point is ;; at the "begin" keyword, then the defun will be recognised. The ;; returned point is at the first character of the "defun" keyword. (interactive "p") (let ((count (or count 1)) (case-fold-search t) (last-forward (point)) foundp) (while (> count 0) (setq foundp nil) (goto-char last-forward) (let ((last-backward ;; Just in case we are actually sitting on the "begin" ;; keyword, allow for the keyword and an extra character, ;; as this will be used when looking forward for the ;; "begin" keyword. (save-excursion (forward-word 1) (1+ (point)))) begin-string literal) (while (and (not foundp) (re-search-backward vhdl-defun-re nil 'move)) ;; If we are in a literal, then try again. (if (or (= (preceding-char) ?_) (vhdl-in-literal (point-min))) (backward-char) (if (setq begin-string (vhdl-corresponding-defun)) ;; This is a real defun keyword. ;; Find the corresponding "begin" keyword. ;; Look for the begin keyword. (progn ;; Save the search start point. (setq last-forward (point)) (while (and (not foundp) (search-forward begin-string last-backward t)) (if (or (= (preceding-char) ?_) (save-match-data (setq literal (vhdl-in-literal last-forward)))) ;; It wasn't a real keyword, so keep searching. (if (eq literal 'comment) (goto-char (min (vhdl-point 'eol) last-backward)) (forward-char)) ;; We have found the begin keyword, loop will exit. (setq foundp (match-beginning 0))) ) ;; Go back to the defun keyword (goto-char last-forward)) ; end search for begin keyword )) ) ; end of the search for the defun keyword ) (setq count (1- count)) ) (vhdl-keep-region-active) foundp)) (defun vhdl-beginning-of-statement (&optional count lim) "Go to the beginning of the innermost VHDL statement. With prefix arg, go back N - 1 statements. If already at the beginning of a statement then go to the beginning of the preceding one. If within a string or comment, or next to a comment (only whitespace between), move by sentences instead of statements. When called from a program, this function takes 2 optional args: the prefix arg, and a buffer position limit which is the farthest back to search." (interactive "p") (let ((count (or count 1)) (case-fold-search t) (lim (or lim (point-min))) (here (point)) state) (save-excursion (goto-char lim) (setq state (parse-partial-sexp (point) here nil nil))) (if (and (interactive-p) (or (nth 3 state) (nth 4 state) (looking-at (concat "[ \t]*" comment-start-skip)))) (forward-sentence (- count)) (while (> count 0) (vhdl-beginning-of-statement-1 lim) (setq count (1- count)))) ;; its possible we've been left up-buf of lim (goto-char (max (point) lim)) ) (vhdl-keep-region-active)) (defconst vhdl-e-o-s-re (concat ";\\|" vhdl-begin-fwd-re "\\|" vhdl-statement-fwd-re)) (defun vhdl-end-of-statement () "Very simple implementation." (interactive) (re-search-forward vhdl-e-o-s-re)) (defconst vhdl-b-o-s-re (concat ";\\|\(\\|\)\\|\\bwhen\\b[^_]\\|" vhdl-begin-bwd-re "\\|" vhdl-statement-bwd-re)) (defun vhdl-beginning-of-statement-1 (&optional lim) "Move to the start of the current statement, or the previous statement if already at the beginning of one." (let ((lim (or lim (point-min))) (here (point)) (pos (point)) donep) ;; go backwards one balanced expression, but be careful of ;; unbalanced paren being reached (if (not (vhdl-safe (progn (backward-sexp) t))) (progn (backward-up-list 1) (forward-char) (vhdl-forward-syntactic-ws here) (setq donep t))) (while (and (not donep) (not (bobp)) ;; look backwards for a statement boundary (re-search-backward vhdl-b-o-s-re lim 'move)) (if (or (= (preceding-char) ?_) (vhdl-in-literal lim)) (backward-char) (cond ;; If we are looking at an open paren, then stop after it ((eq (following-char) ?\() (forward-char) (vhdl-forward-syntactic-ws here) (setq donep t)) ;; If we are looking at a close paren, then skip it ((eq (following-char) ?\)) (forward-char) (setq pos (point)) (backward-sexp) (if (< (point) lim) (progn (goto-char pos) (vhdl-forward-syntactic-ws here) (setq donep t)))) ;; If we are looking at a semicolon, then stop ((eq (following-char) ?\;) (progn (forward-char) (vhdl-forward-syntactic-ws here) (setq donep t))) ;; If we are looking at a "begin", then stop ((and (looking-at vhdl-begin-fwd-re) (/= (preceding-char) ?_) (vhdl-begin-p nil)) ;; If it's a leader "begin", then find the ;; right place (if (looking-at vhdl-leader-re) (save-excursion ;; set a default stop point at the begin (setq pos (point)) ;; is the start point inside the leader area ? (goto-char (vhdl-end-of-leader)) (vhdl-forward-syntactic-ws here) (if (< (point) here) ;; start point was not inside leader area ;; set stop point at word after leader (setq pos (point)))) (forward-word 1) (vhdl-forward-syntactic-ws here) (setq pos (point))) (goto-char pos) (setq donep t)) ;; If we are looking at a "statement", then stop ((and (looking-at vhdl-statement-fwd-re) (/= (preceding-char) ?_) (vhdl-statement-p nil)) (setq donep t)) ;; If we are looking at a case alternative key, then stop ((and (looking-at vhdl-case-alternative-re) (vhdl-case-alternative-p lim)) (save-excursion ;; set a default stop point at the when (setq pos (point)) ;; is the start point inside the case alternative key ? (looking-at vhdl-case-alternative-re) (goto-char (match-end 0)) (vhdl-forward-syntactic-ws here) (if (< (point) here) ;; start point was not inside the case alternative key ;; set stop point at word after case alternative keyleader (setq pos (point)))) (goto-char pos) (setq donep t)) ;; Bogus find, continue (t (backward-char))))) )) ;; Defuns for calculating the current syntactic state: (defun vhdl-get-library-unit (bod placeholder) "If there is an enclosing library unit at bod, with it's \"begin\" keyword at placeholder, then return the library unit type." (let ((here (vhdl-point 'bol))) (if (save-excursion (goto-char placeholder) (vhdl-safe (vhdl-forward-sexp 1 bod)) (<= here (point))) (save-excursion (goto-char bod) (cond ((looking-at "e") 'entity) ((looking-at "a") 'architecture) ((looking-at "c") 'configuration) ((looking-at "p") (save-excursion (goto-char bod) (forward-sexp) (vhdl-forward-syntactic-ws here) (if (looking-at "body\\b[^_]") 'package-body 'package)))))) )) (defun vhdl-get-block-state (&optional lim) "Finds and records all the closest opens. lim is the furthest back we need to search (it should be the previous libunit keyword)." (let ((here (point)) (lim (or lim (point-min))) keyword sexp-start sexp-mid sexp-end preceding-sexp containing-sexp containing-begin containing-mid containing-paren) (save-excursion ;; Find the containing-paren, and use that as the limit (if (setq containing-paren (save-restriction (narrow-to-region lim (point)) (vhdl-safe (scan-lists (point) -1 1)))) (setq lim containing-paren)) ;; Look backwards for "begin" and "end" keywords. (while (and (> (point) lim) (not containing-sexp)) (setq keyword (vhdl-backward-to-block lim)) (cond ((eq keyword 'begin) ;; Found a "begin" keyword (setq sexp-start (point)) (setq sexp-mid (vhdl-corresponding-mid lim)) (setq sexp-end (vhdl-safe (save-excursion (vhdl-forward-sexp 1 lim) (point)))) (if (and sexp-end (<= sexp-end here)) ;; we want to record this sexp, but we only want to ;; record the last-most of any of them before here (or preceding-sexp (setq preceding-sexp sexp-start)) ;; we're contained in this sexp so put sexp-start on ;; front of list (setq containing-sexp sexp-start) (setq containing-mid sexp-mid) (setq containing-begin t))) ((eq keyword 'end) ;; Found an "end" keyword (forward-sexp) (setq sexp-end (point)) (setq sexp-mid nil) (setq sexp-start (or (vhdl-safe (vhdl-backward-sexp 1 lim) (point)) (progn (backward-sexp) (point)))) ;; we want to record this sexp, but we only want to ;; record the last-most of any of them before here (or preceding-sexp (setq preceding-sexp sexp-start))) ))) ;; Check if the containing-paren should be the containing-sexp (if (and containing-paren (or (null containing-sexp) (< containing-sexp containing-paren))) (setq containing-sexp containing-paren preceding-sexp nil containing-begin nil containing-mid nil)) (vector containing-sexp preceding-sexp containing-begin containing-mid) )) (defconst vhdl-s-c-a-re (concat vhdl-case-alternative-re "\\|" vhdl-case-header-key)) (defun vhdl-skip-case-alternative (&optional lim) "Skip forward over case/when bodies, with optional maximal limit. If no next case alternative is found, nil is returned and point is not moved." (let ((lim (or lim (point-max))) (here (point)) donep foundp) (while (and (< (point) lim) (not donep)) (if (and (re-search-forward vhdl-s-c-a-re lim 'move) (save-match-data (not (vhdl-in-literal))) (/= (match-beginning 0) here)) (progn (goto-char (match-beginning 0)) (cond ((and (looking-at "case") (re-search-forward "\\bis[^_]" lim t)) (backward-sexp) (vhdl-forward-sexp)) (t (setq donep t foundp t)))))) (if (not foundp) (goto-char here)) foundp)) (defun vhdl-backward-skip-label (&optional lim) "Skip backward over a label, with optional maximal limit. If label is not found, nil is returned and point is not moved." (let ((lim (or lim (point-min))) placeholder) (if (save-excursion (vhdl-backward-syntactic-ws lim) (and (eq (preceding-char) ?:) (progn (backward-sexp) (setq placeholder (point)) (looking-at vhdl-label-key)))) (goto-char placeholder)) )) (defun vhdl-forward-skip-label (&optional lim) "Skip forward over a label, with optional maximal limit. If label is not found, nil is returned and point is not moved." (let ((lim (or lim (point-max)))) (if (looking-at vhdl-label-key) (progn (goto-char (match-end 0)) (vhdl-forward-syntactic-ws lim))) )) (defun vhdl-get-syntactic-context () "Guess the syntactic description of the current line of VHDL code." (save-excursion (save-restriction (beginning-of-line) (let* ((indent-point (point)) (case-fold-search t) vec literal containing-sexp preceding-sexp containing-begin containing-mid containing-leader char-before-ip char-after-ip begin-after-ip end-after-ip placeholder lim library-unit ) ;; Reset the syntactic context (setq vhdl-syntactic-context nil) (save-excursion ;; Move to the start of the previous library unit, and ;; record the position of the "begin" keyword. (setq placeholder (vhdl-beginning-of-libunit)) ;; The position of the "libunit" keyword gives us a gross ;; limit point. (setq lim (point)) ) ;; If there is a previous library unit, and we are enclosed by ;; it, then set the syntax accordingly. (and placeholder (setq library-unit (vhdl-get-library-unit lim placeholder)) (vhdl-add-syntax library-unit lim)) ;; Find the surrounding state. (if (setq vec (vhdl-get-block-state lim)) (progn (setq containing-sexp (aref vec 0)) (setq preceding-sexp (aref vec 1)) (setq containing-begin (aref vec 2)) (setq containing-mid (aref vec 3)) )) ;; set the limit on the farthest back we need to search (setq lim (if containing-sexp (save-excursion (goto-char containing-sexp) ;; set containing-leader if required (if (looking-at vhdl-leader-re) (setq containing-leader (vhdl-end-of-leader))) (vhdl-point 'bol)) (point-min))) ;; cache char before and after indent point, and move point to ;; the most likely position to perform the majority of tests (goto-char indent-point) (skip-chars-forward " \t") (setq literal (vhdl-in-literal lim)) (setq char-after-ip (following-char)) (setq begin-after-ip (and (not literal) (looking-at vhdl-begin-fwd-re) (vhdl-begin-p))) (setq end-after-ip (and (not literal) (looking-at vhdl-end-fwd-re) (vhdl-end-p))) (vhdl-backward-syntactic-ws lim) (setq char-before-ip (preceding-char)) (goto-char indent-point) (skip-chars-forward " \t") ;; now figure out syntactic qualities of the current line (cond ;; CASE 1: in a string or comment. ((memq literal '(string comment)) (vhdl-add-syntax literal (vhdl-point 'bopl))) ;; CASE 2: Line is at top level. ((null containing-sexp) ;; Find the point to which indentation will be relative (save-excursion (if (null preceding-sexp) ;; CASE 2X.1 ;; no preceding-sexp -> use the preceding statement (vhdl-beginning-of-statement-1 lim) ;; CASE 2X.2 ;; if there is a preceding-sexp then indent relative to it (goto-char preceding-sexp) ;; if not at boi, then the block-opening keyword is ;; probably following a label, so we need a different ;; relpos (if (/= (point) (vhdl-point 'boi)) ;; CASE 2X.3 (vhdl-beginning-of-statement-1 lim))) ;; v-b-o-s could have left us at point-min (and (bobp) ;; CASE 2X.4 (vhdl-forward-syntactic-ws indent-point)) (setq placeholder (point))) (cond ;; CASE 2A : we are looking at a block-open (begin-after-ip (vhdl-add-syntax 'block-open placeholder)) ;; CASE 2B: we are looking at a block-close (end-after-ip (vhdl-add-syntax 'block-close placeholder)) ;; CASE 2C: we are looking at a top-level statement ((progn (vhdl-backward-syntactic-ws lim) (or (bobp) (= (preceding-char) ?\;))) (vhdl-add-syntax 'statement placeholder)) ;; CASE 2D: we are looking at a top-level statement-cont (t (vhdl-beginning-of-statement-1 lim) ;; v-b-o-s could have left us at point-min (and (bobp) ;; CASE 2D.1 (vhdl-forward-syntactic-ws indent-point)) (vhdl-add-syntax 'statement-cont (point))) )) ; end CASE 2 ;; CASE 3: line is inside parentheses. Most likely we are ;; either in a subprogram argument (interface) list, or a ;; continued expression containing parentheses. ((null containing-begin) (vhdl-backward-syntactic-ws containing-sexp) (cond ;; CASE 3A: we are looking at the arglist closing paren ((eq char-after-ip ?\)) (goto-char containing-sexp) (vhdl-add-syntax 'arglist-close (vhdl-point 'boi))) ;; CASE 3B: we are looking at the first argument in an empty ;; argument list. ((eq char-before-ip ?\() (goto-char containing-sexp) (vhdl-add-syntax 'arglist-intro (vhdl-point 'boi))) ;; CASE 3C: we are looking at an arglist continuation line, ;; but the preceding argument is on the same line as the ;; opening paren. This case includes multi-line ;; expression paren groupings. ((and (save-excursion (goto-char (1+ containing-sexp)) (skip-chars-forward " \t") (not (eolp)) (not (looking-at "--"))) (save-excursion (vhdl-beginning-of-statement-1 containing-sexp) (skip-chars-backward " \t(") (<= (point) containing-sexp))) (goto-char containing-sexp) (vhdl-add-syntax 'arglist-cont-nonempty (vhdl-point 'boi))) ;; CASE 3D: we are looking at just a normal arglist ;; continuation line (t (vhdl-beginning-of-statement-1 containing-sexp) (vhdl-forward-syntactic-ws indent-point) (vhdl-add-syntax 'arglist-cont (vhdl-point 'boi))) )) ;; CASE 4: A block mid open ((and begin-after-ip (looking-at containing-mid)) (goto-char containing-sexp) ;; If the \"begin\" keyword is a trailer, then find v-b-o-s (if (looking-at vhdl-trailer-re) ;; CASE 4.1 (progn (forward-sexp) (vhdl-beginning-of-statement-1 nil))) (vhdl-backward-skip-label (vhdl-point 'boi)) (vhdl-add-syntax 'block-open (point))) ;; CASE 5: block close brace (end-after-ip (goto-char containing-sexp) ;; If the \"begin\" keyword is a trailer, then find v-b-o-s (if (looking-at vhdl-trailer-re) ;; CASE 5.1 (progn (forward-sexp) (vhdl-beginning-of-statement-1 nil))) (vhdl-backward-skip-label (vhdl-point 'boi)) (vhdl-add-syntax 'block-close (point))) ;; CASE 6: A continued statement ((and (/= char-before-ip ?\;) ;; check it's not a trailer begin keyword, or a begin ;; keyword immediately following a label. (not (and begin-after-ip (or (looking-at vhdl-trailer-re) (save-excursion (vhdl-backward-skip-label containing-sexp))))) ;; check it's not a statement keyword (not (and (looking-at vhdl-statement-fwd-re) (vhdl-statement-p))) ;; see if the b-o-s is before the indent point (> indent-point (save-excursion (vhdl-beginning-of-statement-1 containing-sexp) ;; If we ended up after a leader, then this will ;; move us forward to the start of the first ;; statement. Note that a containing sexp here is ;; always a keyword, not a paren, so this will ;; have no effect if we hit the containing-sexp. (vhdl-forward-syntactic-ws indent-point) (setq placeholder (point)))) ;; check it's not a block-intro (/= placeholder containing-sexp) ;; check it's not a case block-intro (save-excursion (goto-char placeholder) (or (not (looking-at vhdl-case-alternative-re)) (> (match-end 0) indent-point)))) ;; Make placeholder skip a label, but only if it puts us ;; before the indent point at the start of a line. (let ((new placeholder)) (if (and (> indent-point (save-excursion (goto-char placeholder) (vhdl-forward-skip-label indent-point) (setq new (point)))) (save-excursion (goto-char new) (eq new (progn (back-to-indentation) (point))))) (setq placeholder new))) (vhdl-add-syntax 'statement-cont placeholder) (if begin-after-ip (vhdl-add-syntax 'block-open))) ;; Statement. But what kind? ;; CASE 7: A case alternative key ((and (looking-at vhdl-case-alternative-re) (vhdl-case-alternative-p containing-sexp)) ;; for a case alternative key, we set relpos to the first ;; non-whitespace char on the line containing the "case" ;; keyword. (goto-char containing-sexp) ;; If the \"begin\" keyword is a trailer, then find v-b-o-s (if (looking-at vhdl-trailer-re) (progn (forward-sexp) (vhdl-beginning-of-statement-1 nil))) (vhdl-add-syntax 'case-alternative (vhdl-point 'boi))) ;; CASE 8: statement catchall (t ;; we know its a statement, but we need to find out if it is ;; the first statement in a block (if containing-leader (goto-char containing-leader) (goto-char containing-sexp) ;; Note that a containing sexp here is always a keyword, ;; not a paren, so skip over the keyword. (forward-sexp)) ;; move to the start of the first statement (vhdl-forward-syntactic-ws indent-point) (setq placeholder (point)) ;; we want to ignore case alternatives keys when skipping forward (let (incase-p) (while (looking-at vhdl-case-alternative-re) (setq incase-p (point)) ;; we also want to skip over the body of the ;; case/when statement if that doesn't put us at ;; after the indent-point (while (vhdl-skip-case-alternative indent-point)) ;; set up the match end (looking-at vhdl-case-alternative-re) (goto-char (match-end 0)) ;; move to the start of the first case alternative statement (vhdl-forward-syntactic-ws indent-point) (setq placeholder (point))) (cond ;; CASE 8A: we saw a case/when statement so we must be ;; in a switch statement. find out if we are at the ;; statement just after a case alternative key ((and incase-p (= (point) indent-point)) ;; relpos is the "when" keyword (vhdl-add-syntax 'statement-case-intro incase-p)) ;; CASE 8B: any old statement ((< (point) indent-point) ;; relpos is the first statement of the block (vhdl-add-syntax 'statement placeholder) (if begin-after-ip (vhdl-add-syntax 'block-open))) ;; CASE 8C: first statement in a block (t (goto-char containing-sexp) ;; If the \"begin\" keyword is a trailer, then find v-b-o-s (if (looking-at vhdl-trailer-re) (progn (forward-sexp) (vhdl-beginning-of-statement-1 nil))) (vhdl-backward-skip-label (vhdl-point 'boi)) (vhdl-add-syntax 'statement-block-intro (point)) (if begin-after-ip (vhdl-add-syntax 'block-open))) ))) ) ;; now we need to look at any modifiers (goto-char indent-point) (skip-chars-forward " \t") (if (looking-at "--") (vhdl-add-syntax 'comment)) ;; return the syntax vhdl-syntactic-context)))) ;; Standard indentation line-ups: (defun vhdl-lineup-arglist (langelem) "Lineup the current arglist line with the arglist appearing just after the containing paren which starts the arglist." (save-excursion (let* ((containing-sexp (save-excursion ;; arglist-cont-nonempty gives relpos == ;; to boi of containing-sexp paren. This ;; is good when offset is +, but bad ;; when it is vhdl-lineup-arglist, so we ;; have to special case a kludge here. (if (memq (car langelem) '(arglist-intro arglist-cont-nonempty)) (progn (beginning-of-line) (backward-up-list 1) (skip-chars-forward " \t" (vhdl-point 'eol))) (goto-char (cdr langelem))) (point))) (cs-curcol (save-excursion (goto-char (cdr langelem)) (current-column)))) (if (save-excursion (beginning-of-line) (looking-at "[ \t]*)")) (progn (goto-char (match-end 0)) (backward-sexp) (forward-char) (vhdl-forward-syntactic-ws) (- (current-column) cs-curcol)) (goto-char containing-sexp) (or (eolp) (let ((eol (vhdl-point 'eol)) (here (progn (forward-char) (skip-chars-forward " \t") (point)))) (vhdl-forward-syntactic-ws) (if (< (point) eol) (goto-char here)))) (- (current-column) cs-curcol) )))) (defun vhdl-lineup-arglist-intro (langelem) "Lineup an arglist-intro line to just after the open paren." (save-excursion (let ((cs-curcol (save-excursion (goto-char (cdr langelem)) (current-column))) (ce-curcol (save-excursion (beginning-of-line) (backward-up-list 1) (skip-chars-forward " \t" (vhdl-point 'eol)) (current-column)))) (- ce-curcol cs-curcol -1)))) (defun vhdl-lineup-comment (langelem) "Support old behavior for comment indentation. We look at vhdl-comment-only-line-offset to decide how to indent comment only-lines." (save-excursion (back-to-indentation) ;; at or to the right of comment-column (if (>= (current-column) comment-column) (vhdl-comment-indent) ;; otherwise, indent as specified by vhdl-comment-only-line-offset (if (not (bolp)) (or (car-safe vhdl-comment-only-line-offset) vhdl-comment-only-line-offset) (or (cdr-safe vhdl-comment-only-line-offset) (car-safe vhdl-comment-only-line-offset) -1000 ;jam it against the left side ))))) (defun vhdl-lineup-statement-cont (langelem) "Line up statement-cont after the assignment operator." (save-excursion (let* ((relpos (cdr langelem)) (assignp (save-excursion (goto-char (vhdl-point 'boi)) (and (re-search-forward "\\(<\\|:\\)=" (vhdl-point 'eol) t) (- (point) (vhdl-point 'boi))))) (curcol (progn (goto-char relpos) (current-column))) foundp) (while (and (not foundp) (< (point) (vhdl-point 'eol))) (re-search-forward "\\(<\\|:\\)=\\|(" (vhdl-point 'eol) 'move) (if (vhdl-in-literal (cdr langelem)) (forward-char) (if (= (preceding-char) ?\() ;; skip over any parenthesized expressions (goto-char (min (vhdl-point 'eol) (scan-lists (point) 1 1))) ;; found an assignment operator (not at eol) (setq foundp (not (looking-at "\\s-*$")))))) (if (not foundp) ;; there's no assignment operator on the line vhdl-basic-offset ;; calculate indentation column after assign and ws, unless ;; our line contains an assignment operator (if (not assignp) (progn (forward-char) (skip-chars-forward " \t") (setq assignp 0))) (- (current-column) assignp curcol)) ))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Indentation commands (defsubst vhdl-in-comment-p () "Check if point is to right of beginning comment delimiter." (let ((position (point))) (save-excursion ; finds an unquoted comment (beginning-of-line) (re-search-forward "^\\([^\"]*\"[^\"]*\"\\)*[^\"]*--" position t)))) (defsubst vhdl-in-string-p () "Check if point is in a string." (let ((position (point))) (save-excursion ; preceeded by odd number of string delimiters? (beginning-of-line) (eq position (re-search-forward "^\\([^\"]*\"[^\"]*\"\\)*[^\"]*\"[^\"]*" position t))))) (defsubst vhdl-in-comment-or-string-p () "Check if point is in a comment or a string." (and (vhdl-in-comment-p) (vhdl-in-string-p))) (defun vhdl-electric-tab (&optional prefix-arg) "If preceeding character is part of a word or a paren then hippie-expand, else if right of non whitespace on line then tab-to-tab-stop, else if last command was a tab or return then dedent one step, else indent `correctly'." (interactive "*P") (vhdl-ext-syntax-table (cond ((= (char-syntax (preceding-char)) ?w) (let ((case-fold-search (not vhdl-word-completion-case-sensitive)) (case-replace nil)) (vhdl-expand-abbrev prefix-arg))) ((or (= (preceding-char) ?\() (= (preceding-char) ?\))) (let ((case-fold-search (not vhdl-word-completion-case-sensitive)) (case-replace nil)) (vhdl-expand-paren prefix-arg))) ((> (current-column) (current-indentation)) (tab-to-tab-stop)) ((and (or (eq last-command 'vhdl-electric-tab) (eq last-command 'vhdl-electric-return)) (/= 0 (current-indentation))) (backward-delete-char-untabify vhdl-basic-offset nil)) (t (vhdl-indent-line))) (setq this-command 'vhdl-electric-tab))) (defun vhdl-electric-return () "newline-and-indent or indent-new-comment-line if in comment and preceding character is a space." (interactive) (if (and (= (preceding-char) ? ) (vhdl-in-comment-p)) (indent-new-comment-line) (newline-and-indent))) (defvar vhdl-progress-info nil "Array variable for progress information: 0 begin, 1 end, 2 time.") (defun vhdl-indent-line () "Indent the current line as VHDL code. Returns the amount of indentation change." (interactive) (let* ((syntax (vhdl-get-syntactic-context)) (pos (- (point-max) (point))) ;; special case: comments at or right of comment-column (indent (if (and (eq (car (car syntax)) 'comment) (>= (vhdl-get-offset (car syntax)) comment-column)) (vhdl-get-offset (car syntax)) (apply '+ (mapcar 'vhdl-get-offset syntax)))) ; (indent (apply '+ (mapcar 'vhdl-get-offset syntax))) (shift-amt (- indent (current-indentation)))) (and vhdl-echo-syntactic-information-p (message "syntax: %s, indent= %d" syntax indent)) (unless (zerop shift-amt) (delete-region (vhdl-point 'bol) (vhdl-point 'boi)) (beginning-of-line) (indent-to indent)) (if (< (point) (vhdl-point 'boi)) (back-to-indentation) ;; If initial point was within line's indentation, position after ;; the indentation. Else stay at same point in text. (when (> (- (point-max) pos) (point)) (goto-char (- (point-max) pos)))) (run-hooks 'vhdl-special-indent-hook) ;; update progress status (when vhdl-progress-info (aset vhdl-progress-info 1 (+ (aref vhdl-progress-info 1) (if (> -500 shift-amt) 0 shift-amt))) (when (< vhdl-progress-interval (- (nth 1 (current-time)) (aref vhdl-progress-info 2))) (message "Indenting... (%2d%s)" (/ (* 100 (- (point) (aref vhdl-progress-info 0))) (- (aref vhdl-progress-info 1) (aref vhdl-progress-info 0))) "%") (aset vhdl-progress-info 2 (nth 1 (current-time))))) shift-amt)) (defun vhdl-indent-buffer () "Indent whole buffer as VHDL code. Calls `indent-region' for whole buffer and adds progress reporting." (interactive) (when vhdl-progress-interval (setq vhdl-progress-info (vector (point-min) (point-max) 0))) (indent-region (point-min) (point-max) nil) (when vhdl-progress-interval (message "Indenting...done")) (setq vhdl-progress-info nil)) (defun vhdl-indent-region (start end column) "Indent region as VHDL code. Adds progress reporting to `indent-region'." (interactive "r\nP") (when vhdl-progress-interval (setq vhdl-progress-info (vector start end 0))) (indent-region start end column) (when vhdl-progress-interval (message "Indenting...done")) (setq vhdl-progress-info nil)) (defun vhdl-indent-sexp (&optional endpos) "Indent each line of the list starting just after point. If optional arg ENDPOS is given, indent each line, stopping when ENDPOS is encountered." (interactive) (save-excursion (let ((beg (point)) (end (progn (vhdl-forward-sexp nil endpos) (point)))) (indent-region beg end nil)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Miscellaneous commands (defun vhdl-show-syntactic-information () "Show syntactic information for current line." (interactive) (message "syntactic analysis: %s" (vhdl-get-syntactic-context)) (vhdl-keep-region-active)) ;; Verification and regression functions: (defun vhdl-regress-line (&optional arg) "Check syntactic information for current line." (interactive "P") (let ((expected (save-excursion (end-of-line) (when (search-backward " -- ((" (vhdl-point 'bol) t) (forward-char 4) (read (current-buffer))))) (actual (vhdl-get-syntactic-context)) (expurgated)) ;; remove the library unit symbols (mapcar (function (lambda (elt) (if (memq (car elt) '(entity configuration package package-body architecture)) nil (setq expurgated (append expurgated (list elt)))))) actual) (if (and (not arg) expected (listp expected)) (if (not (equal expected expurgated)) (error "Should be: %s, is: %s" expected expurgated)) (save-excursion (beginning-of-line) (when (not (looking-at "^\\s-*\\(--.*\\)?$")) (end-of-line) (if (search-backward " -- ((" (vhdl-point 'bol) t) (kill-line)) (insert " -- ") (insert (format "%s" expurgated)))))) (vhdl-keep-region-active)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Alignment, whitespace fixup, beautifying ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar vhdl-align-alist '( ;; after some keywords (vhdl-mode "\\<\\(constant\\|quantity\\|signal\\|terminal\\|variable\\)[ \t]" "\\<\\(constant\\|quantity\\|signal\\|terminal\\|variable\\)\\([ \t]+\\)" 2) ;; before ':' (vhdl-mode ":[^=]" "\\([ \t]*\\):[^=]") ;; after direction specifications (vhdl-mode ":[ \t]*\\(in\\|out\\|inout\\|buffer\\|\\)\\>" ":[ \t]*\\(in\\|out\\|inout\\|buffer\\|\\)\\([ \t]+\\)" 2) ;; before "==", ":=", "=>", and "<=" (vhdl-mode "==" "\\([ \t]*\\)==" 1) (vhdl-mode ":=" "\\([ \t]*\\):=" 1) ; since ":= ... =>" can occur (vhdl-mode "<=" "\\([ \t]*\\)<=" 1) ; since "<= ... =>" can occur (vhdl-mode "=>" "\\([ \t]*\\)=>" 1) (vhdl-mode ":=" "\\([ \t]*\\):=" 1) ; since "=> ... :=" can occur (vhdl-mode "<=" "\\([ \t]*\\)<=" 1) ; since "=> ... <=" can occur ;; before some keywords (vhdl-mode "[ \t]after\\>" "[^ \t]\\([ \t]+\\)after\\>" 1) (vhdl-mode "[ \t]when\\>" "[^ \t]\\([ \t]+\\)when\\>" 1) (vhdl-mode "[ \t]else\\>" "[^ \t]\\([ \t]+\\)else\\>" 1) ) "The format of this alist is (MODES [or MODE] REGEXP ALIGN-PATTERN SUBEXP). It is searched in order. If REGEXP is found anywhere in the first line of a region to be aligned, ALIGN-PATTERN will be used for that region. ALIGN-PATTERN must include the whitespace to be expanded or contracted. It may also provide regexps for the text surrounding the whitespace. SUBEXP specifies which sub-expression of ALIGN-PATTERN matches the white space to be expanded/contracted.") (defvar vhdl-align-try-all-clauses t "If REGEXP is not found on the first line of the region that clause is ignored. If this variable is non-nil, then the clause is tried anyway.") (defun vhdl-align-region (begin end &optional spacing alignment-list indent) "Attempt to align a range of lines based on the content of the lines. The definition of `alignment-list' determines the matching order and the manner in which the lines are aligned. If ALIGNMENT-LIST is not specified `vhdl-align-alist' is used. If INDENT is non-nil, indentation is done before aligning." (interactive "r\np") (setq alignment-list (or alignment-list vhdl-align-alist)) (setq spacing (or spacing 1)) (save-excursion (let (bol indent) (goto-char end) (setq end (point-marker)) (goto-char begin) (setq bol (setq begin (progn (beginning-of-line) (point)))) ; (untabify bol end) (when indent (indent-region bol end nil)))) (let ((case-fold-search t) (copy (copy-alist alignment-list))) (vhdl-ext-syntax-table (while copy (save-excursion (goto-char begin) (let (element (eol (save-excursion (progn (end-of-line) (point))))) (setq element (nth 0 copy)) (when (and (or (and (listp (car element)) (memq major-mode (car element))) (eq major-mode (car element))) (or vhdl-align-try-all-clauses (re-search-forward (car (cdr element)) eol t))) (vhdl-align-region-1 begin end (car (cdr (cdr element))) (car (cdr (cdr (cdr element)))) spacing)) (setq copy (cdr copy)))))))) (defun vhdl-align-region-1 (begin end match &optional substr spacing) "Align a range of lines from BEGIN to END. The regular expression MATCH must match exactly one fields: the whitespace to be contracted/expanded. The alignment column will equal the rightmost column of the widest whitespace block. SPACING is the amount of extra spaces to add to the calculated maximum required. SPACING defaults to 1 so that at least one space is inserted after the token in MATCH." (setq spacing (or spacing 1)) (setq substr (or substr 1)) (save-excursion (let (distance (max 0) (lines 0) bol eol width) ;; Determine the greatest whitespace distance to the alignment ;; character (goto-char begin) (setq eol (progn (end-of-line) (point)) bol (setq begin (progn (beginning-of-line) (point)))) (while (< bol end) (save-excursion (when (and (re-search-forward match eol t) (not (vhdl-in-comment-p))) (setq distance (- (match-beginning substr) bol)) (when (> distance max) (setq max distance)))) (forward-line) (setq bol (point) eol (save-excursion (end-of-line) (point))) (setq lines (1+ lines))) ;; Now insert enough maxs to push each assignment operator to ;; the same column. We need to use 'lines' as a counter, since ;; the location of the mark may change (goto-char (setq bol begin)) (setq eol (save-excursion (end-of-line) (point))) (while (> lines 0) (when (and (re-search-forward match eol t) (not (vhdl-in-comment-p))) (setq width (- (match-end substr) (match-beginning substr))) (setq distance (- (match-beginning substr) bol)) (goto-char (match-beginning substr)) (delete-char width) (insert-char ? (+ (- max distance) spacing))) (beginning-of-line) (forward-line) (setq bol (point) eol (save-excursion (end-of-line) (point))) (setq lines (1- lines)))))) (defun vhdl-align-inline-comment-region-1 (beg end &optional spacing) "Align inline comments in region." (save-excursion (let ((high-start 0) (high-length 0) (case-fold-search t)) (vhdl-ext-syntax-table (goto-char beg) ;; search for longest code line and longest inline comment (while (< (point) end) (cond ((and (not (looking-at "^\\s-*\\(begin\\|end\\)\\>")) (looking-at "^\\(.*[^ \t\n-]+\\)\\s-*\\(--\\s-*.*\\)$")) (setq high-start (max high-start (- (match-end 1) (match-beginning 1)))) (setq high-length (max high-length (- (match-end 2) (match-beginning 2))))) ((and (looking-at "^\\(\\s-*\\))\\(--\\s-*.*\\)$") (>= (- (match-end 1) (match-beginning 1)) comment-column)) (setq high-length (max high-length (- (match-end 2) (match-beginning 2)))))) (beginning-of-line 2)) (goto-char beg) (setq spacing (or spacing 2)) (setq high-start (+ high-start spacing)) ;; align as nice as possible (while (< (point) end) (when (and (not (looking-at "^\\s-*\\(begin\\|end\\)\\>")) (or (looking-at "^.*[^ \t\n-]+\\(\\s-*\\)--") (and (looking-at "^\\(\\s-*\\)--") (>= (- (match-end 1) (match-beginning 1)) comment-column)))) (goto-char (match-end 1)) (delete-region (match-beginning 1) (match-end 1)) (insert-char ? spacing) (cond ((<= high-start comment-column) (indent-to comment-column)) ((<= (+ high-start high-length) end-comment-column) (indent-to high-start)) (t (indent-to comment-column)))) (beginning-of-line 2)))))) (defun vhdl-align-noindent-region (beg end &optional spacing no-message) "Align region without indentation." (interactive "r\nP") (save-excursion (let (pos) (goto-char beg) (beginning-of-line) (setq beg (point)) (goto-char end) (setq end (point-marker)) (untabify beg end) (unless no-message (message "Aligning...")) (vhdl-fixup-whitespace-region beg end t) (goto-char beg) (if (not vhdl-align-groups) ;; align entire region (progn (vhdl-align-region beg end spacing) (vhdl-align-inline-comment-region-1 beg end)) ;; align groups (while (and (< beg end) (re-search-forward "^\\s-*$" end t)) (setq pos (point-marker)) (vhdl-align-region beg pos spacing) (vhdl-align-inline-comment-region-1 beg pos) (setq beg (1+ pos)) (goto-char beg)) ;; align last group (when (< beg end) (vhdl-align-region beg end spacing) (vhdl-align-inline-comment-region-1 beg end))))) (unless no-message (message "Aligning...done"))) (defun vhdl-align-group (&optional spacing) "Align group of lines between empty lines." (interactive) (save-excursion (let ((start (point)) beg end) (setq end (if (re-search-forward "^\\s-*$" nil t) (point-marker) (point-max))) (goto-char start) (setq beg (if (re-search-backward "^\\s-*$" nil t) (point) (point-min))) (untabify beg end) (message "Aligning...") (vhdl-fixup-whitespace-region beg end t) (vhdl-align-region beg end spacing) (vhdl-align-inline-comment-region-1 beg end) (message "Aligning...done")))) (defun vhdl-align-noindent-buffer () "Align buffer without indentation." (interactive) (vhdl-align-noindent-region (point-min) (point-max))) (defun vhdl-align-inline-comment-region (beg end &optional spacing no-message) "Align inline comments within a region. Groups of code lines separated by empty lines are aligned individually, if `vhdl-align-groups' is non-nil." (interactive "r\nP") (save-excursion (let (pos) (goto-char beg) (beginning-of-line) (setq beg (point)) (goto-char end) (setq end (point-marker)) (untabify beg end) (unless no-message (message "Aligning inline comments...")) (goto-char beg) (if (not vhdl-align-groups) ;; align entire region (vhdl-align-inline-comment-region-1 beg end spacing) ;; align groups (while (and (< beg end) (re-search-forward "^\\s-*$" end t)) (setq pos (point-marker)) (vhdl-align-inline-comment-region-1 beg pos spacing) (setq beg (1+ pos)) (goto-char beg)) ;; align last group (when (< beg end) (vhdl-align-inline-comment-region-1 beg end spacing)))) (unless no-message (message "Aligning inline comments...done")))) (defun vhdl-align-inline-comment-group (&optional spacing) "Align inline comments within a group of lines between empty lines." (interactive) (save-excursion (let ((start (point)) beg end) (setq end (if (re-search-forward "^\\s-*$" nil t) (point-marker) (point-max))) (goto-char start) (setq beg (if (re-search-backward "^\\s-*$" nil t) (point) (point-min))) (untabify beg end) (message "Aligning inline comments...") (vhdl-align-inline-comment-region-1 beg end) (message "Aligning inline comments...done")))) (defun vhdl-align-inline-comment-buffer () "Align inline comments within buffer. Groups of code lines separated by empty lines are aligned individually, if `vhdl-align-groups' is non-nil." (interactive) (vhdl-align-inline-comment-region (point-min) (point-max))) (defun vhdl-fixup-whitespace-region (beg end &optional no-message) "Fixup whitespace in region. Surround operator symbols by one space, eliminate multiple spaces (except at beginning of line), eliminate spaces at end of line, do nothing in comments." (interactive "r") (unless no-message (message "Fixing up whitespace...")) (save-excursion (goto-char end) (setq end (point-marker)) ;; surround operator symbols by one space (goto-char beg) (while (re-search-forward "\\([^/:<>=]\\|^\\)\\(--\\|:\\|=\\|<\\|>\\|:=\\|<=\\|>=\\|=>\\)\\([^=>]\\|$\\)" end t) (if (equal "--" (match-string 2)) (re-search-forward ".*\n" end t) (replace-match "\\1 \\2 \\3"))) ;; have no space before and one space after `,' and ';' (goto-char beg) (while (re-search-forward "\\(--\\|\\s-*\\([,;]\\)\\)" end t) (if (equal "--" (match-string 1)) (re-search-forward ".*\n" end t) (replace-match "\\2 " nil nil nil 1))) ;; eliminate multiple spaces and spaces at end of line (goto-char beg) (while (or (and (looking-at "--.*\n") (re-search-forward "--.*\n" end t)) (and (looking-at "\\s-+$") (re-search-forward "\\s-+$" end t) (progn (replace-match "" nil nil) t)) (and (looking-at "\\s-+;") (re-search-forward "\\s-+;" end t) (progn (replace-match ";" nil nil) t)) (and (looking-at "^\\s-+") (re-search-forward "^\\s-+" end t)) (and (looking-at "\\s-+--") (re-search-forward "\\s-+" end t) (progn (replace-match " " nil nil) t )) (and (looking-at "\\s-+") (re-search-forward "\\s-+" end t) (progn (replace-match " " nil nil) t )) (re-search-forward "\\S-+" end t)))) (unless no-message (message "Fixing up whitespace...done"))) (defun vhdl-fixup-whitespace-buffer () "Fixup whitespace in buffer. Surround operator symbols by one space, eliminate multiple spaces (except at beginning of line), eliminate spaces at end of line, do nothing in comments." (interactive) (vhdl-fixup-whitespace-region (point-min) (point-max))) (defun vhdl-beautify-region (beg end) "Beautify region by applying indentation, whitespace fixup, alignment, and case fixing to a resion. Calls functions `vhdl-indent-buffer', `vhdl-align-noindent-buffer' (variable `vhdl-align-groups' set to non-nil), and `vhdl-fix-case-buffer'." (interactive "r") (vhdl-indent-region beg end nil) (let ((vhdl-align-groups t)) (vhdl-align-noindent-region beg end)) (vhdl-fix-case-region beg end)) (defun vhdl-beautify-buffer () "Beautify buffer by applying indentation, whitespace fixup, alignment, and case fixing to entire buffer. Calls `vhdl-beautify-region' for the entire buffer." (interactive) (vhdl-beautify-region (point-min) (point-max))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Electrification ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defconst vhdl-template-prompt-syntax "[^ =<>][^<>@.\n]*[^ =<>]" "Syntax of prompt inserted by template generators.") (defvar vhdl-template-invoked-by-hook nil "Indicates whether a template has been invoked by a hook or by key or menu. Used for undoing after template abortion.") ;; correct different behavior of function `unread-command-events' in XEmacs (defalias 'vhdl-character-to-event (if (string-match "XEmacs" emacs-version) 'character-to-event 'identity)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Enabling/disabling (defun vhdl-mode-line-update () "Update the modeline string for VHDL major mode." (setq mode-name (concat "VHDL" (and (or vhdl-electric-mode vhdl-stutter-mode) "/") (and vhdl-electric-mode "e") (and vhdl-stutter-mode "s"))) (force-mode-line-update)) (defun vhdl-electric-mode (arg) "Toggle VHDL electric mode. Turn on if ARG positive, turn off if ARG negative, toggle if ARG zero or nil." (interactive "P") (setq vhdl-electric-mode (cond ((or (not arg) (zerop arg)) (not vhdl-electric-mode)) ((> arg 0) t) (t nil))) (vhdl-mode-line-update)) (defun vhdl-stutter-mode (arg) "Toggle VHDL stuttering mode. Turn on if ARG positive, turn off if ARG negative, toggle if ARG zero or nil." (interactive "P") (setq vhdl-stutter-mode (cond ((or (not arg) (zerop arg)) (not vhdl-stutter-mode)) ((> arg 0) t) (t nil))) (vhdl-mode-line-update)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Stuttering (defun vhdl-electric-dash (count) "-- starts a comment, --- draws a horizontal line, ---- starts a display comment" (interactive "p") (if vhdl-stutter-mode (cond ((and abbrev-start-location (= abbrev-start-location (point))) (setq abbrev-start-location nil) (goto-char last-abbrev-location) (beginning-of-line nil) (vhdl-comment-display)) ((/= (preceding-char) ?-) ; standard dash (minus) (self-insert-command count)) (t (self-insert-command count) (message "Enter '-' for horiz. line, 'CR' for commenting-out code, else enter comment") (let ((next-input (read-char))) (if (= next-input ?-) ; triple dash (progn (vhdl-comment-display-line) (message "Enter '-' for display comment, else continue coding") (let ((next-input (read-char))) (if (= next-input ?-) ; four dashes (vhdl-comment-display t) (setq unread-command-events ; pushback the char (list (vhdl-character-to-event next-input)))))) (setq unread-command-events ; pushback the char (list (vhdl-character-to-event next-input))) (vhdl-comment-insert))))) (self-insert-command count))) (defun vhdl-electric-open-bracket (count) "'[' --> '(', '([' --> '['" (interactive "p") (if (and vhdl-stutter-mode (= count 1)) (if (= (preceding-char) ?\() (progn (delete-char -1) (insert-char ?\[ 1)) (insert-char ?\( 1)) (self-insert-command count))) (defun vhdl-electric-close-bracket (count) "']' --> ')', ')]' --> ']'" (interactive "p") (if (and vhdl-stutter-mode (= count 1)) (progn (if (= (preceding-char) ?\)) (progn (delete-char -1) (insert-char ?\] 1)) (insert-char ?\) 1)) (blink-matching-open)) (self-insert-command count))) (defun vhdl-electric-quote (count) "'' --> \"" (interactive "p") (if (and vhdl-stutter-mode (= count 1)) (if (= (preceding-char) last-input-char) (progn (delete-backward-char 1) (insert-char ?\" 1)) (insert-char ?\' 1)) (self-insert-command count))) (defun vhdl-electric-semicolon (count) "';;' --> ' : ', ': ;' --> ' := '" (interactive "p") (if (and vhdl-stutter-mode (= count 1)) (cond ((= (preceding-char) last-input-char) (progn (delete-char -1) (when (not (eq (preceding-char) ? )) (insert " ")) (insert ": ") (setq this-command 'vhdl-electric-colon))) ((and (eq last-command 'vhdl-electric-colon) (= (preceding-char) ? )) (progn (delete-char -1) (insert "= "))) (t (insert-char ?\; 1))) (self-insert-command count))) (defun vhdl-electric-comma (count) "',,' --> ' <= '" (interactive "p") (if (and vhdl-stutter-mode (= count 1)) (cond ((= (preceding-char) last-input-char) (progn (delete-char -1) (when (not (eq (preceding-char) ? )) (insert " ")) (insert "<= "))) (t (insert-char ?\, 1))) (self-insert-command count))) (defun vhdl-electric-period (count) "'..' --> ' => '" (interactive "p") (if (and vhdl-stutter-mode (= count 1)) (cond ((= (preceding-char) last-input-char) (progn (delete-char -1) (when (not (eq (preceding-char) ? )) (insert " ")) (insert "=> "))) (t (insert-char ?\. 1))) (self-insert-command count))) (defun vhdl-electric-equal (count) "'==' --> ' == '" (interactive "p") (if (and vhdl-stutter-mode (= count 1)) (cond ((= (preceding-char) last-input-char) (progn (delete-char -1) (when (not (eq (preceding-char) ? )) (insert " ")) (insert "== "))) (t (insert-char ?\= 1))) (self-insert-command count))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; VHDL templates (defun vhdl-template-paired-parens () "Insert a pair of round parentheses, placing point between them." (interactive) (insert "()") (backward-char)) (defun vhdl-template-alias () "Insert alias declaration." (interactive) (let ((start (point))) (vhdl-insert-keyword "ALIAS ") (when (vhdl-template-field "name" nil t start (point)) (insert " : ") (unless (vhdl-template-field (concat "[type" (and (vhdl-standard-p 'ams) " or nature") "]") nil t) (backward-delete-char 3)) (vhdl-insert-keyword " IS ") (vhdl-template-field "name" ";") (vhdl-comment-insert-inline)))) (defun vhdl-template-architecture () "Insert architecture." (interactive) (let ((margin (current-indentation)) (start (point)) arch-name entity-exists string (case-fold-search t)) (vhdl-insert-keyword "ARCHITECTURE ") (when (setq arch-name (vhdl-template-field "name" nil t start (point))) (vhdl-insert-keyword " OF ") (save-excursion (vhdl-ext-syntax-table (setq entity-exists (re-search-backward "\\<entity \\(\\w+\\) is\\>" nil t)) (setq string (match-string 1)))) (if (and entity-exists (not (equal string ""))) (insert string) (vhdl-template-field "entity name")) (vhdl-insert-keyword " IS") (vhdl-template-begin-end (unless (vhdl-standard-p '87) "ARCHITECTURE") arch-name margin (memq vhdl-insert-empty-lines '(unit all)))))) (defun vhdl-template-array (kind &optional secondary) "Insert array type definition." (interactive) (let ((start (point))) (vhdl-insert-keyword "ARRAY (") (when (or (vhdl-template-field "range" nil (not secondary) start (point)) secondary) (vhdl-insert-keyword ") OF ") (vhdl-template-field (if (eq kind 'type) "type" "nature")) (vhdl-insert-keyword ";")))) (defun vhdl-template-assert () "Insert an assertion statement." (interactive) (let ((start (point))) (vhdl-insert-keyword "ASSERT ") (when vhdl-conditions-in-parenthesis (insert "(")) (when (vhdl-template-field "condition (negated)" nil t start (point)) (when vhdl-conditions-in-parenthesis (insert ")")) (setq start (point)) (vhdl-insert-keyword " REPORT ") (unless (vhdl-template-field "string expression" nil nil nil nil t) (delete-region start (point))) (setq start (point)) (vhdl-insert-keyword " SEVERITY ") (unless (vhdl-template-field "[NOTE | WARNING | ERROR | FAILURE]" nil t) (delete-region start (point))) (insert ";")))) (defun vhdl-template-attribute () "Insert an attribute declaration or specification." (interactive) (if (eq (vhdl-decision-query "attribute" "(d)eclaration or (s)pecification?" t) ?s) (vhdl-template-attribute-spec) (vhdl-template-attribute-decl))) (defun vhdl-template-attribute-decl () "Insert an attribute declaration." (interactive) (let ((start (point))) (vhdl-insert-keyword "ATTRIBUTE ") (when (vhdl-template-field "name" " : " t start (point)) (vhdl-template-field "type" ";") (vhdl-comment-insert-inline)))) (defun vhdl-template-attribute-spec () "Insert an attribute specification." (interactive) (let ((start (point))) (vhdl-insert-keyword "ATTRIBUTE ") (when (vhdl-template-field "name" nil t start (point)) (vhdl-insert-keyword " OF ") (vhdl-template-field "entity names | OTHERS | ALL" " : ") (vhdl-template-field "entity class") (vhdl-insert-keyword " IS ") (vhdl-template-field "expression" ";")))) (defun vhdl-template-block () "Insert a block." (interactive) (let ((margin (current-indentation)) (start (point)) label) (vhdl-insert-keyword ": BLOCK ") (goto-char start) (when (setq label (vhdl-template-field "label" nil t start (+ (point) 8))) (forward-word 1) (forward-char 1) (insert "(") (if (vhdl-template-field "[guard expression]" nil t) (insert ")") (delete-char -2)) (unless (vhdl-standard-p '87) (vhdl-insert-keyword " IS")) (vhdl-template-begin-end "BLOCK" label margin) (vhdl-comment-block)))) (defun vhdl-template-block-configuration () "Insert a block configuration statement." (interactive) (let ((margin (current-indentation)) (start (point))) (vhdl-insert-keyword "FOR ") (when (vhdl-template-field "block name" nil t start (point)) (vhdl-insert-keyword "\n\n") (indent-to margin) (vhdl-insert-keyword "END FOR;") (end-of-line 0) (indent-to (+ margin vhdl-basic-offset))))) (defun vhdl-template-break () "Insert a break statement." (interactive) (let (position) (vhdl-insert-keyword "BREAK") (setq position (point)) (insert " ") (while (or (progn (vhdl-insert-keyword "FOR ") (if (vhdl-template-field "[quantity name]" " USE " t) (progn (vhdl-template-field "quantity name" " => ") t) (kill-word -1) nil)) (vhdl-template-field "[quantity name]" " => " t)) (vhdl-template-field "expression") (setq position (point)) (insert ", ")) (delete-region position (point)) (unless (vhdl-sequential-statement-p) (vhdl-insert-keyword " ON ") (if (vhdl-template-field "[sensitivity list]" nil t) (setq position (point)) (delete-region position (point)))) (vhdl-insert-keyword " WHEN ") (when vhdl-conditions-in-parenthesis (insert "(")) (if (vhdl-template-field "[condition]" nil t) (when vhdl-conditions-in-parenthesis (insert ")")) (delete-region position (point))) (insert ";"))) (defun vhdl-template-case (&optional kind) "Insert a case statement." (interactive) (let ((margin (current-indentation)) (start (point)) label) (unless kind (setq kind (if (vhdl-sequential-statement-p) 'is 'use))) (if (or (not (eq vhdl-optional-labels 'all)) (vhdl-standard-p '87)) (vhdl-insert-keyword "CASE ") (vhdl-insert-keyword ": CASE ") (goto-char start) (setq label (vhdl-template-field "[label]" nil t)) (unless label (delete-char 2)) (forward-word 1) (forward-char 1)) (when (vhdl-template-field "expression" nil t start (point)) (vhdl-insert-keyword (concat " " (if (eq kind 'is) "IS" "USE") "\n\n")) (indent-to margin) (vhdl-insert-keyword "END CASE") (when label (insert " " label)) (insert ";") (forward-line -1) (indent-to (+ margin vhdl-basic-offset)) (vhdl-insert-keyword "WHEN ") (let ((position (point))) (insert " => ;\n") (indent-to (+ margin vhdl-basic-offset)) (vhdl-insert-keyword "WHEN OTHERS => null;") (goto-char position))))) (defun vhdl-template-case-is () "Insert a sequential case statement." (interactive) (vhdl-template-case 'is)) (defun vhdl-template-case-use () "Insert a simultaneous case statement." (interactive) (vhdl-template-case 'use)) (defun vhdl-template-component () "Insert a component declaration." (interactive) (vhdl-template-component-decl)) (defun vhdl-template-component-conf () "Insert a component configuration (uses `vhdl-template-configuration-spec' since these are almost equivalent)." (interactive) (let ((margin (current-indentation)) (result (vhdl-template-configuration-spec t))) (when result (insert "\n") (indent-to margin) (vhdl-insert-keyword "END FOR;") (when (eq result 'no-use) (end-of-line -0))))) (defun vhdl-template-component-decl () "Insert a component declaration." (interactive) (let ((margin (current-indentation)) (start (point)) name end-column) (vhdl-insert-keyword "COMPONENT ") (when (setq name (vhdl-template-field "name" nil t start (point))) (insert "\n\n") (indent-to margin) (vhdl-insert-keyword "END COMPONENT") (unless (vhdl-standard-p '87) (insert " " name)) (insert ";") (setq end-column (current-column)) (end-of-line -0) (indent-to (+ margin vhdl-basic-offset)) (vhdl-template-generic-list t t) (insert "\n") (indent-to (+ margin vhdl-basic-offset)) (vhdl-template-port-list t) (beginning-of-line 2) (forward-char end-column)))) (defun vhdl-template-component-inst () "Insert a component instantiation statement." (interactive) (let ((margin (current-indentation)) (start (point)) unit position) (when (vhdl-template-field "instance label" nil t start (point)) (insert ": ") (if (vhdl-standard-p '87) (vhdl-template-field "component name") ;; direct instantiation (setq unit (vhdl-template-field "[COMPONENT | ENTITY | CONFIGURATION]" " " t)) (setq unit (upcase (or unit ""))) (cond ((equal unit "ENTITY") (vhdl-template-field "library name" "." nil nil nil nil "work") (vhdl-template-field "entity name" "(") (if (vhdl-template-field "[architecture name]" nil t) (insert ")") (delete-char -1))) ((equal unit "CONFIGURATION") (vhdl-template-field "library name" "." nil nil nil nil "work") (vhdl-template-field "configuration name")) (t (vhdl-template-field "component name")))) (insert "\n") (indent-to (+ margin vhdl-basic-offset)) (setq position (point)) (vhdl-insert-keyword "GENERIC ") (when (vhdl-template-map position t t) (insert "\n") (indent-to (+ margin vhdl-basic-offset))) (setq position (point)) (vhdl-insert-keyword "PORT ") (unless (vhdl-template-map position t t) (kill-line -0) (delete-char -1)) (insert ";")))) (defun vhdl-template-conditional-signal-asst () "Insert a conditional signal assignment." (interactive) (when (vhdl-template-field "target signal") (insert " <= ") ; (if (not (equal (vhdl-template-field "[GUARDED] [TRANSPORT]") "")) ; (insert " ")) (let ((margin (current-column)) (start (point)) position) (vhdl-template-field "waveform") (setq position (point)) (vhdl-insert-keyword " WHEN ") (when vhdl-conditions-in-parenthesis (insert "(")) (while (and (vhdl-template-field "[condition]" nil t) (progn (when vhdl-conditions-in-parenthesis (insert ")")) (setq position (point)) (vhdl-insert-keyword " ELSE") (insert "\n") (indent-to margin) (vhdl-template-field "[waveform]" nil t))) (setq position (point)) (vhdl-insert-keyword " WHEN ") (when vhdl-conditions-in-parenthesis (insert "("))) (delete-region position (point)) (insert ";") (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1))))) (defun vhdl-template-configuration () "Insert a configuration specification if within an architecture, a block or component configuration if within a configuration declaration, a configuration declaration if not within a design unit." (interactive) (let ((case-fold-search t)) (vhdl-ext-syntax-table (cond ((and (save-excursion ; architecture body (re-search-backward "^\\(architecture\\|end\\)\\>" nil t)) (equal "ARCHITECTURE" (upcase (match-string 1)))) (vhdl-template-configuration-spec)) ((and (save-excursion ; configuration declaration (re-search-backward "^\\(configuration\\|end\\)\\>" nil t)) (equal "CONFIGURATION" (upcase (match-string 1)))) (if (eq (vhdl-decision-query "configuration" "(b)lock or (c)omponent configuration?" t) ?c) (vhdl-template-component-conf) (vhdl-template-block-configuration))) (t (vhdl-template-configuration-decl)))))) ; otherwise (defun vhdl-template-configuration-spec (&optional optional-use) "Insert a configuration specification." (interactive) (let ((margin (current-indentation)) (start (point)) aspect position) (vhdl-insert-keyword "FOR ") (when (vhdl-template-field "component names | OTHERS | ALL" " : " t start (point)) (vhdl-template-field "component type" "\n") (indent-to (+ margin vhdl-basic-offset)) (setq start (point)) (vhdl-insert-keyword "USE ") (if (and optional-use (not (setq aspect (vhdl-template-field "[ENTITY | CONFIGURATION | OPEN]" " " t)))) (progn (delete-region start (point)) 'no-use) (unless optional-use (setq aspect (vhdl-template-field "ENTITY | CONFIGURATION | OPEN" " "))) (setq aspect (upcase (or aspect ""))) (cond ((equal aspect "ENTITY") (vhdl-template-field "library name" "." nil nil nil nil "work") (vhdl-template-field "entity name" "(") (if (vhdl-template-field "[architecture name]" nil t) (insert ")") (delete-char -1)) (insert "\n") (indent-to (+ margin (* 2 vhdl-basic-offset))) (setq position (point)) (vhdl-insert-keyword "GENERIC ") (when (vhdl-template-map position t t) (insert "\n") (indent-to (+ margin (* 2 vhdl-basic-offset)))) (setq position (point)) (vhdl-insert-keyword "PORT ") (unless (vhdl-template-map position t t) (kill-line -0) (delete-char -1)) (insert ";") t) ((equal aspect "CONFIGURATION") (vhdl-template-field "library name" "." nil nil nil nil "work") (vhdl-template-field "configuration name" ";")) (t (backward-delete-char 1) (insert ";") t)))))) (defun vhdl-template-configuration-decl () "Insert a configuration declaration." (interactive) (let ((margin (current-indentation)) (start (point)) (case-fold-search t) entity-exists string name position) (vhdl-insert-keyword "CONFIGURATION ") (when (setq name (vhdl-template-field "name" nil t start (point))) (vhdl-insert-keyword " OF ") (save-excursion (vhdl-ext-syntax-table (setq entity-exists (re-search-backward "\\<entity \\(\\w*\\) is\\>" nil t)) (setq string (match-string 1)))) (if (and entity-exists (not (equal string ""))) (insert string) (vhdl-template-field "entity name")) (vhdl-insert-keyword " IS\n") (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n")) (indent-to (+ margin vhdl-basic-offset)) (setq position (point)) (insert "\n") (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n")) (indent-to margin) (vhdl-insert-keyword "END ") (unless (vhdl-standard-p '87) (vhdl-insert-keyword "CONFIGURATION ")) (insert name ";") (goto-char position)))) (defun vhdl-template-constant () "Insert a constant declaration." (interactive) (let ((start (point)) (in-arglist (vhdl-in-argument-list-p))) (vhdl-insert-keyword "CONSTANT ") (when (vhdl-template-field "name" nil t start (point)) (insert " : ") (when in-arglist (vhdl-insert-keyword "IN ")) (vhdl-template-field "type") (if in-arglist (progn (insert ";") (vhdl-comment-insert-inline)) (let ((position (point))) (insert " := ") (unless (vhdl-template-field "[initialization]" nil t) (delete-region position (point))) (insert ";") (vhdl-comment-insert-inline)))))) (defun vhdl-template-default () "Insert nothing." (interactive) (insert " ") (unexpand-abbrev) (backward-word 1) (vhdl-case-word 1) (forward-char 1)) (defun vhdl-template-default-indent () "Insert nothing and indent." (interactive) (insert " ") (unexpand-abbrev) (backward-word 1) (vhdl-case-word 1) (forward-char 1) (vhdl-indent-line)) (defun vhdl-template-disconnect () "Insert a disconnect statement." (interactive) (let ((start (point))) (vhdl-insert-keyword "DISCONNECT ") (when (vhdl-template-field "signal names | OTHERS | ALL" " : " t start (point)) (vhdl-template-field "type") (vhdl-insert-keyword " AFTER ") (vhdl-template-field "time expression" ";")))) (defun vhdl-template-else () "Insert an else statement." (interactive) (let ((case-fold-search t) margin) (vhdl-ext-syntax-table (vhdl-insert-keyword "ELSE") (if (save-excursion (re-search-backward "\\(\\<when\\>\\|;\\)" nil t) (equal "WHEN" (upcase (match-string 1)))) (insert " ") (vhdl-indent-line) (setq margin (current-indentation)) (insert "\n") (indent-to (+ margin vhdl-basic-offset)))))) (defun vhdl-template-elsif () "Insert an elsif statement." (interactive) (let ((start (point)) margin) (vhdl-insert-keyword "ELSIF ") (when vhdl-conditions-in-parenthesis (insert "(")) (when (vhdl-template-field "condition" nil t start (point)) (when vhdl-conditions-in-parenthesis (insert ")")) (vhdl-indent-line) (setq margin (current-indentation)) (vhdl-insert-keyword (concat " " (if (vhdl-sequential-statement-p) "THEN" "USE") "\n")) (indent-to (+ margin vhdl-basic-offset))))) (defun vhdl-template-entity () "Insert an entity." (interactive) (let ((margin (current-indentation)) (start (point)) name end-column) (vhdl-insert-keyword "ENTITY ") (when (setq name (vhdl-template-field "name" nil t start (point))) (vhdl-insert-keyword " IS\n\n") (indent-to margin) (vhdl-insert-keyword "END ") (unless (vhdl-standard-p '87) (vhdl-insert-keyword "ENTITY ")) (insert name ";") (setq end-column (current-column)) (end-of-line -0) (indent-to (+ margin vhdl-basic-offset)) (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n")) (indent-to (+ margin vhdl-basic-offset)) (when (vhdl-template-generic-list t) (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n"))) (insert "\n") (indent-to (+ margin vhdl-basic-offset)) (when (vhdl-template-port-list t) (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n"))) (beginning-of-line 2) (forward-char end-column)))) (defun vhdl-template-exit () "Insert an exit statement." (interactive) (let ((start (point))) (vhdl-insert-keyword "EXIT ") (unless (vhdl-template-field "[loop label]" nil t) (delete-char -1)) (let ((position (point))) (vhdl-insert-keyword " WHEN ") (when vhdl-conditions-in-parenthesis (insert "(")) (if (vhdl-template-field "[condition]" nil t) (when vhdl-conditions-in-parenthesis (insert ")")) (delete-region position (point)))) (insert ";"))) (defun vhdl-template-file () "Insert a file declaration." (interactive) (let ((start (point))) (vhdl-insert-keyword "FILE ") (when (vhdl-template-field "name" nil t start (point)) (insert " : ") (vhdl-template-field "type") (unless (vhdl-standard-p '87) (vhdl-insert-keyword " OPEN ") (unless (vhdl-template-field "[READ_MODE | WRITE_MODE | APPEND_MODE]" nil t) (backward-delete-char 6))) (vhdl-insert-keyword " IS ") (when (vhdl-standard-p '87) (vhdl-template-field "[IN | OUT]" " " t)) (vhdl-template-field "filename-string" nil nil nil nil t) (insert ";") (vhdl-comment-insert-inline)))) (defun vhdl-template-for () "Insert a block or component configuration if within a configuration declaration, a configuration specification if within an architecture declarative part (and not within a subprogram), and a for-loop otherwise." (interactive) (let ((case-fold-search t)) (vhdl-ext-syntax-table (cond ((and (save-excursion ; configuration declaration (re-search-backward "^\\(configuration\\|end\\)\\>" nil t)) (equal "CONFIGURATION" (upcase (match-string 1)))) (if (eq (vhdl-decision-query "for" "(b)lock or (c)omponent configuration?" t) ?c) (vhdl-template-component-conf) (vhdl-template-block-configuration))) ((and (save-excursion (re-search-backward ; architecture declarative part "^\\(architecture\\|entity\\|begin\\|end\\)\\>" nil t)) (equal "ARCHITECTURE" (upcase (match-string 1))) (not (and (save-excursion ; not subprogram (re-search-backward "^\\s-*\\(architecture\\|begin\\|end\\)\\>" nil t)) (equal "BEGIN" (upcase (match-string 1))) (save-excursion (re-search-backward "^\\s-*\\(function\\|procedure\\)\\>" nil t))))) (vhdl-template-configuration-spec)) ((vhdl-sequential-statement-p) ; sequential statement (vhdl-template-for-loop)) (t (vhdl-template-for-generate)))))) ; concurrent statement (defun vhdl-template-for-generate () "Insert a for-generate." (interactive) (let ((margin (current-indentation)) (start (point)) label string position) (vhdl-insert-keyword ": FOR ") (setq position (point-marker)) (goto-char start) (when (setq label (vhdl-template-field "label" nil t start position)) (goto-char position) (vhdl-template-field "loop variable") (vhdl-insert-keyword " IN ") (vhdl-template-field "range") (vhdl-template-generate-body margin label)))) (defun vhdl-template-for-loop () "Insert a for loop." (interactive) (let ((margin (current-indentation)) (start (point)) label index) (if (not (eq vhdl-optional-labels 'all)) (vhdl-insert-keyword "FOR ") (vhdl-insert-keyword ": FOR ") (goto-char start) (setq label (vhdl-template-field "[label]" nil t)) (unless label (delete-char 2)) (forward-word 1) (forward-char 1)) (when (setq index (vhdl-template-field "loop variable" nil t start (point))) (vhdl-insert-keyword " IN ") (vhdl-template-field "range") (vhdl-insert-keyword " LOOP\n\n") (indent-to margin) (vhdl-insert-keyword "END LOOP") (if label (insert " " label ";") (insert ";") (when vhdl-self-insert-comments (insert " -- " index))) (forward-line -1) (indent-to (+ margin vhdl-basic-offset))))) (defun vhdl-template-footer () "Insert a VHDL file footer." (interactive) (unless (equal vhdl-file-footer "") (save-excursion (goto-char (point-max)) (insert "\n") (vhdl-insert-string-or-file vhdl-file-footer)))) (defun vhdl-template-function (&optional kind) "Insert a function declaration or body." (interactive) (let ((margin (current-indentation)) (start (point)) name) (vhdl-insert-keyword "FUNCTION ") (when (setq name (vhdl-template-field "name" nil t start (point))) (vhdl-template-argument-list t) (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1)) (end-of-line) (insert "\n") (indent-to (+ margin vhdl-basic-offset)) (vhdl-insert-keyword "RETURN ") (vhdl-template-field "type") (if (if kind (eq kind 'body) (eq (vhdl-decision-query nil "(d)eclaration or (b)ody?") ?b)) (progn (vhdl-insert-keyword " IS") (vhdl-template-begin-end (unless (vhdl-standard-p '87) "FUNCTION") name margin) (vhdl-comment-block)) (insert ";"))))) (defun vhdl-template-function-decl () "Insert a function declaration." (interactive) (vhdl-template-function 'decl)) (defun vhdl-template-function-body () "Insert a function declaration." (interactive) (vhdl-template-function 'body)) (defun vhdl-template-generate () "Insert a generation scheme." (interactive) (if (eq (vhdl-decision-query nil "(f)or or (i)f?" t) ?i) (vhdl-template-if-generate) (vhdl-template-for-generate))) (defun vhdl-template-generic () "Insert generic declaration, or generic map in instantiation statements." (interactive) (let ((start (point)) (case-fold-search t)) (vhdl-ext-syntax-table (cond ((and (save-excursion ; entity declaration (re-search-backward "^\\(entity\\|end\\)\\>" nil t)) (equal "ENTITY" (upcase (match-string 1)))) (vhdl-template-generic-list nil)) ((or (save-excursion (or (beginning-of-line) (looking-at "^\\s-*\\w+\\s-*:\\s-*\\w+"))) (equal 'statement-cont (car (car (vhdl-get-syntactic-context))))) (vhdl-insert-keyword "GENERIC ") (vhdl-template-map start)) (t (vhdl-template-generic-list nil t)))))) (defun vhdl-template-group () "Insert group or group template declaration." (interactive) (let ((start (point))) (if (eq (vhdl-decision-query "group" "(d)eclaration or (t)emplate declaration?" t) ?t) (vhdl-template-group-template) (vhdl-template-group-decl)))) (defun vhdl-template-group-decl () "Insert group declaration." (interactive) (let ((start (point))) (vhdl-insert-keyword "GROUP ") (when (vhdl-template-field "name" " : " t start (point)) (vhdl-template-field "template name" " (") (vhdl-template-field "constituent list" ");") (vhdl-comment-insert-inline)))) (defun vhdl-template-group-template () "Insert group template declaration." (interactive) (let ((start (point))) (vhdl-insert-keyword "GROUP ") (when (vhdl-template-field "template name" nil t start (point)) (vhdl-insert-keyword " IS (") (vhdl-template-field "entity class list" ");") (vhdl-comment-insert-inline)))) (defun vhdl-template-header () "Insert a VHDL file header." (interactive) (unless (equal vhdl-file-header "") (let ((case-fold-search t) (project-name (or (nth 0 (aget vhdl-project-alist vhdl-project)) "")) (project-desc (or (nth 2 (aget vhdl-project-alist vhdl-project)) "")) eot) (vhdl-ext-syntax-table (save-excursion (save-restriction (widen) (goto-char (point-min)) (vhdl-insert-string-or-file vhdl-file-header) (setq eot (point)) (narrow-to-region (point-min) eot) (goto-char (point-min)) (while (search-forward "<projectdesc>" nil t) (replace-match project-desc t t)) (goto-char (point-min)) (while (search-forward "<filename>" nil t) (replace-match (buffer-name) t t)) (goto-char (point-min)) (while (search-forward "<author>" nil t) (replace-match "" t t) (insert (user-full-name)) (when user-mail-address (insert " <" user-mail-address ">"))) (goto-char (point-min)) (while (search-forward "<login>" nil t) (replace-match (user-login-name) t t)) (goto-char (point-min)) (while (search-forward "<project>" nil t) (replace-match project-name t t)) (goto-char (point-min)) (while (search-forward "<company>" nil t) (replace-match vhdl-company-name t t)) (goto-char (point-min)) (while (search-forward "<platform>" nil t) (replace-match vhdl-platform-spec t t)) (goto-char (point-min)) ;; Replace <RCS> with $, so that RCS for the source is ;; not over-enthusiastic with replacements (while (search-forward "<RCS>" nil t) (replace-match "$" nil t)) (goto-char (point-min)) (while (search-forward "<date>" nil t) (replace-match "" t t) (vhdl-template-insert-date)) (goto-char (point-min)) (let (string) (while (re-search-forward "<\\(\\(\\w\\|\\s_\\)*\\) string>" nil t) (setq string (read-string (concat (match-string 1) ": "))) (replace-match string t t))))) (goto-char (point-min)) (when (search-forward "<cursor>" nil t) (replace-match "" t t)) (when (or (not project-name) (equal project-name "")) (message "You can specify a project title in custom variable `vhdl-project-alist'")) (when (or (not project-desc) (equal project-desc "")) (message "You can specify a project description in custom variable `vhdl-project-alist'")) (when (equal vhdl-company-name "") (message "You can specify a company name in custom variable `vhdl-company-name'")) (when (equal vhdl-platform-spec "") (message "You can specify a platform in custom variable `vhdl-platform-spec'")))))) (defun vhdl-template-if () "Insert a sequential if statement or an if-generate statement." (interactive) (if (vhdl-sequential-statement-p) (vhdl-template-if-then) (if (and (vhdl-standard-p 'ams) (eq (vhdl-decision-query "if" "(g)enerate or (u)se?" t) ?u)) (vhdl-template-if-use) (vhdl-template-if-generate)))) (defun vhdl-template-if-generate () "Insert an if-generate." (interactive) (let ((margin (current-indentation)) (start (point)) label string position) (vhdl-insert-keyword ": IF ") (setq position (point-marker)) (goto-char start) (when (setq label (vhdl-template-field "label" nil t start position)) (goto-char position) (when vhdl-conditions-in-parenthesis (insert "(")) (vhdl-template-field "condition") (when vhdl-conditions-in-parenthesis (insert ")")) (vhdl-template-generate-body margin label)))) (defun vhdl-template-if-then-use (kind) "Insert a sequential if statement." (interactive) (let ((margin (current-indentation)) (start (point)) label) (if (or (not (eq vhdl-optional-labels 'all)) (vhdl-standard-p '87)) (vhdl-insert-keyword "IF ") (vhdl-insert-keyword ": IF ") (goto-char start) (setq label (vhdl-template-field "[label]" nil t)) (unless label (delete-char 2)) (forward-word 1) (forward-char 1)) (when vhdl-conditions-in-parenthesis (insert "(")) (when (vhdl-template-field "condition" nil t start (point)) (when vhdl-conditions-in-parenthesis (insert ")")) (vhdl-insert-keyword (concat " " (if (eq kind 'then) "THEN" "USE") "\n\n")) (indent-to margin) (vhdl-insert-keyword "END IF") (when label (insert " " label)) (insert ";") (forward-line -1) (indent-to (+ margin vhdl-basic-offset))))) (defun vhdl-template-if-then () "Insert a sequential if statement." (interactive) (vhdl-template-if-then-use 'then)) (defun vhdl-template-if-use () "Insert a simultaneous if statement." (interactive) (vhdl-template-if-then-use 'use)) (defun vhdl-template-instance () "Insert a component instantiation statement." (interactive) (vhdl-template-component-inst)) (defun vhdl-template-library () "Insert a library specification." (interactive) (let ((margin (current-indentation)) (start (point)) name end-pos) (vhdl-insert-keyword "LIBRARY ") (when (setq name (vhdl-template-field "names" nil t start (point))) (insert ";") (unless (string-match "," name) (setq end-pos (point)) (insert "\n") (indent-to margin) (vhdl-insert-keyword "USE ") (insert name) (vhdl-insert-keyword "..ALL;") (backward-char 5) (if (vhdl-template-field "package name") (forward-char 5) (delete-region end-pos (+ (point) 5))))))) (defun vhdl-template-limit () "Insert a limit." (interactive) (let ((start (point))) (vhdl-insert-keyword "LIMIT ") (when (vhdl-template-field "quantity names | OTHERS | ALL" " : " t start (point)) (vhdl-template-field "type") (vhdl-insert-keyword " WITH ") (vhdl-template-field "real expression" ";")))) (defun vhdl-template-loop () "Insert a loop." (interactive) (let ((char (vhdl-decision-query nil "(w)hile, (f)or, or (b)are?" t))) (cond ((eq char ?w) (vhdl-template-while-loop)) ((eq char ?f) (vhdl-template-for-loop)) (t (vhdl-template-bare-loop))))) (defun vhdl-template-bare-loop () "Insert a loop." (interactive) (let ((margin (current-indentation)) (start (point)) label) (if (not (eq vhdl-optional-labels 'all)) (vhdl-insert-keyword "LOOP ") (vhdl-insert-keyword ": LOOP ") (goto-char start) (setq label (vhdl-template-field "[label]" nil t)) (unless label (delete-char 2)) (forward-word 1) (delete-char 1)) (insert "\n\n") (indent-to margin) (vhdl-insert-keyword "END LOOP") (insert (if label (concat " " label ";") ";")) (forward-line -1) (indent-to (+ margin vhdl-basic-offset)))) (defun vhdl-template-map (&optional start optional secondary) "Insert a map specification with association list." (interactive) (let ((start (or start (point))) margin end-pos) (vhdl-insert-keyword "MAP (") (if (not vhdl-association-list-with-formals) (if (vhdl-template-field (concat (and optional "[") "association list" (and optional "]")) ")" (or (not secondary) optional) (and (not secondary) start) (point)) t (if (and optional secondary) (delete-region start (point))) nil) (if vhdl-argument-list-indent (setq margin (current-column)) (setq margin (+ (current-indentation) vhdl-basic-offset)) (insert "\n") (indent-to margin)) (if (vhdl-template-field (concat (and optional "[") "formal" (and optional "]")) " => " (or (not secondary) optional) (and (not secondary) start) (point)) (progn (vhdl-template-field "actual" ",") (setq end-pos (point)) (insert "\n") (indent-to margin) (while (vhdl-template-field "[formal]" " => " t) (vhdl-template-field "actual" ",") (setq end-pos (point)) (insert "\n") (indent-to margin)) (delete-region end-pos (point)) (backward-delete-char 1) (insert ")") (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1)) t) (when (and optional secondary) (delete-region start (point))) nil)))) (defun vhdl-template-modify (&optional noerror) "Actualize modification date." (interactive) (let ((case-fold-search t)) (vhdl-ext-syntax-table (save-excursion (goto-char (point-min)) (if (re-search-forward vhdl-modify-date-prefix-string nil t) (progn (kill-line) (vhdl-template-insert-date)) (unless noerror (error (concat "Modification date prefix string \"" vhdl-modify-date-prefix-string "\" not found")))))))) (defun vhdl-template-modify-noerror () "Call `vhdl-template-modify' with NOERROR non-nil." (vhdl-template-modify t)) (defun vhdl-template-nature () "Insert a nature declaration." (interactive) (let ((start (point)) name mid-pos end-pos) (vhdl-insert-keyword "NATURE ") (when (setq name (vhdl-template-field "name" nil t start (point))) (vhdl-insert-keyword " IS ") (let ((definition (upcase (or (vhdl-template-field "across type | ARRAY | RECORD") "")))) (cond ((equal definition "") (insert ";")) ((equal definition "ARRAY") (kill-word -1) (vhdl-template-array 'nature t)) ((equal definition "RECORD") (setq mid-pos (point-marker)) (kill-word -1) (vhdl-template-record 'nature name t)) (t (vhdl-insert-keyword " ACROSS ") (vhdl-template-field "through type") (vhdl-insert-keyword " THROUGH ") (vhdl-template-field "reference name") (vhdl-insert-keyword " REFERENCE;"))) (when mid-pos (setq end-pos (point-marker)) (goto-char mid-pos) (end-of-line)) (vhdl-comment-insert-inline) (when end-pos (goto-char end-pos)))))) (defun vhdl-template-next () "Insert a next statement." (interactive) (vhdl-insert-keyword "NEXT ") (unless (vhdl-template-field "[loop label]" nil t) (delete-char -1)) (let ((position (point))) (vhdl-insert-keyword " WHEN ") (when vhdl-conditions-in-parenthesis (insert "(")) (if (vhdl-template-field "[condition]" nil t) (when vhdl-conditions-in-parenthesis (insert ")")) (delete-region position (point))) (insert ";"))) (defun vhdl-template-others () "Insert an others aggregate." (interactive) (vhdl-insert-keyword "(OTHERS => '')") (backward-char 2)) (defun vhdl-template-package (&optional kind) "Insert a package specification or body." (interactive) (let ((margin (current-indentation)) (start (point)) name body position) (vhdl-insert-keyword "PACKAGE ") (setq body (if kind (eq kind 'body) (eq (vhdl-decision-query nil "(d)eclaration or (b)ody?") ?b))) (when body (vhdl-insert-keyword "BODY ")) (when (setq name (vhdl-template-field "name" nil t start (point))) (vhdl-insert-keyword " IS\n") (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n")) (indent-to (+ margin vhdl-basic-offset)) (setq position (point)) (insert "\n") (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n")) (indent-to margin) (vhdl-insert-keyword "END ") (unless (vhdl-standard-p '87) (vhdl-insert-keyword (concat "PACKAGE " (and body "BODY ")))) (insert (or name "") ";") (goto-char position)))) (defun vhdl-template-package-decl () "Insert a package specification." (interactive) (vhdl-template-package 'decl)) (defun vhdl-template-package-body () "Insert a package body." (interactive) (vhdl-template-package 'body)) (defun vhdl-template-port () "Insert a port declaration, or port map in instantiation statements." (interactive) (let ((start (point)) (case-fold-search t)) (vhdl-ext-syntax-table (cond ((and (save-excursion ; entity declaration (re-search-backward "^\\(entity\\|end\\)\\>" nil t)) (equal "ENTITY" (upcase (match-string 1)))) (vhdl-template-port-list nil)) ((or (save-excursion (or (beginning-of-line) (looking-at "^\\s-*\\w+\\s-*:\\s-*\\w+"))) (equal 'statement-cont (car (car (vhdl-get-syntactic-context))))) (vhdl-insert-keyword "PORT ") (vhdl-template-map start)) (t (vhdl-template-port-list nil)))))) (defun vhdl-template-procedural () "Insert a procedural." (interactive) (let ((margin (current-indentation)) (start (point)) (case-fold-search t) label) (vhdl-insert-keyword "PROCEDURAL ") (when (memq vhdl-optional-labels '(process all)) (goto-char start) (insert ": ") (goto-char start) (setq label (vhdl-template-field "[label]" nil t)) (unless label (delete-char 2)) (forward-word 1) (forward-char 1)) (unless (vhdl-standard-p '87) (vhdl-insert-keyword "IS")) (vhdl-template-begin-end "PROCEDURAL" label margin) (vhdl-comment-block))) (defun vhdl-template-procedure (&optional kind) "Insert a procedure declaration or body." (interactive) (let ((margin (current-indentation)) (start (point)) name) (vhdl-insert-keyword "PROCEDURE ") (when (setq name (vhdl-template-field "name" nil t start (point))) (vhdl-template-argument-list) (if (if kind (eq kind 'body) (eq (vhdl-decision-query nil "(d)eclaration or (b)ody?") ?b)) (progn (vhdl-insert-keyword " IS") (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1)) (end-of-line) (vhdl-template-begin-end (unless (vhdl-standard-p '87) "PROCEDURE") name margin) (vhdl-comment-block)) (insert ";") (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1)) (end-of-line))))) (defun vhdl-template-procedure-decl () "Insert a procedure declaration." (interactive) (vhdl-template-procedure 'decl)) (defun vhdl-template-procedure-body () "Insert a procedure body." (interactive) (vhdl-template-procedure 'body)) (defun vhdl-template-process (&optional kind) "Insert a process." (interactive) (let ((margin (current-indentation)) (start (point)) (case-fold-search t) label seq input-signals clock reset final-pos) (setq seq (if kind (eq kind 'seq) (eq (vhdl-decision-query "process" "(c)ombinational or (s)equential?" t) ?s))) (vhdl-insert-keyword "PROCESS ") (when (memq vhdl-optional-labels '(process all)) (goto-char start) (insert ": ") (goto-char start) (setq label (vhdl-template-field "[label]" nil t)) (unless label (delete-char 2)) (forward-word 1) (forward-char 1)) (insert "(") (if (not seq) (unless (setq input-signals (vhdl-template-field "[sensitivity list]" ")" t)) (setq input-signals "") (delete-char -2)) (setq clock (or (and (not (equal "" vhdl-clock-name)) (progn (insert vhdl-clock-name) vhdl-clock-name)) (vhdl-template-field "clock name") "<clock>")) (when (eq vhdl-reset-kind 'async) (insert ", ") (setq reset (or (and (not (equal "" vhdl-reset-name)) (progn (insert vhdl-reset-name) vhdl-reset-name)) (vhdl-template-field "reset name") "<reset>"))) (insert ")")) (unless (vhdl-standard-p '87) (vhdl-insert-keyword " IS")) (vhdl-template-begin-end "PROCESS" label margin) (when seq (setq reset (vhdl-template-seq-process clock reset))) (when vhdl-prompt-for-comments (setq final-pos (point-marker)) (vhdl-ext-syntax-table (when (and (re-search-backward "\\<begin\\>" nil t) (re-search-backward "\\<process\\>" nil t)) (end-of-line -0) (if (bobp) (progn (insert "\n") (forward-line -1)) (insert "\n")) (indent-to margin) (insert "-- purpose: ") (if (not (vhdl-template-field "[description]" nil t)) (vhdl-line-kill-entire) (insert "\n") (indent-to margin) (insert "-- type : ") (insert (if seq "sequential" "combinational") "\n") (indent-to margin) (insert "-- inputs : ") (if (not seq) (insert input-signals) (insert clock ", ") (when reset (insert reset ", ")) (unless (vhdl-template-field "[signal names]" nil t) (delete-char -2))) (insert "\n") (indent-to margin) (insert "-- outputs: ") (vhdl-template-field "[signal names]" nil t)))) (goto-char final-pos)))) (defun vhdl-template-process-comb () "Insert a combinational process." (interactive) (vhdl-template-process 'comb)) (defun vhdl-template-process-seq () "Insert a sequential process." (interactive) (vhdl-template-process 'seq)) (defun vhdl-template-quantity () "Insert a quantity declaration." (interactive) (if (vhdl-in-argument-list-p) (let ((start (point))) (vhdl-insert-keyword "QUANTITY ") (when (vhdl-template-field "names" nil t start (point)) (insert " : ") (vhdl-template-field "[IN | OUT]" " " t) (vhdl-template-field "type") (insert ";") (vhdl-comment-insert-inline))) (let ((char (vhdl-decision-query "quantity" "(f)ree, (b)ranch, or (s)ource quantity?" t))) (cond ((eq char ?f) (vhdl-template-quantity-free)) ((eq char ?b) (vhdl-template-quantity-branch)) ((eq char ?s) (vhdl-template-quantity-source)) (t (vhdl-template-undo (point) (point))))))) (defun vhdl-template-quantity-free () "Insert a free quantity declaration." (interactive) (vhdl-insert-keyword "QUANTITY ") (vhdl-template-field "names") (insert " : ") (vhdl-template-field "type") (let ((position (point))) (insert " := ") (unless (vhdl-template-field "[initialization]" nil t) (delete-region position (point))) (insert ";") (vhdl-comment-insert-inline))) (defun vhdl-template-quantity-branch () "Insert a branch quantity declaration." (interactive) (let (position) (vhdl-insert-keyword "QUANTITY ") (when (vhdl-template-field "[across names]" " " t) (vhdl-insert-keyword "ACROSS ")) (when (vhdl-template-field "[through names]" " " t) (vhdl-insert-keyword "THROUGH ")) (vhdl-template-field "plus terminal name") (setq position (point)) (vhdl-insert-keyword " TO ") (unless (vhdl-template-field "[minus terminal name]" nil t) (delete-region position (point))) (insert ";") (vhdl-comment-insert-inline))) (defun vhdl-template-quantity-source () "Insert a source quantity declaration." (interactive) (vhdl-insert-keyword "QUANTITY ") (vhdl-template-field "names") (insert " : ") (vhdl-template-field "type" " ") (if (eq (vhdl-decision-query nil "(s)pectrum or (n)oise?") ?n) (progn (vhdl-insert-keyword "NOISE ") (vhdl-template-field "power expression")) (vhdl-insert-keyword "SPECTRUM ") (vhdl-template-field "magnitude expression" ", ") (vhdl-template-field "phase expression")) (insert ";") (vhdl-comment-insert-inline)) (defun vhdl-template-record (kind &optional name secondary) "Insert a record type declaration." (interactive) (let ((margin (current-column)) (start (point)) (first t)) (vhdl-insert-keyword "RECORD\n") (indent-to (+ margin vhdl-basic-offset)) (when (or (vhdl-template-field "element names" nil (not secondary) start (point)) secondary) (while (or first (vhdl-template-field "[element names]" nil t)) (insert " : ") (vhdl-template-field (if (eq kind 'type) "type" "nature") ";") (vhdl-comment-insert-inline) (insert "\n") (indent-to (+ margin vhdl-basic-offset)) (setq first nil)) (kill-line -0) (indent-to margin) (vhdl-insert-keyword "END RECORD") (unless (vhdl-standard-p '87) (and name (insert " " name))) (insert ";") (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1))))) (defun vhdl-template-report () "Insert a report statement." (interactive) (let ((start (point))) (vhdl-insert-keyword "REPORT ") (if (equal "\"\"" (vhdl-template-field "string expression" nil t start (point) t)) (backward-delete-char 2) (setq start (point)) (vhdl-insert-keyword " SEVERITY ") (unless (vhdl-template-field "[NOTE | WARNING | ERROR | FAILURE]" nil t) (delete-region start (point))) (insert ";")))) (defun vhdl-template-return () "Insert a return statement." (interactive) (vhdl-insert-keyword "RETURN ") (unless (vhdl-template-field "[expression]" nil t) (delete-char -1)) (insert ";")) (defun vhdl-template-selected-signal-asst () "Insert a selected signal assignment." (interactive) (let ((margin (current-indentation)) (start (point)) (choices t)) (let ((position (point))) (vhdl-insert-keyword " SELECT ") (goto-char position)) (vhdl-insert-keyword "WITH ") (when (vhdl-template-field "selector expression" nil t start (+ (point) 7)) (forward-word 1) (delete-char 1) (insert "\n") (indent-to (+ margin vhdl-basic-offset)) (vhdl-template-field "target signal" " <= ") ; (vhdl-template-field "[GUARDED] [TRANSPORT]") (insert "\n") (indent-to (+ margin vhdl-basic-offset)) (vhdl-template-field "waveform") (vhdl-insert-keyword " WHEN ") (vhdl-template-field "choices" ",") (insert "\n") (indent-to (+ margin vhdl-basic-offset)) (while (and choices (vhdl-template-field "[waveform]" nil t)) (vhdl-insert-keyword " WHEN ") (if (setq choices (vhdl-template-field "[choices]" "," t)) (progn (insert "\n") (indent-to (+ margin vhdl-basic-offset))) (vhdl-insert-keyword "OTHERS"))) (when choices (fixup-whitespace) (delete-char -2)) (insert ";") (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1))))) (defun vhdl-template-signal () "Insert a signal declaration." (interactive) (let ((start (point)) (in-arglist (vhdl-in-argument-list-p))) (vhdl-insert-keyword "SIGNAL ") (when (vhdl-template-field "names" nil t start (point)) (insert " : ") (when in-arglist (vhdl-template-field "[IN | OUT | INOUT]" " " t)) (vhdl-template-field "type") (if in-arglist (progn (insert ";") (vhdl-comment-insert-inline)) (let ((position (point))) (insert " := ") (unless (vhdl-template-field "[initialization]" nil t) (delete-region position (point))) (insert ";") (vhdl-comment-insert-inline)))))) (defun vhdl-template-subnature () "Insert a subnature declaration." (interactive) (let ((start (point)) position) (vhdl-insert-keyword "SUBNATURE ") (when (vhdl-template-field "name" nil t start (point)) (vhdl-insert-keyword " IS ") (vhdl-template-field "nature" " (") (if (vhdl-template-field "[index range]" nil t) (insert ")") (delete-char -2)) (setq position (point)) (vhdl-insert-keyword " TOLERANCE ") (if (equal "\"\"" (vhdl-template-field "[string expression]" nil t nil nil t)) (delete-region position (point)) (vhdl-insert-keyword " ACROSS ") (vhdl-template-field "string expression" nil nil nil nil t) (vhdl-insert-keyword " THROUGH")) (insert ";") (vhdl-comment-insert-inline)))) (defun vhdl-template-subprogram-body () "Insert a subprogram body." (interactive) (if (eq (vhdl-decision-query nil "(p)rocedure or (f)unction?" t) ?f) (vhdl-template-function-body) (vhdl-template-procedure-body))) (defun vhdl-template-subprogram-decl () "Insert a subprogram declaration." (interactive) (if (eq (vhdl-decision-query nil "(p)rocedure or (f)unction?" t) ?f) (vhdl-template-function-decl) (vhdl-template-procedure-decl))) (defun vhdl-template-subtype () "Insert a subtype declaration." (interactive) (let ((start (point))) (vhdl-insert-keyword "SUBTYPE ") (when (vhdl-template-field "name" nil t start (point)) (vhdl-insert-keyword " IS ") (vhdl-template-field "type" " ") (unless (vhdl-template-field "[RANGE value range | ( index range )]" nil t) (delete-char -1)) (insert ";") (vhdl-comment-insert-inline)))) (defun vhdl-template-terminal () "Insert a terminal declaration." (interactive) (let ((start (point))) (vhdl-insert-keyword "TERMINAL ") (when (vhdl-template-field "names" nil t start (point)) (insert " : ") (vhdl-template-field "nature") (insert ";") (vhdl-comment-insert-inline)))) (defun vhdl-template-type () "Insert a type declaration." (interactive) (let ((start (point)) name mid-pos end-pos) (vhdl-insert-keyword "TYPE ") (when (setq name (vhdl-template-field "name" nil t start (point))) (vhdl-insert-keyword " IS ") (let ((definition (upcase (or (vhdl-template-field "[scalar type | ARRAY | RECORD | ACCESS | FILE]" nil t) "")))) (cond ((equal definition "") (backward-delete-char 4) (insert ";")) ((equal definition "ARRAY") (kill-word -1) (vhdl-template-array 'type t)) ((equal definition "RECORD") (setq mid-pos (point-marker)) (kill-word -1) (vhdl-template-record 'type name t)) ((equal definition "ACCESS") (insert " ") (vhdl-template-field "type" ";")) ((equal definition "FILE") (vhdl-insert-keyword " OF ") (vhdl-template-field "type" ";")) (t (insert ";"))) (when mid-pos (setq end-pos (point-marker)) (goto-char mid-pos) (end-of-line)) (vhdl-comment-insert-inline) (when end-pos (goto-char end-pos)))))) (defun vhdl-template-use () "Insert a use clause." (interactive) (let ((start (point)) (case-fold-search t)) (vhdl-ext-syntax-table (vhdl-insert-keyword "USE ") (when (save-excursion (beginning-of-line) (looking-at "^\\s-*use\\>")) (vhdl-insert-keyword "..ALL;") (backward-char 6) (when (vhdl-template-field "library name" nil t start (+ (point) 6)) (forward-char 1) (vhdl-template-field "package name") (forward-char 5)))))) (defun vhdl-template-variable () "Insert a variable declaration." (interactive) (let ((start (point)) (case-fold-search t) (in-arglist (vhdl-in-argument-list-p))) (vhdl-ext-syntax-table (if (or (save-excursion (and (re-search-backward "\\<function\\|procedure\\|process\\|procedural\\|end\\>" nil t) (not (progn (backward-word 1) (looking-at "\\<end\\>"))))) (save-excursion (backward-word 1) (looking-at "\\<shared\\>"))) (vhdl-insert-keyword "VARIABLE ") (vhdl-insert-keyword "SHARED VARIABLE "))) (when (vhdl-template-field "names" nil t start (point)) (insert " : ") (when in-arglist (vhdl-template-field "[IN | OUT | INOUT]" " " t)) (vhdl-template-field "type") (if in-arglist (progn (insert ";") (vhdl-comment-insert-inline)) (let ((position (point))) (insert " := ") (unless (vhdl-template-field "[initialization]" nil t) (delete-region position (point))) (insert ";") (vhdl-comment-insert-inline)))))) (defun vhdl-template-wait () "Insert a wait statement." (interactive) (vhdl-insert-keyword "WAIT ") (unless (vhdl-template-field "[ON sensitivity list] [UNTIL condition] [FOR time expression]" nil t) (delete-char -1)) (insert ";")) (defun vhdl-template-when () "Indent correctly if within a case statement." (interactive) (let ((position (point)) (case-fold-search t) margin) (vhdl-ext-syntax-table (if (and (= (current-column) (current-indentation)) (re-search-forward "\\<end\\>" nil t) (looking-at "\\s-*\\<case\\>")) (progn (setq margin (current-indentation)) (goto-char position) (delete-horizontal-space) (indent-to (+ margin vhdl-basic-offset))) (goto-char position))) (vhdl-insert-keyword "WHEN "))) (defun vhdl-template-while-loop () "Insert a while loop." (interactive) (let* ((margin (current-indentation)) (start (point)) label) (if (not (eq vhdl-optional-labels 'all)) (vhdl-insert-keyword "WHILE ") (vhdl-insert-keyword ": WHILE ") (goto-char start) (setq label (vhdl-template-field "[label]" nil t)) (unless label (delete-char 2)) (forward-word 1) (forward-char 1)) (when vhdl-conditions-in-parenthesis (insert "(")) (when (vhdl-template-field "condition" nil t start (point)) (when vhdl-conditions-in-parenthesis (insert ")")) (vhdl-insert-keyword " LOOP\n\n") (indent-to margin) (vhdl-insert-keyword "END LOOP") (insert (if label (concat " " label ";") ";")) (forward-line -1) (indent-to (+ margin vhdl-basic-offset))))) (defun vhdl-template-with () "Insert a with statement (i.e. selected signal assignment)." (interactive) (let ((case-fold-search t)) (vhdl-ext-syntax-table (if (save-excursion (re-search-backward "\\(\\<limit\\>\\|;\\)") (equal ";" (match-string 1))) (vhdl-template-selected-signal-asst) (vhdl-insert-keyword "WITH "))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Special templates (defun vhdl-template-clocked-wait () "Insert a wait statement for rising/falling clock edge." (interactive) (let ((start (point)) clock) (vhdl-insert-keyword "WAIT UNTIL ") (when (setq clock (or (and (not (equal "" vhdl-clock-name)) (progn (insert vhdl-clock-name) vhdl-clock-name)) (vhdl-template-field "clock name" nil t start (point)))) (insert "'event") (vhdl-insert-keyword " AND ") (insert clock) (insert " = " (if vhdl-clock-rising-edge vhdl-one-string vhdl-zero-string) ";") (vhdl-comment-insert-inline (concat (if vhdl-clock-rising-edge "rising" "falling") " clock edge"))))) (defun vhdl-template-seq-process (clock reset) "Insert a template for the body of a sequential process." (let ((margin (current-indentation)) position) (vhdl-insert-keyword "IF ") (when (eq vhdl-reset-kind 'async) (insert reset " = " (if vhdl-reset-active-high vhdl-one-string vhdl-zero-string)) (vhdl-insert-keyword " THEN") (vhdl-comment-insert-inline (concat "asynchronous reset (active " (if vhdl-reset-active-high "high" "low") ")")) (insert "\n") (indent-to (+ margin vhdl-basic-offset)) (setq position (point)) (insert "\n") (indent-to margin) (vhdl-insert-keyword "ELSIF ")) (if (eq vhdl-clock-edge-condition 'function) (insert (if vhdl-clock-rising-edge "rising" "falling") "_edge(" clock ")") (insert clock "'event") (vhdl-insert-keyword " AND ") (insert clock " = " (if vhdl-clock-rising-edge vhdl-one-string vhdl-zero-string))) (vhdl-insert-keyword " THEN") (vhdl-comment-insert-inline (concat (if vhdl-clock-rising-edge "rising" "falling") " clock edge")) (insert "\n") (indent-to (+ margin vhdl-basic-offset)) (when (eq vhdl-reset-kind 'sync) (vhdl-insert-keyword "IF ") (setq reset (or (and (not (equal "" vhdl-reset-name)) (progn (insert vhdl-reset-name) vhdl-reset-name)) (vhdl-template-field "reset name") "<reset>")) (insert " = " (if vhdl-reset-active-high vhdl-one-string vhdl-zero-string)) (vhdl-insert-keyword " THEN") (vhdl-comment-insert-inline (concat "synchronous reset (active " (if vhdl-reset-active-high "high" "low") ")")) (insert "\n") (indent-to (+ margin (* 2 vhdl-basic-offset))) (setq position (point)) (insert "\n") (indent-to (+ margin vhdl-basic-offset)) (vhdl-insert-keyword "ELSE") (insert "\n") (indent-to (+ margin (* 2 vhdl-basic-offset))) (insert "\n") (indent-to (+ margin vhdl-basic-offset)) (vhdl-insert-keyword "END IF;")) (when (eq vhdl-reset-kind 'none) (setq position (point))) (insert "\n") (indent-to margin) (vhdl-insert-keyword "END IF;") (goto-char position) reset)) (defun vhdl-template-standard-package (library package) "Insert specification of a standard package. Include a library specification, if not already there." (let ((margin (current-indentation)) (case-fold-search t)) (save-excursion (vhdl-ext-syntax-table (and (not (bobp)) (re-search-backward (concat "^\\s-*\\(library\\s-+\\(\\(\\w\\|\\s_\\)+,\\s-+\\)*" library "\\|end\\)\\>") nil t)))) (unless (and (match-string 1) (string-match "library" (match-string 1))) (vhdl-insert-keyword "LIBRARY ") (insert library ";\n") (indent-to margin)) (vhdl-insert-keyword "USE ") (insert library "." package) (vhdl-insert-keyword ".ALL;"))) (defun vhdl-template-package-math-complex () "Insert specification of `math_complex' package." (interactive) (vhdl-template-standard-package "ieee" "math_complex")) (defun vhdl-template-package-math-real () "Insert specification of `math_real' package." (interactive) (vhdl-template-standard-package "ieee" "math_real")) (defun vhdl-template-package-numeric-bit () "Insert specification of `numeric_bit' package." (interactive) (vhdl-template-standard-package "ieee" "numeric_bit")) (defun vhdl-template-package-numeric-std () "Insert specification of `numeric_std' package." (interactive) (vhdl-template-standard-package "ieee" "numeric_std")) (defun vhdl-template-package-std-logic-1164 () "Insert specification of `std_logic_1164' package." (interactive) (vhdl-template-standard-package "ieee" "std_logic_1164")) (defun vhdl-template-package-std-logic-arith () "Insert specification of `std_logic_arith' package." (interactive) (vhdl-template-standard-package "ieee" "std_logic_arith")) (defun vhdl-template-package-std-logic-misc () "Insert specification of `std_logic_misc' package." (interactive) (vhdl-template-standard-package "ieee" "std_logic_misc")) (defun vhdl-template-package-std-logic-signed () "Insert specification of `std_logic_signed' package." (interactive) (vhdl-template-standard-package "ieee" "std_logic_signed")) (defun vhdl-template-package-std-logic-textio () "Insert specification of `std_logic_textio' package." (interactive) (vhdl-template-standard-package "ieee" "std_logic_textio")) (defun vhdl-template-package-std-logic-unsigned () "Insert specification of `std_logic_unsigned' package." (interactive) (vhdl-template-standard-package "ieee" "std_logic_unsigned")) (defun vhdl-template-package-textio () "Insert specification of `textio' package." (interactive) (vhdl-template-standard-package "std" "textio")) (defun vhdl-template-directive (directive) "Insert directive." (unless (= (current-indentation) (current-column)) (delete-horizontal-space) (insert " ")) (insert "-- pragma " directive)) (defun vhdl-template-directive-translate-on () "Insert directive 'translate_on'." (interactive) (vhdl-template-directive "translate_on")) (defun vhdl-template-directive-translate-off () "Insert directive 'translate_off'." (interactive) (vhdl-template-directive "translate_off")) (defun vhdl-template-directive-synthesis-on () "Insert directive 'synthesis_on'." (interactive) (vhdl-template-directive "synthesis_on")) (defun vhdl-template-directive-synthesis-off () "Insert directive 'synthesis_off'." (interactive) (vhdl-template-directive "synthesis_off")) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Comment templates and functions (defun vhdl-comment-indent () "Indent comments." (let* ((position (point)) (col (progn (forward-line -1) (if (re-search-forward "--" position t) (- (current-column) 2) ; existing comment at bol stays there (goto-char position) (skip-chars-backward " \t") (max comment-column ; else indent to comment column (1+ (current-column))))))) ; except leave at least one space (goto-char position) col)) (defun vhdl-comment-insert () "Start a comment at the end of the line. If on line with code, indent at least `comment-column'. If starting after end-comment-column, start a new line." (interactive) (when (> (current-column) end-comment-column) (newline-and-indent)) (if (or (looking-at "\\s-*$") ; end of line (and (not unread-command-events) ; called with key binding or menu (not (end-of-line)))) (let (margin) (while (= (preceding-char) ?-) (delete-char -1)) (setq margin (current-column)) (delete-horizontal-space) (if (bolp) (progn (indent-to margin) (insert "--")) (insert " ") (indent-to comment-column) (insert "--")) (if (not unread-command-events) (insert " "))) ;; else code following current point implies commenting out code (let (next-input code) (while (= (preceding-char) ?-) (delete-char -2)) (while (= (setq next-input (read-char)) 13) ; CR (insert "--") ; or have a space after it? (forward-char -2) (forward-line 1) (message "Enter CR if commenting out a line of code.") (setq code t)) (when (not code) (insert "--")) ; hardwire to 1 space or use vhdl-basic-offset? (setq unread-command-events (list (vhdl-character-to-event next-input)))))) ; pushback the char (defun vhdl-comment-display (&optional line-exists) "Add 2 comment lines at the current indent, making a display comment." (interactive) (let ((margin (current-indentation))) (when (not line-exists) (vhdl-comment-display-line)) (insert "\n") (indent-to margin) (insert "\n") (indent-to margin) (vhdl-comment-display-line) (end-of-line -0) (insert "-- "))) (defun vhdl-comment-display-line () "Displays one line of dashes." (interactive) (while (= (preceding-char) ?-) (delete-char -2)) (let* ((col (current-column)) (len (- end-comment-column col))) (insert-char ?- len))) (defun vhdl-comment-append-inline () "Append empty inline comment to current line." (interactive) (end-of-line) (delete-horizontal-space) (insert " ") (indent-to comment-column) (insert "-- ")) (defun vhdl-comment-insert-inline (&optional string always-insert) "Insert inline comment." (when (or (and string (or vhdl-self-insert-comments always-insert)) (and (not string) vhdl-prompt-for-comments)) (let ((position (point))) (insert " ") (indent-to comment-column) (insert "-- ") (if (or (and string (progn (insert string) t)) (vhdl-template-field "[comment]" nil t)) (when (> (current-column) end-comment-column) (setq position (point-marker)) (re-search-backward "-- ") (insert "\n") (indent-to comment-column) (goto-char position)) (delete-region position (point)))))) (defun vhdl-comment-block () "Insert comment for code block." (when vhdl-prompt-for-comments (let ((final-pos (point-marker)) (case-fold-search t)) (vhdl-ext-syntax-table (when (and (re-search-backward "^\\s-*begin\\>" nil t) (re-search-backward "\\<\\(architecture\\|block\\|function\\|procedure\\|process\\|procedural\\)\\>" nil t)) (let (margin) (back-to-indentation) (setq margin (current-column)) (end-of-line -0) (if (bobp) (progn (insert "\n") (forward-line -1)) (insert "\n")) (indent-to margin) (insert "-- purpose: ") (unless (vhdl-template-field "[description]" nil t) (vhdl-line-kill-entire))))) (goto-char final-pos)))) (defun vhdl-comment-uncomment-region (beg end &optional arg) "Comment out region if not commented out, uncomment otherwise." (interactive "r\nP") (save-excursion (goto-char (1- end)) (end-of-line) (setq end (point-marker)) (goto-char beg) (beginning-of-line) (setq beg (point)) (if (looking-at comment-start) (comment-region beg end -1) (comment-region beg end)))) (defun vhdl-comment-uncomment-line (&optional arg) "Comment out line if not commented out, uncomment otherwise." (interactive "p") (save-excursion (beginning-of-line) (let ((position (point))) (forward-line (or arg 1)) (vhdl-comment-uncomment-region position (point))))) (defun vhdl-comment-kill-region (beg end) "Kill comments in region." (interactive "r") (save-excursion (goto-char end) (setq end (point-marker)) (goto-char beg) (beginning-of-line) (while (< (point) end) (if (looking-at "^\\(\\s-*--.*\n\\)") (progn (delete-region (match-beginning 1) (match-end 1))) (beginning-of-line 2))))) (defun vhdl-comment-kill-inline-region (beg end) "Kill inline comments in region." (interactive "r") (save-excursion (goto-char end) (setq end (point-marker)) (goto-char beg) (beginning-of-line) (while (< (point) end) (when (looking-at "^.*[^ \t\n-]+\\(\\s-*--.*\\)$") (delete-region (match-beginning 1) (match-end 1))) (beginning-of-line 2)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Subtemplates (defun vhdl-template-begin-end (construct name margin &optional empty-lines) "Insert a begin ... end pair with optional name after the end. Point is left between them." (let (position) (insert "\n") (when (or empty-lines (eq vhdl-insert-empty-lines 'all)) (insert "\n")) (indent-to margin) (vhdl-insert-keyword "BEGIN") (when (and (or construct name) vhdl-self-insert-comments) (insert " --") (when construct (insert " ") (vhdl-insert-keyword construct)) (when name (insert " " name))) (insert "\n") (when (or empty-lines (eq vhdl-insert-empty-lines 'all)) (insert "\n")) (indent-to (+ margin vhdl-basic-offset)) (setq position (point)) (insert "\n") (when (or empty-lines (eq vhdl-insert-empty-lines 'all)) (insert "\n")) (indent-to margin) (vhdl-insert-keyword "END") (when construct (insert " ") (vhdl-insert-keyword construct)) (insert (if name (concat " " name) "") ";") (goto-char position))) (defun vhdl-template-argument-list (&optional is-function) "Read from user a procedure or function argument list." (insert " (") (let ((margin (current-column)) (start (point)) (end-pos (point)) not-empty interface semicolon-pos) (when (not vhdl-argument-list-indent) (setq margin (+ (current-indentation) vhdl-basic-offset)) (insert "\n") (indent-to margin)) (setq interface (vhdl-template-field (concat "[CONSTANT | SIGNAL" (unless is-function " | VARIABLE") "]") " " t)) (while (vhdl-template-field "[names]" nil t) (setq not-empty t) (insert " : ") (when (not is-function) (if (and interface (equal (upcase interface) "CONSTANT")) (vhdl-insert-keyword "IN ") (vhdl-template-field "[IN | OUT | INOUT]" " " t))) (vhdl-template-field "type") (setq semicolon-pos (point)) (insert ";") (vhdl-comment-insert-inline) (setq end-pos (point)) (insert "\n") (indent-to margin) (setq interface (vhdl-template-field (concat "[CONSTANT | SIGNAL" (unless is-function " | VARIABLE") "]") " " t))) (delete-region end-pos (point)) (when semicolon-pos (goto-char semicolon-pos)) (if not-empty (progn (delete-char 1) (insert ")")) (backward-delete-char 2)))) (defun vhdl-template-generic-list (optional &optional no-value) "Read from user a generic spec argument list." (let (margin (start (point))) (vhdl-insert-keyword "GENERIC (") (setq margin (current-column)) (when (not vhdl-argument-list-indent) (let ((position (point))) (back-to-indentation) (setq margin (+ (current-column) vhdl-basic-offset)) (goto-char position) (insert "\n") (indent-to margin))) (let ((vhdl-generics (vhdl-template-field (concat (and optional "[") "name" (and no-value "s") (and optional "]")) nil optional))) (if (not vhdl-generics) (if optional (progn (vhdl-line-kill-entire) (end-of-line -0) (when (not vhdl-argument-list-indent) (vhdl-line-kill-entire) (end-of-line -0))) (vhdl-template-undo start (point)) nil ) (insert " : ") (let (semicolon-pos end-pos) (while vhdl-generics (vhdl-template-field "type") (if no-value (progn (setq semicolon-pos (point)) (insert ";")) (insert " := ") (unless (vhdl-template-field "[value]" nil t) (delete-char -4)) (setq semicolon-pos (point)) (insert ";")) (vhdl-comment-insert-inline) (setq end-pos (point)) (insert "\n") (indent-to margin) (setq vhdl-generics (vhdl-template-field (concat "[name" (and no-value "s") "]") " : " t))) (delete-region end-pos (point)) (goto-char semicolon-pos) (insert ")") (end-of-line) (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1)) t))))) (defun vhdl-template-port-list (optional) "Read from user a port spec argument list." (let ((start (point)) margin vhdl-ports object) (vhdl-insert-keyword "PORT (") (setq margin (current-column)) (when (not vhdl-argument-list-indent) (let ((position (point))) (back-to-indentation) (setq margin (+ (current-column) vhdl-basic-offset)) (goto-char position) (insert "\n") (indent-to margin))) (when (vhdl-standard-p 'ams) (setq object (vhdl-template-field "[SIGNAL | TERMINAL | QUANTITY]" " " t))) (setq vhdl-ports (vhdl-template-field (concat (and optional "[") "names" (and optional "]")) nil optional)) (if (not vhdl-ports) (if optional (progn (vhdl-line-kill-entire) (end-of-line -0) (when (not vhdl-argument-list-indent) (vhdl-line-kill-entire) (end-of-line -0))) (vhdl-template-undo start (point)) nil) (insert " : ") (let (semicolon-pos end-pos) (while vhdl-ports (cond ((or (null object) (equal "SIGNAL" (upcase object))) (vhdl-template-field "IN | OUT | INOUT" " ")) ((equal "QUANTITY" (upcase object)) (vhdl-template-field "[IN | OUT]" " " t))) (vhdl-template-field (if (and object (equal "TERMINAL" (upcase object))) "nature" "type")) (setq semicolon-pos (point)) (insert ";") (vhdl-comment-insert-inline) (setq end-pos (point)) (insert "\n") (indent-to margin) (when (vhdl-standard-p 'ams) (setq object (vhdl-template-field "[SIGNAL | TERMINAL | QUANTITY]" " " t))) (setq vhdl-ports (vhdl-template-field "[names]" " : " t))) (delete-region end-pos (point)) (goto-char semicolon-pos) (insert ")") (end-of-line) (when vhdl-auto-align (vhdl-align-noindent-region start end-pos 1)) t)))) (defun vhdl-template-generate-body (margin label) "Insert body for generate template." (vhdl-insert-keyword " GENERATE") (if (not (vhdl-standard-p '87)) (vhdl-template-begin-end "GENERATE" label margin) (insert "\n\n") (indent-to margin) (vhdl-insert-keyword "END GENERATE ") (insert label ";") (end-of-line 0) (indent-to (+ margin vhdl-basic-offset)))) (defun vhdl-template-insert-date () "Insert date in appropriate format." (interactive) (insert (cond ;; 'american, 'european', 'scientific kept for backward compatibility ((eq vhdl-date-format 'american) (format-time-string "%m/%d/%Y" nil)) ((eq vhdl-date-format 'european) (format-time-string "%d.%m.%Y" nil)) ((eq vhdl-date-format 'scientific) (format-time-string "%Y/%m/%d" nil)) (t (format-time-string vhdl-date-format nil))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Help functions (defun vhdl-electric-space (count) "Expand abbreviations and self-insert space(s), do indent-new-comment-line if in comment and past end-comment-column." (interactive "p") (cond ((vhdl-in-comment-p) (self-insert-command count) (cond ((>= (current-column) (+ 2 end-comment-column)) (backward-word 1) (indent-new-comment-line) (forward-word 1) (forward-char 1)) ((>= (current-column) end-comment-column) (indent-new-comment-line)) (t nil))) ((or (and (>= (preceding-char) ?a) (<= (preceding-char) ?z)) (and (>= (preceding-char) ?A) (<= (preceding-char) ?Z))) (vhdl-ext-syntax-table (let ((case-fold-search t)) (expand-abbrev))) (self-insert-command count)) (t (self-insert-command count)))) (defun vhdl-template-field (prompt &optional follow-string optional begin end is-string default) "Prompt for string and insert it in buffer with optional FOLLOW-STRING. If OPTIONAL is nil, the prompt is left if an empty string is inserted. If an empty string is inserted, return nil and call `vhdl-template-undo' for the region between BEGIN and END. IS-STRING indicates whether a string with double-quotes is to be inserted. DEFAULT specifies a default string." (let ((position (point)) string) (insert "<" prompt ">") (setq string (condition-case () (read-from-minibuffer (concat prompt ": ") (or (and is-string '("\"\"" . 2)) default) vhdl-minibuffer-local-map) (quit (if (and optional begin end) (progn (beep) "") (keyboard-quit))))) (when (or (not (equal string "")) optional) (delete-region position (point))) (when (and (equal string "") optional begin end) (vhdl-template-undo begin end) (message "Template aborted")) (when (not (equal string "")) (insert string) (vhdl-fix-case-region-1 position (point) vhdl-upper-case-keywords vhdl-keywords-regexp)) (when (or (not (equal string "")) (not optional)) (insert (or follow-string ""))) (if (equal string "") nil string))) (defun vhdl-decision-query (string prompt &optional optional) "Query a decision from the user." (let ((start (point))) (when string (vhdl-insert-keyword (concat string " "))) (message prompt) (let ((char (read-char))) (delete-region start (point)) (if (and optional (eq char ?\r)) (progn (insert " ") (unexpand-abbrev) (throw 'abort "Template aborted")) char)))) (defun vhdl-insert-keyword (keyword) "Insert KEYWORD and adjust case." (insert (if vhdl-upper-case-keywords (upcase keyword) (downcase keyword)))) (defun vhdl-case-keyword (keyword) "Adjust case of KEYWORD." (if vhdl-upper-case-keywords (upcase keyword) (downcase keyword))) (defun vhdl-case-word (num) "Adjust case or following NUM words." (if vhdl-upper-case-keywords (upcase-word num) (downcase-word num))) (defun vhdl-minibuffer-tab (&optional prefix-arg) "If preceeding character is part of a word or a paren then hippie-expand, else if right of non whitespace on line then tab-to-tab-stop, else indent line in proper way for current major mode (used for word completion in VHDL minibuffer)." (interactive "P") (cond ((= (char-syntax (preceding-char)) ?w) (let ((case-fold-search (not vhdl-word-completion-case-sensitive)) (case-replace nil)) (vhdl-expand-abbrev prefix-arg))) ((or (= (preceding-char) ?\() (= (preceding-char) ?\))) (let ((case-fold-search (not vhdl-word-completion-case-sensitive)) (case-replace nil)) (vhdl-expand-paren prefix-arg))) ((> (current-column) (current-indentation)) (tab-to-tab-stop)) (t (if (eq indent-line-function 'indent-to-left-margin) (insert-tab prefix-arg) (if prefix-arg (funcall indent-line-function prefix-arg) (funcall indent-line-function)))))) (defun vhdl-template-search-prompt () "Search for left out template prompts and query again." (interactive) (let ((case-fold-search t)) (vhdl-ext-syntax-table (when (or (re-search-forward (concat "<\\(" vhdl-template-prompt-syntax "\\)>") nil t) (re-search-backward (concat "<\\(" vhdl-template-prompt-syntax "\\)>") nil t)) (let ((string (match-string 1))) (replace-match "") (vhdl-template-field string)))))) (defun vhdl-template-undo (begin end) "Undo aborted template by deleting region and unexpanding the keyword." (cond (vhdl-template-invoked-by-hook (goto-char end) (insert " ") (delete-region begin end) (unexpand-abbrev)) (t (delete-region begin end)))) (defun vhdl-insert-string-or-file (string) "Insert STRING or file contents if STRING is an existing file name." (unless (equal string "") (cond ((file-exists-p string) (forward-char (cadr (insert-file-contents string)))) (t (insert string))))) (defun vhdl-sequential-statement-p () "Check if point is within sequential statement part." (save-excursion (let ((case-fold-search t) (start (point))) (vhdl-ext-syntax-table (set-match-data nil) (while (and (re-search-backward "^\\s-*\\(begin\\|end\\(\\s-*\\(case\\|if\\|loop\\)\\)?\\)\\>" nil t) (match-string 2))) (and (match-data) (equal "BEGIN" (upcase (match-string 1))) (re-search-backward "^\\s-*\\(\\w+\\s-*:\\s-*\\)?\\(\\w+\\s-+\\)?\\(function\\|procedure\\|process\\|procedural\\|end\\)\\>" nil t) (not (equal "END" (upcase (match-string 3))))))))) (defun vhdl-in-argument-list-p () "Check if within an argument list." (save-excursion (let ((case-fold-search t)) (vhdl-ext-syntax-table (or (string-match "arglist" (format "%s" (car (car (vhdl-get-syntactic-context))))) (progn (beginning-of-line) (looking-at "^\\s-*\\(generic\\|port\\|\\(\\(impure\\|pure\\)\\s-+\\|\\)function\\|procedure\\)\\>\\s-*\\(\\w+\\s-*\\)?(") )))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Abbrev hooks (defun vhdl-hooked-abbrev (func) "Do function, if syntax says abbrev is a keyword, invoked by hooked abbrev, but not if inside a comment or quote)." (if (or (vhdl-in-comment-p) (vhdl-in-string-p) (save-excursion (forward-word -1) (and (looking-at "\\<end\\>") (not (looking-at "\\<end;"))))) (progn (insert " ") (unexpand-abbrev) (delete-char -1)) (if (not vhdl-electric-mode) (progn (insert " ") (unexpand-abbrev) (backward-word 1) (vhdl-case-word 1) (delete-char 1)) (let ((invoke-char last-command-char) (abbrev-mode -1) (vhdl-template-invoked-by-hook t)) (let ((caught (catch 'abort (funcall func)))) (when (stringp caught) (message caught))) (when (= invoke-char ?-) (setq abbrev-start-location (point))) ;; delete CR which is still in event queue (if (string-match "XEmacs" emacs-version) (enqueue-eval-event 'delete-char -1) (setq unread-command-events ; push back a delete char (list (vhdl-character-to-event ?\177)))))))) (defun vhdl-template-alias-hook () (vhdl-hooked-abbrev 'vhdl-template-alias)) (defun vhdl-template-architecture-hook () (vhdl-hooked-abbrev 'vhdl-template-architecture)) (defun vhdl-template-assert-hook () (vhdl-hooked-abbrev 'vhdl-template-assert)) (defun vhdl-template-attribute-hook () (vhdl-hooked-abbrev 'vhdl-template-attribute)) (defun vhdl-template-block-hook () (vhdl-hooked-abbrev 'vhdl-template-block)) (defun vhdl-template-break-hook () (vhdl-hooked-abbrev 'vhdl-template-break)) (defun vhdl-template-case-hook () (vhdl-hooked-abbrev 'vhdl-template-case)) (defun vhdl-template-component-hook () (vhdl-hooked-abbrev 'vhdl-template-component)) (defun vhdl-template-instance-hook () (vhdl-hooked-abbrev 'vhdl-template-instance)) (defun vhdl-template-conditional-signal-asst-hook () (vhdl-hooked-abbrev 'vhdl-template-conditional-signal-asst)) (defun vhdl-template-configuration-hook () (vhdl-hooked-abbrev 'vhdl-template-configuration)) (defun vhdl-template-constant-hook () (vhdl-hooked-abbrev 'vhdl-template-constant)) (defun vhdl-template-disconnect-hook () (vhdl-hooked-abbrev 'vhdl-template-disconnect)) (defun vhdl-template-display-comment-hook () (vhdl-hooked-abbrev 'vhdl-comment-display)) (defun vhdl-template-else-hook () (vhdl-hooked-abbrev 'vhdl-template-else)) (defun vhdl-template-elsif-hook () (vhdl-hooked-abbrev 'vhdl-template-elsif)) (defun vhdl-template-entity-hook () (vhdl-hooked-abbrev 'vhdl-template-entity)) (defun vhdl-template-exit-hook () (vhdl-hooked-abbrev 'vhdl-template-exit)) (defun vhdl-template-file-hook () (vhdl-hooked-abbrev 'vhdl-template-file)) (defun vhdl-template-for-hook () (vhdl-hooked-abbrev 'vhdl-template-for)) (defun vhdl-template-function-hook () (vhdl-hooked-abbrev 'vhdl-template-function)) (defun vhdl-template-generic-hook () (vhdl-hooked-abbrev 'vhdl-template-generic)) (defun vhdl-template-group-hook () (vhdl-hooked-abbrev 'vhdl-template-group)) (defun vhdl-template-library-hook () (vhdl-hooked-abbrev 'vhdl-template-library)) (defun vhdl-template-limit-hook () (vhdl-hooked-abbrev 'vhdl-template-limit)) (defun vhdl-template-if-hook () (vhdl-hooked-abbrev 'vhdl-template-if)) (defun vhdl-template-bare-loop-hook () (vhdl-hooked-abbrev 'vhdl-template-bare-loop)) (defun vhdl-template-map-hook () (vhdl-hooked-abbrev 'vhdl-template-map)) (defun vhdl-template-nature-hook () (vhdl-hooked-abbrev 'vhdl-template-nature)) (defun vhdl-template-next-hook () (vhdl-hooked-abbrev 'vhdl-template-next)) (defun vhdl-template-package-hook () (vhdl-hooked-abbrev 'vhdl-template-package)) (defun vhdl-template-port-hook () (vhdl-hooked-abbrev 'vhdl-template-port)) (defun vhdl-template-procedural-hook () (vhdl-hooked-abbrev 'vhdl-template-procedural)) (defun vhdl-template-procedure-hook () (vhdl-hooked-abbrev 'vhdl-template-procedure)) (defun vhdl-template-process-hook () (vhdl-hooked-abbrev 'vhdl-template-process)) (defun vhdl-template-quantity-hook () (vhdl-hooked-abbrev 'vhdl-template-quantity)) (defun vhdl-template-report-hook () (vhdl-hooked-abbrev 'vhdl-template-report)) (defun vhdl-template-return-hook () (vhdl-hooked-abbrev 'vhdl-template-return)) (defun vhdl-template-selected-signal-asst-hook () (vhdl-hooked-abbrev 'vhdl-template-selected-signal-asst)) (defun vhdl-template-signal-hook () (vhdl-hooked-abbrev 'vhdl-template-signal)) (defun vhdl-template-subnature-hook () (vhdl-hooked-abbrev 'vhdl-template-subnature)) (defun vhdl-template-subtype-hook () (vhdl-hooked-abbrev 'vhdl-template-subtype)) (defun vhdl-template-terminal-hook () (vhdl-hooked-abbrev 'vhdl-template-terminal)) (defun vhdl-template-type-hook () (vhdl-hooked-abbrev 'vhdl-template-type)) (defun vhdl-template-use-hook () (vhdl-hooked-abbrev 'vhdl-template-use)) (defun vhdl-template-variable-hook () (vhdl-hooked-abbrev 'vhdl-template-variable)) (defun vhdl-template-wait-hook () (vhdl-hooked-abbrev 'vhdl-template-wait)) (defun vhdl-template-when-hook () (vhdl-hooked-abbrev 'vhdl-template-when)) (defun vhdl-template-while-loop-hook () (vhdl-hooked-abbrev 'vhdl-template-while-loop)) (defun vhdl-template-with-hook () (vhdl-hooked-abbrev 'vhdl-template-with)) (defun vhdl-template-and-hook () (vhdl-hooked-abbrev 'vhdl-template-and)) (defun vhdl-template-or-hook () (vhdl-hooked-abbrev 'vhdl-template-or)) (defun vhdl-template-nand-hook () (vhdl-hooked-abbrev 'vhdl-template-nand)) (defun vhdl-template-nor-hook () (vhdl-hooked-abbrev 'vhdl-template-nor)) (defun vhdl-template-xor-hook () (vhdl-hooked-abbrev 'vhdl-template-xor)) (defun vhdl-template-xnor-hook () (vhdl-hooked-abbrev 'vhdl-template-xnor)) (defun vhdl-template-not-hook () (vhdl-hooked-abbrev 'vhdl-template-not)) (defun vhdl-template-default-hook () (vhdl-hooked-abbrev 'vhdl-template-default)) (defun vhdl-template-default-indent-hook () (vhdl-hooked-abbrev 'vhdl-template-default-indent)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Template insertion from completion list (defun vhdl-template-insert-construct (name) "Insert the built-in construct template with NAME." (interactive (list (let ((completion-ignore-case t)) (completing-read "Construct name: " vhdl-template-construct-alist nil t)))) (vhdl-template-insert-fun (car (cdr (assoc name vhdl-template-construct-alist))))) (defun vhdl-template-insert-package (name) "Insert the built-in package template with NAME." (interactive (list (let ((completion-ignore-case t)) (completing-read "Package name: " vhdl-template-package-alist nil t)))) (vhdl-template-insert-fun (car (cdr (assoc name vhdl-template-package-alist))))) (defun vhdl-template-insert-directive (name) "Insert the built-in directive template with NAME." (interactive (list (let ((completion-ignore-case t)) (completing-read "Directive name: " vhdl-template-directive-alist nil t)))) (vhdl-template-insert-fun (car (cdr (assoc name vhdl-template-directive-alist))))) (defun vhdl-template-insert-fun (fun) "Call FUN to insert a built-in template." (let ((caught (catch 'abort (when fun (funcall fun))))) (when (stringp caught) (message caught)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Models ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun vhdl-model-insert (model-name) "Insert the user model with name MODEL-NAME." (interactive (let ((completion-ignore-case t)) (list (completing-read "Model name: " vhdl-model-alist)))) (vhdl-indent-line) (let ((start (point-marker)) (margin (current-indentation)) (case-fold-search t) model position prompt string end) (vhdl-ext-syntax-table (when (setq model (assoc model-name vhdl-model-alist)) ;; insert model (beginning-of-line) (delete-horizontal-space) (goto-char start) (vhdl-insert-string-or-file (nth 1 model)) (setq end (point-marker)) ;; indent code (goto-char start) (beginning-of-line) (while (< (point) end) (unless (looking-at "^$") (insert-char ? margin)) (beginning-of-line 2)) (goto-char start) ;; insert clock (unless (equal "" vhdl-clock-name) (while (re-search-forward "<clock>" end t) (replace-match vhdl-clock-name))) (goto-char start) ;; insert reset (unless (equal "" vhdl-reset-name) (while (re-search-forward "<reset>" end t) (replace-match vhdl-reset-name))) (goto-char start) ;; query prompts (while (re-search-forward (concat "<\\(" vhdl-template-prompt-syntax "\\)>") end t) (unless (equal "cursor" (match-string 1)) (setq position (match-beginning 1)) (setq prompt (match-string 1)) (replace-match "") (setq string (vhdl-template-field prompt nil t)) ;; replace occurences of same prompt (while (re-search-forward (concat "<\\(" prompt "\\)>") end t) (replace-match (or string ""))) (goto-char position))) (goto-char start) ;; goto final position (if (re-search-forward "<cursor>" end t) (replace-match "") (goto-char end)))))) (defun vhdl-model-defun () "Define help and hook functions for user models." (let ((model-alist vhdl-model-alist) model-name model-keyword) (while model-alist ;; define functions for user models that can be invoked from menu and key ;; bindings and which themselves call `vhdl-model-insert' with the model ;; name as argument (setq model-name (nth 0 (car model-alist))) (eval (` (defun (, (vhdl-function-name "vhdl-model" model-name)) () (, (concat "Insert model for \"" model-name "\".")) (interactive) (vhdl-model-insert (, model-name))))) ;; define hooks for user models that are invoked from keyword abbrevs (setq model-keyword (nth 3 (car model-alist))) (unless (equal model-keyword "") (eval (` (defun (, (vhdl-function-name "vhdl-model" model-name "hook")) () (vhdl-hooked-abbrev '(, (vhdl-function-name "vhdl-model" model-name))))))) (setq model-alist (cdr model-alist))))) (vhdl-model-defun) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Port translation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar vhdl-port-list nil "Variable to hold last PORT map parsed.") ;; structure: (parenthesised expression means list of such entries) ;; ((generic-names) generic-type generic-init generic-comment) ;; ((port-names) port-object port-direct port-type port-comment) (defun vhdl-parse-string (string &optional optional) "Check that the text following point matches the regexp in STRING. END is the point beyond which matching/searching should not go." (if (looking-at string) (re-search-forward string nil t) (unless optional (throw 'parse (format "Syntax error near line %s" (vhdl-current-line)))) nil)) (defun vhdl-replace-string (regexp-cons string) "Replace STRING from car of REGEXP-CONS to cdr of REGEXP-CONS." (vhdl-ext-syntax-table (if (string-match (car regexp-cons) string) (replace-match (cdr regexp-cons) t nil string) string))) (defun vhdl-port-flatten () "Flatten port list so that only one generic/port exists per line." (interactive) (if (not vhdl-port-list) (error "No port read") (message "Flattening port...") (let ((new-vhdl-port-list (list (car vhdl-port-list))) (old-vhdl-port-list (cdr vhdl-port-list)) old-port-list new-port-list old-port new-port names) ;; traverse port list and flatten entries (while old-vhdl-port-list (setq old-port-list (car old-vhdl-port-list)) (setq new-port-list nil) (while old-port-list (setq old-port (car old-port-list)) (setq names (car old-port)) (while names (setq new-port (cons (list (car names)) (cdr old-port))) (setq new-port-list (append new-port-list (list new-port))) (setq names (cdr names))) (setq old-port-list (cdr old-port-list))) (setq old-vhdl-port-list (cdr old-vhdl-port-list)) (setq new-vhdl-port-list (append new-vhdl-port-list (list new-port-list)))) (setq vhdl-port-list new-vhdl-port-list) (message "Flattening port...done")))) (defun vhdl-port-copy () "Get generic and port information from an entity or component declaration." (interactive) (message "Reading port...") (save-excursion (let ((case-fold-search t) parse-error end-of-list name generics ports object names direct type init comment) (vhdl-ext-syntax-table (setq parse-error (catch 'parse ;; check if within entity or component declaration (when (or (not (re-search-backward "^\\s-*\\(component\\|entity\\|end\\)\\>" nil t)) (equal "end" (match-string 1))) (throw 'parse "Not within entity or component declaration")) (forward-word 1) (vhdl-parse-string "\\s-*\\(\\w+\\)\\s-*\\(is\\)?\\s-*$") (setq name (match-string 1)) (vhdl-forward-syntactic-ws) ;; parse generic clause (when (vhdl-parse-string "generic[ \t\n]*(" t) (vhdl-forward-syntactic-ws) (setq end-of-list (looking-at ")")) (while (not end-of-list) ;; parse names (vhdl-parse-string "\\(\\w+\\)[ \t\n]*") (setq names (list (match-string 1))) (while (vhdl-parse-string ",[ \t\n]*\\(\\w+\\)[ \t\n]*" t) (setq names (append names (list (match-string 1))))) ;; parse type (vhdl-parse-string ":[ \t\n]*\\([^():;\n]+\\)") (setq type (match-string 1)) (setq comment nil) (while (looking-at "(") (setq type (concat type (buffer-substring (point) (progn (forward-sexp) (point))) (and (vhdl-parse-string "\\([^():;\n]*\\)" t) (match-string 1))))) ;; special case: closing parenthesis is on separate line (when (and type (string-match "\\(\\s-*--\\s-*\\)\\(.*\\)" type)) (setq comment (substring type (match-beginning 2))) (setq type (substring type 0 (match-beginning 1)))) ;; strip of trailing whitespace (string-match "\\(\\(\\s-*\\S-+\\)+\\)\\s-*" type) (setq type (substring type 0 (match-end 1))) ;; parse initialization expression (setq init nil) (when (vhdl-parse-string ":=[ \t\n]*" t) (vhdl-parse-string "\\([^();\n]*\\)") (setq init (match-string 1)) (while (looking-at "(") (setq init (concat init (buffer-substring (point) (progn (forward-sexp) (point))) (and (vhdl-parse-string "\\([^();\n]*\\)" t) (match-string 1)))))) ;; special case: closing parenthesis is on separate line (when (and init (string-match "\\(\\s-*--\\s-*\\)\\(.*\\)" init)) (setq comment (substring init (match-beginning 2))) (setq init (substring init 0 (match-beginning 1))) (vhdl-forward-syntactic-ws)) (skip-chars-forward " \t") ;; parse inline comment, special case: as above, no initial. (unless comment (setq comment (and (vhdl-parse-string "--\\s-*\\([^\n]*\\)" t) (match-string 1)))) (vhdl-forward-syntactic-ws) (setq end-of-list (vhdl-parse-string ")" t)) (vhdl-parse-string "\\s-*;\\s-*") ;; parse inline comment (unless comment (setq comment (and (vhdl-parse-string "--\\s-*\\([^\n]*\\)" t) (match-string 1)))) (vhdl-forward-syntactic-ws) ;; save everything in list (setq generics (append generics (list (list names type init comment)))))) ;; parse port clause (when (vhdl-parse-string "port[ \t\n]*(" t) (vhdl-forward-syntactic-ws) (setq end-of-list (looking-at ")")) (while (not end-of-list) ;; parse object (setq object (and (vhdl-parse-string "\\(signal\\|quantity\\|terminal\\)[ \t\n]*" t) (match-string 1))) ;; parse names (vhdl-parse-string "\\(\\w+\\)[ \t\n]*") (setq names (list (match-string 1))) (while (vhdl-parse-string ",[ \t\n]*\\(\\w+\\)[ \t\n]*" t) (setq names (append names (list (match-string 1))))) ;; parse direction (vhdl-parse-string ":[ \t\n]*") (setq direct (and (vhdl-parse-string "\\(IN\\|OUT\\|INOUT\\)[ \t\n]+" t) (match-string 1))) ;; parse type (vhdl-parse-string "\\([^();\n]+\\)") (setq type (match-string 1)) (setq comment nil) (while (looking-at "(") (setq type (concat type (buffer-substring (point) (progn (forward-sexp) (point))) (and (vhdl-parse-string "\\([^();\n]*\\)" t) (match-string 1))))) ;; special case: closing parenthesis is on separate line (when (string-match "\\(\\s-*--\\s-*\\)\\(.*\\)" type) (setq comment (substring type (match-beginning 2))) (setq type (substring type 0 (match-beginning 1)))) ;; strip of trailing whitespace (string-match "\\(\\(\\s-*\\S-+\\)+\\)\\s-*" type) (setq type (substring type 0 (match-end 1))) (vhdl-forward-syntactic-ws) (setq end-of-list (vhdl-parse-string ")" t)) (vhdl-parse-string "\\s-*;\\s-*") ;; parse inline comment (unless comment (setq comment (and (vhdl-parse-string "--\\s-*\\([^\n]*\\)" t) (match-string 1)))) (vhdl-forward-syntactic-ws) ;; save everything in list (setq ports (append ports (list (list names object direct type comment)))))) nil))) ;; finish parsing (if parse-error (error parse-error) (setq vhdl-port-list (list name generics ports)) (message "Reading port...done"))))) (defun vhdl-port-paste-generic (&optional no-init) "Paste a generic clause." (let ((margin (current-indentation)) list-margin start names generic (generics-list (nth 1 vhdl-port-list))) ;; paste generic clause (when generics-list (setq start (point)) (vhdl-insert-keyword "GENERIC (") (unless vhdl-argument-list-indent (insert "\n") (indent-to (+ margin vhdl-basic-offset))) (setq list-margin (current-column)) (while generics-list ;; paste names (setq generic (car generics-list)) (setq names (nth 0 generic)) (while names (insert (car names)) (setq names (cdr names)) (when names (insert ", "))) ;; paste type (insert " : " (nth 1 generic)) ;; paste initialization (when (and (not no-init) (nth 2 generic)) (insert " := " (nth 2 generic))) (unless (cdr generics-list) (insert ")")) (insert ";") ;; paste comment (when (and vhdl-include-port-comments (nth 3 generic)) (vhdl-comment-insert-inline (nth 3 generic) t)) (setq generics-list (cdr generics-list)) (when generics-list (insert "\n") (indent-to list-margin))) ;; align generic clause (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1 t))))) (defun vhdl-port-paste-port () "Paste a port clause." (let ((margin (current-indentation)) list-margin start names port (ports-list (nth 2 vhdl-port-list))) ;; paste port clause (when ports-list (setq start (point)) (vhdl-insert-keyword "PORT (") (unless vhdl-argument-list-indent (insert "\n") (indent-to (+ margin vhdl-basic-offset))) (setq list-margin (current-column)) (while ports-list (setq port (car ports-list)) ;; paste object (when (nth 1 port) (insert (nth 1 port) " ")) ;; paste names (setq names (nth 0 port)) (while names (insert (car names)) (setq names (cdr names)) (when names (insert ", "))) ;; paste direction (insert " : ") (when (nth 2 port) (insert (nth 2 port) " ")) ;; paste type (insert (nth 3 port)) (unless (cdr ports-list) (insert ")")) (insert ";") ;; paste comment (when (and vhdl-include-port-comments (nth 4 port)) (vhdl-comment-insert-inline (nth 4 port) t)) (setq ports-list (cdr ports-list)) (when ports-list (insert "\n") (indent-to list-margin))) ;; align port clause (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1))))) (defun vhdl-port-paste-declaration (kind) "Paste as an entity or component declaration." (vhdl-indent-line) (let ((margin (current-indentation)) (name (nth 0 vhdl-port-list))) (vhdl-insert-keyword (if (eq kind 'entity) "ENTITY " "COMPONENT ")) (insert name) (if (eq kind 'entity) (vhdl-insert-keyword " IS")) ;; paste generic and port clause (when (nth 1 vhdl-port-list) (insert "\n") (when (and (memq vhdl-insert-empty-lines '(unit all)) (eq kind 'entity)) (insert "\n")) (indent-to (+ margin vhdl-basic-offset)) (vhdl-port-paste-generic (eq kind 'component))) (when (nth 2 vhdl-port-list) (insert "\n") (when (and (memq vhdl-insert-empty-lines '(unit all)) (eq kind 'entity)) (insert "\n")) (indent-to (+ margin vhdl-basic-offset))) (vhdl-port-paste-port) (insert "\n") (when (and (memq vhdl-insert-empty-lines '(unit all)) (eq kind 'entity)) (insert "\n")) (indent-to margin) (vhdl-insert-keyword "END") (if (eq kind 'entity) (progn (unless (vhdl-standard-p '87) (vhdl-insert-keyword " ENTITY")) (insert " " name)) (vhdl-insert-keyword " COMPONENT") (unless (vhdl-standard-p '87) (insert " " name))) (insert ";"))) (defun vhdl-port-paste-entity () "Paste as an entity declaration." (interactive) (if (not vhdl-port-list) (error "No port read") (message "Pasting port as entity...") (vhdl-port-paste-declaration 'entity) (message "Pasting port as entity...done"))) (defun vhdl-port-paste-component () "Paste as a component declaration." (interactive) (if (not vhdl-port-list) (error "No port read") (message "Pasting port as component...") (vhdl-port-paste-declaration 'component) (message "Pasting port as component...done"))) (defun vhdl-port-paste-generic-map (&optional secondary no-constants) "Paste as a generic map." (interactive) (unless secondary (vhdl-indent-line)) (let ((margin (current-indentation)) list-margin start generic (generics-list (nth 1 vhdl-port-list))) (when generics-list (setq start (point)) (vhdl-insert-keyword "GENERIC MAP (") (if (not vhdl-association-list-with-formals) ;; paste list of actual generics (while generics-list (insert (or (nth 2 (car generics-list)) " ")) (setq generics-list (cdr generics-list)) (insert (if generics-list ", " ")"))) (unless vhdl-argument-list-indent (insert "\n") (indent-to (+ margin vhdl-basic-offset))) (setq list-margin (current-column)) (while generics-list (setq generic (car generics-list)) ;; paste formal and actual generic (insert (car (nth 0 generic)) " => " (if no-constants (car (nth 0 generic)) (or (nth 2 generic) ""))) (setq generics-list (cdr generics-list)) (insert (if generics-list "," ")")) ;; paste comment (when (and vhdl-include-port-comments (nth 3 generic)) (vhdl-comment-insert-inline (nth 3 generic) t)) (when generics-list (insert "\n") (indent-to list-margin))) ;; align generic map (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1 t)))))) (defun vhdl-port-paste-port-map () "Paste as a port map." (let ((margin (current-indentation)) list-margin start port (ports-list (nth 2 vhdl-port-list))) (when ports-list (setq start (point)) (vhdl-insert-keyword "PORT MAP (") (if (not vhdl-association-list-with-formals) ;; paste list of actual ports (while ports-list (insert (vhdl-replace-string vhdl-actual-port-name (car (nth 0 (car ports-list))))) (setq ports-list (cdr ports-list)) (insert (if ports-list ", " ");"))) (unless vhdl-argument-list-indent (insert "\n") (indent-to (+ margin vhdl-basic-offset))) (setq list-margin (current-column)) (while ports-list (setq port (car ports-list)) ;; paste formal and actual port (insert (car (nth 0 port)) " => ") (insert (vhdl-replace-string vhdl-actual-port-name (car (nth 0 port)))) (setq ports-list (cdr ports-list)) (insert (if ports-list "," ");")) ;; paste comment (when (or vhdl-include-direction-comments (and vhdl-include-port-comments (nth 4 port))) (vhdl-comment-insert-inline (concat (if vhdl-include-direction-comments (format "%-4s" (or (concat (nth 2 port) " ") "")) "") (if vhdl-include-port-comments (nth 4 port) "")) t)) (when ports-list (insert "\n") (indent-to list-margin))) ;; align port clause (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1)))))) (defun vhdl-port-paste-instance (&optional name) "Paste as an instantiation." (interactive) (if (not vhdl-port-list) (error "No port read") (let ((orig-vhdl-port-list vhdl-port-list)) ;; flatten local copy of port list (must be flat for port mapping) (vhdl-port-flatten) (vhdl-indent-line) (let ((margin (current-indentation)) list-margin start generic port (generics-list (nth 1 vhdl-port-list)) (ports-list (nth 2 vhdl-port-list))) ;; paste instantiation (if name (insert name ": ") (if (equal (cdr vhdl-instance-name) "") (vhdl-template-field "instance name" ": ") (insert (vhdl-replace-string vhdl-instance-name (nth 0 vhdl-port-list)) ": "))) (message "Pasting port as instantiation...") (if (vhdl-standard-p '87) (insert (nth 0 vhdl-port-list)) (vhdl-insert-keyword "ENTITY ") (insert "work." (nth 0 vhdl-port-list))) (when (nth 1 vhdl-port-list) (insert "\n") (indent-to (+ margin vhdl-basic-offset)) (vhdl-port-paste-generic-map t t)) (when (nth 2 vhdl-port-list) (insert "\n") (indent-to (+ margin vhdl-basic-offset)) (vhdl-port-paste-port-map)) (message "Pasting port as instantiation...done")) (setq vhdl-port-list orig-vhdl-port-list)))) (defun vhdl-port-paste-signals (&optional initialize) "Paste ports as internal signals." (interactive) (if (not vhdl-port-list) (error "No port read") (message "Pasting port as signals...") (vhdl-indent-line) (let ((margin (current-indentation)) start port names (ports-list (nth 2 vhdl-port-list))) (when ports-list (setq start (point)) (while ports-list (setq port (car ports-list)) ;; paste object (if (nth 1 port) (insert (nth 1 port) " ") (vhdl-insert-keyword "SIGNAL ")) ;; paste actual port signals (setq names (nth 0 port)) (while names (insert (vhdl-replace-string vhdl-actual-port-name (car names))) (setq names (cdr names)) (when names (insert ", "))) ;; paste type (insert " : " (nth 3 port)) ;; paste initialization (inputs only) (when (and initialize (equal "in" (nth 2 port))) (insert " := " (if (string-match "(.+)" (nth 3 port)) "(others => '0')" "'0'"))) (insert ";") ;; paste comment (when (and vhdl-include-port-comments (nth 4 port)) (vhdl-comment-insert-inline (nth 4 port) t)) (setq ports-list (cdr ports-list)) (when ports-list (insert "\n") (indent-to margin))) ;; align signal list (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1)))) (message "Pasting port as signals...done"))) (defun vhdl-port-paste-constants () "Paste generics as constants." (interactive) (if (not vhdl-port-list) (error "No port read") (let ((orig-vhdl-port-list vhdl-port-list)) (message "Pasting port as constants...") ;; flatten local copy of port list (must be flat for constant initial.) (vhdl-port-flatten) (vhdl-indent-line) (let ((margin (current-indentation)) start generic name (generics-list (nth 1 vhdl-port-list))) (when generics-list (setq start (point)) (while generics-list (setq generic (car generics-list)) (vhdl-insert-keyword "CONSTANT ") ;; paste generic constants (setq name (nth 0 generic)) (when name (insert (car name)) ;; paste type (insert " : " (nth 1 generic)) ;; paste initialization (when (nth 2 generic) (insert " := " (nth 2 generic))) (insert ";") ;; paste comment (when (and vhdl-include-port-comments (nth 3 generic)) (vhdl-comment-insert-inline (nth 3 generic) t)) (setq generics-list (cdr generics-list)) (when generics-list (insert "\n") (indent-to margin)))) ;; align signal list (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1)))) (message "Pasting port as constants...done") (setq vhdl-port-list orig-vhdl-port-list)))) (defun vhdl-port-paste-testbench () "Paste as a bare-bones test bench." (interactive) (if (not vhdl-port-list) (error "No port read") (message "Pasting port as test bench...") (let ((case-fold-search t) (ent-name (vhdl-replace-string vhdl-testbench-entity-name (nth 0 vhdl-port-list))) (source-buffer (current-buffer)) arch-name ent-file-name arch-file-name no-entity position) ;; open entity file (when (not (eq vhdl-testbench-create-files 'none)) (string-match "\\.[^.]*\\'" (buffer-file-name (current-buffer))) (setq ent-file-name (concat ent-name (substring (buffer-file-name (current-buffer)) (match-beginning 0)))) (when (file-exists-p ent-file-name) (if (y-or-n-p (concat "File `" ent-file-name "' exists; overwrite? ")) (progn (delete-file ent-file-name) (when (get-file-buffer ent-file-name) (set-buffer ent-file-name) (set-buffer-modified-p nil) (kill-buffer ent-file-name))) (if (eq vhdl-testbench-create-files 'separate) (setq no-entity t) (error "Pasting port as test bench...aborted")))) (unless no-entity (set-buffer source-buffer) (find-file ent-file-name))) (let ((margin 0)) (unless (and (eq vhdl-testbench-create-files 'separate) no-entity) ;; paste entity header (unless (equal "" vhdl-testbench-entity-header) (vhdl-insert-string-or-file vhdl-testbench-entity-header)) (vhdl-comment-display-line) (insert "\n\n") (indent-to margin) ;; paste std_logic_1164 package (vhdl-insert-keyword "LIBRARY ") (insert "ieee;\n") (indent-to margin) (vhdl-insert-keyword "USE ") (insert "ieee.std_logic_1164.") (vhdl-insert-keyword "ALL;") (insert "\n\n") (indent-to margin) (vhdl-comment-display-line) (insert "\n\n") (indent-to margin) ;; paste entity declaration (vhdl-insert-keyword "ENTITY ") (insert ent-name) (vhdl-insert-keyword " IS") (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n")) (insert "\n") (indent-to margin) (vhdl-insert-keyword "END ") (unless (vhdl-standard-p '87) (vhdl-insert-keyword "ENTITY ")) (insert ent-name ";") (insert "\n\n") (indent-to margin) (vhdl-comment-display-line) (insert "\n")) ;; get architecture name (setq arch-name (if (equal (cdr vhdl-testbench-architecture-name) "") (read-from-minibuffer "architecture name: " nil vhdl-minibuffer-local-map) (vhdl-replace-string vhdl-testbench-architecture-name (nth 0 vhdl-port-list)))) ;; open architecture file (when (eq vhdl-testbench-create-files 'separate) (save-buffer) (string-match "\\.[^.]*\\'" (buffer-file-name (current-buffer))) (setq arch-file-name (concat arch-name (substring (buffer-file-name (current-buffer)) (match-beginning 0)))) (when (file-exists-p arch-file-name) (if (y-or-n-p (concat "File `" ent-file-name "' exists; overwrite? ")) (progn (delete-file arch-file-name) (when (get-file-buffer arch-file-name) (set-buffer (get-file-buffer arch-file-name)) (set-buffer-modified-p nil) (kill-buffer arch-file-name))) (error "Pasting port as test bench...aborted"))) (set-buffer source-buffer) (find-file arch-file-name) ;; paste architecture header (unless (equal "" vhdl-testbench-architecture-header) (vhdl-insert-string-or-file vhdl-testbench-architecture-header)) (vhdl-comment-display-line) (insert "\n")) (insert "\n") (indent-to margin) ;; paste architecture body (vhdl-insert-keyword "ARCHITECTURE ") (insert arch-name) (vhdl-insert-keyword " OF ") (insert ent-name) (vhdl-insert-keyword " IS") (insert "\n\n") (indent-to margin) ;; paste component declaration (when (vhdl-standard-p '87) (vhdl-port-paste-component) (insert "\n\n") (indent-to margin)) ;; paste constants (when (nth 1 vhdl-port-list) (vhdl-port-paste-constants) (insert "\n\n") (indent-to margin)) ;; paste internal signals (vhdl-port-paste-signals vhdl-testbench-initialize-signals) ;; paste custom declarations (unless (equal "" vhdl-testbench-declarations) (insert "\n\n") (vhdl-insert-string-or-file vhdl-testbench-declarations) (delete-indentation)) (setq position (point)) (insert "\n\n") (indent-to margin) (vhdl-comment-display-line) (insert "\n") (goto-char position) (vhdl-template-begin-end (unless (vhdl-standard-p '87) "ARCHITECTURE") arch-name margin t) ;; paste instantiation (vhdl-port-paste-instance (vhdl-replace-string vhdl-testbench-dut-name (nth 0 vhdl-port-list))) (insert "\n") ;; paste custom statements (unless (equal "" vhdl-testbench-statements) (insert "\n") (vhdl-insert-string-or-file vhdl-testbench-statements)) (insert "\n") (indent-to (+ margin vhdl-basic-offset)) (when (not (eq vhdl-testbench-create-files 'none)) (save-buffer)) (message "Pasting port as test bench...done"))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Miscellaneous ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Hippie expand customization (defvar vhdl-expand-upper-case nil) (defun vhdl-try-expand-abbrev (old) "Try expanding abbreviations from `vhdl-abbrev-list'." (unless old (he-init-string (he-dabbrev-beg) (point)) (setq he-expand-list (let ((abbrev-list vhdl-abbrev-list) (sel-abbrev-list '())) (while abbrev-list (when (or (not (stringp (car abbrev-list))) (string-match (concat "^" he-search-string) (car abbrev-list))) (setq sel-abbrev-list (cons (car abbrev-list) sel-abbrev-list))) (setq abbrev-list (cdr abbrev-list))) (nreverse sel-abbrev-list)))) (while (and he-expand-list (or (not (stringp (car he-expand-list))) (he-string-member (car he-expand-list) he-tried-table t))) ; (equal (car he-expand-list) he-search-string))) (unless (stringp (car he-expand-list)) (setq vhdl-expand-upper-case (car he-expand-list))) (setq he-expand-list (cdr he-expand-list))) (if (null he-expand-list) (progn (when old (he-reset-string)) nil) (he-substitute-string (if vhdl-expand-upper-case (upcase (car he-expand-list)) (car he-expand-list)) t) (setq he-expand-list (cdr he-expand-list)) t)) (defun vhdl-he-list-beg () "Also looks at the word before `(' in order to better match parenthesized expressions (e.g. for index ranges of types and signals)." (save-excursion (condition-case () (progn (backward-up-list 1) (skip-syntax-backward "w_")) ; crashes in `viper-mode' (error ())) (point))) ;; override `he-list-beg' from `hippie-exp' (unless (and (boundp 'viper-mode) viper-mode) (require 'hippie-exp) (defalias 'he-list-beg 'vhdl-he-list-beg)) ;; function for expanding abbrevs and dabbrevs (fset 'vhdl-expand-abbrev (make-hippie-expand-function '(try-expand-dabbrev try-expand-dabbrev-all-buffers vhdl-try-expand-abbrev))) ;; function for expanding parenthesis (fset 'vhdl-expand-paren (make-hippie-expand-function '(try-expand-list try-expand-list-all-buffers))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Case fixing (defun vhdl-fix-case-region-1 (beg end upper-case word-regexp &optional count) "Convert all words matching word-regexp in region to lower or upper case, depending on parameter upper-case." (let ((case-fold-search t) (case-replace nil) (last-update 0)) (vhdl-ext-syntax-table (save-excursion (goto-char end) (setq end (point-marker)) (goto-char beg) (while (re-search-forward word-regexp end t) (or (vhdl-in-comment-p) (vhdl-in-string-p) (if upper-case (upcase-word -1) (downcase-word -1))) (when (and count vhdl-progress-interval (< vhdl-progress-interval (- (nth 1 (current-time)) last-update))) (message "Fixing case... (%2d%s)" (+ (* count 25) (/ (* 25 (- (point) beg)) (- end beg))) "%") (setq last-update (nth 1 (current-time))))) (goto-char end))) (and count vhdl-progress-interval (message "Fixing case...done")))) (defun vhdl-fix-case-region (beg end &optional arg) "Convert all VHDL words in region to lower or upper case, depending on variables vhdl-upper-case-{keywords,types,attributes,enum-values}." (interactive "r\nP") (vhdl-fix-case-region-1 beg end vhdl-upper-case-keywords vhdl-keywords-regexp 0) (vhdl-fix-case-region-1 beg end vhdl-upper-case-types vhdl-types-regexp 1) (vhdl-fix-case-region-1 beg end vhdl-upper-case-attributes (concat "'" vhdl-attributes-regexp) 2) (vhdl-fix-case-region-1 beg end vhdl-upper-case-enum-values vhdl-enum-values-regexp 3)) (defun vhdl-fix-case-buffer () "Convert all VHDL words in buffer to lower or upper case, depending on variables vhdl-upper-case-{keywords,types,attributes,enum-values}." (interactive) (vhdl-fix-case-region (point-min) (point-max))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Line handling functions (defun vhdl-current-line () "Return the line number of the line containing point." (save-restriction (widen) (save-excursion (beginning-of-line) (1+ (count-lines 1 (point)))))) (defun vhdl-line-kill-entire (&optional arg) "Delete entire line." (interactive "p") (beginning-of-line) (kill-line (or arg 1))) (defun vhdl-line-kill (&optional arg) "Kill current line." (interactive "p") (vhdl-line-kill-entire arg)) (defun vhdl-line-copy (&optional arg) "Copy current line." (interactive "p") (save-excursion (beginning-of-line) (let ((position (point))) (forward-line (or arg 1)) (copy-region-as-kill position (point))))) (defun vhdl-line-yank () "Yank entire line." (interactive) (beginning-of-line) (yank)) (defun vhdl-line-expand (&optional prefix-arg) "Hippie-expand current line." (interactive "P") (let ((case-fold-search t) (case-replace nil) (hippie-expand-try-functions-list '(try-expand-line try-expand-line-all-buffers))) (hippie-expand prefix-arg))) (defun vhdl-line-transpose-next (&optional arg) "Interchange this line with next line." (interactive "p") (forward-line 1) (transpose-lines (or arg 1)) (forward-line -1)) (defun vhdl-line-transpose-previous (&optional arg) "Interchange this line with previous line." (interactive "p") (forward-line 1) (transpose-lines (- 0 (or arg 0))) (forward-line -1)) (defun vhdl-line-open () "Open a new line and indent." (interactive) (end-of-line -0) (newline-and-indent)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Project ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun vhdl-project-switch (name) "Switch to project NAME." (setq vhdl-project name) (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame)) (speedbar-refresh))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Compilation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; (using `compile.el') (defun vhdl-compile-init () "Initialize for compilation." (unless compilation-error-regexp-alist (setq compilation-error-regexp-alist (let ((commands-alist vhdl-compiler-alist) regexp-alist sublist) (while commands-alist (setq sublist (nth 5 (car commands-alist))) (unless (equal "" (car sublist)) (setq regexp-alist (cons (list (nth 0 sublist) (if (= 0 (nth 1 sublist)) (if (string-match "XEmacs" emacs-version) 9 nil) (nth 1 sublist)) (nth 2 sublist)) regexp-alist))) (setq commands-alist (cdr commands-alist))) regexp-alist))) (unless compilation-file-regexp-alist (setq compilation-file-regexp-alist (let ((commands-alist vhdl-compiler-alist) regexp-alist) (while commands-alist (unless (equal "" (car (nth 6 (car commands-alist)))) (setq regexp-alist (append regexp-alist (list (nth 6 (car commands-alist)))))) (setq commands-alist (cdr commands-alist))) regexp-alist)))) (defun vhdl-compile () "Compile current buffer using the VHDL compiler specified in `vhdl-compiler'." (interactive) (vhdl-compile-init) (let* ((command-elem (assoc vhdl-compiler vhdl-compiler-alist)) (command (nth 1 command-elem)) (default-directory (expand-file-name (nth 4 command-elem)))) (when command (compile (concat command " " vhdl-compiler-options (unless (string-equal vhdl-compiler-options "") " ") (buffer-file-name)))))) (defun vhdl-make () "Call make command for compilation of all updated source files (requires `Makefile')." (interactive) (vhdl-compile-init) (let* ((command-elem (assoc vhdl-compiler vhdl-compiler-alist)) (command (nth 2 command-elem)) (default-directory (expand-file-name (nth 4 command-elem)))) (if (equal command "") (compile "make") (compile command)))) (defun vhdl-generate-makefile () "Generate new `Makefile'." (interactive) (vhdl-compile-init) (let* ((command-elem (assoc vhdl-compiler vhdl-compiler-alist)) (command (nth 3 command-elem)) (default-directory (expand-file-name (nth 4 command-elem)))) (if (not (equal command "")) (compile command) (error "No such command specified for `%s'" vhdl-compiler)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Hideshow ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; (using `hideshow.el') (defun vhdl-forward-unit (&optional count) "Find begin and end of VHDL design units (for hideshow)." (interactive "p") (let ((case-fold-search t)) (if (< count 0) (re-search-backward "^\\(architecture\\|configuration\\|entity\\|package\\)\\>" nil t) (re-search-forward "^end\\>" nil t)))) (when (string-match "XEmacs" emacs-version) (require 'hideshow)) (unless (assq 'vhdl-mode hs-special-modes-alist) (setq hs-special-modes-alist (cons '(vhdl-mode "\\(^\\)\\(architecture\\|ARCHITECTURE\\|configuration\\|CONFIGURATION\\|entity\\|ENTITY\\|package\\|PACKAGE\\)\\>" "\\(^\\)\\(end\\|END\\)\\>" "--\\( \\|$\\)" vhdl-forward-unit) hs-special-modes-alist))) (defun vhdl-hideshow-init () "Initialize `hideshow'." (if vhdl-hide-all-init (add-hook 'hs-minor-mode-hook 'hs-hide-all) (remove-hook 'hs-minor-mode-hook 'hs-hide-all)) (if vhdl-hideshow-menu (hs-minor-mode 1) (when (boundp 'hs-minor-mode) (hs-minor-mode 0)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Font locking ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; (using `font-lock.el') ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Help functions for translate-off region highlighting (defun vhdl-within-translate-off () "Return point if within translate-off region, else nil." (and (save-excursion (re-search-backward "^\\s-*--\\s-*pragma\\s-*translate_\\(on\\|off\\)\\s-*\n" nil t)) (equal "off" (match-string 1)) (point))) (defun vhdl-start-translate-off (limit) "Return point before translate-off pragma if before LIMIT, else nil." (when (re-search-forward "^\\s-*--\\s-*pragma\\s-*translate_off\\s-*\n" limit t) (match-beginning 0))) (defun vhdl-end-translate-off (limit) "Return point after translate-on pragma if before LIMIT, else nil." (re-search-forward "^\\s-*--\\s-*pragma\\s-*translate_on\\s-*\n" limit t)) (defun vhdl-match-translate-off (limit) "Match a translate-off block, setting match-data and returning t, else nil." (when (< (point) limit) (let ((start (or (vhdl-within-translate-off) (vhdl-start-translate-off limit))) (case-fold-search t)) (when start (let ((end (or (vhdl-end-translate-off limit) limit))) (set-match-data (list start end)) (goto-char end)))))) (defun vhdl-font-lock-match-item (limit) "Match, and move over, any declaration item after point. Adapted from `font-lock-match-c-style-declaration-item-and-skip-to-next'." (condition-case nil (save-restriction (narrow-to-region (point-min) limit) ;; match item (when (looking-at "\\s-*\\(\\w+\\)") (save-match-data (goto-char (match-end 1)) ;; move to next item (if (looking-at "\\(\\s-*,\\)") (goto-char (match-end 1)) (end-of-line) t)))) (error t))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Syntax definitions (defconst vhdl-font-lock-syntactic-keywords '(("\\(\'\\).\\(\'\\)" (1 (7 . ?\')) (2 (7 . ?\')))) "Mark single quotes as having string quote syntax in 'c' instances.") (defvar vhdl-font-lock-keywords nil "Regular expressions to highlight in VHDL Mode.") (defconst vhdl-font-lock-keywords-0 (list ;; highlight template prompts (list (concat "\\(<" vhdl-template-prompt-syntax ">\\)") 1 'vhdl-font-lock-prompt-face t) ;; highlight directives '("--\\s-*pragma\\s-+\\(.*\\)$" 1 vhdl-font-lock-directive-face t) ) "For consideration as a value of `vhdl-font-lock-keywords'. This does highlighting of template prompts and directives (pragmas).") (defvar vhdl-font-lock-keywords-1 nil ;; set in `vhdl-font-lock-init' because dependent on custom variables "For consideration as a value of `vhdl-font-lock-keywords'. This does highlighting of keywords and standard identifiers.") (defconst vhdl-font-lock-keywords-2 (list ;; highlight names of units, subprograms, and components when declared (list (concat "^\\s-*\\(" "architecture\\|configuration\\|entity\\|package\\(\\s-+body\\|\\)\\|" "\\(\\(impure\\|pure\\)\\s-+\\|\\)function\\|procedure\\|component" "\\)\\s-+\\(\\w+\\)") 5 'font-lock-function-name-face) ;; highlight entity names of architectures and configurations (list "^\\s-*\\(architecture\\|configuration\\)\\s-+\\w+\\s-+of\\s-+\\(\\w+\\)" 2 'font-lock-function-name-face) ;; highlight labels of common constructs (list (concat "^\\s-*\\(\\w+\\)\\s-*:\\(\\s-\\|\n\\)*\\(\\(" "assert\\|block\\|case\\|component\\|configuration\\|entity\\|exit\\|" "for\\|if\\|loop\\|next\\|null\\|postponed\\|process\\|" (when (vhdl-standard-p 'ams) "procedural\\|") "with\\|while" "\\)\\>\\|[^\n]*<=\\)") 1 'font-lock-function-name-face) ;; highlight label and component name of component instantiations (list (concat "^\\s-*\\(\\w+\\)\\s-*:[ \t\n]*\\(component\\s-+\\|\\)\\(\\w+\\)" "\\(\\s-\\|\n\\)+\\(generic\\|port\\)\\s-+map\\>") '(1 font-lock-function-name-face) '(3 font-lock-function-name-face)) ;; highlight names and labels at end of constructs (list (concat "^\\s-*end\\s-+\\(\\(" "architecture\\|block\\|case\\|component\\|configuration\\|entity\\|" "for\\|function\\|generate\\|if\\|loop\\|package\\(\\s-+body\\|\\)\\|" "procedure\\|\\(postponed\\s-+\\|\\)process\\|" (when (vhdl-standard-p 'ams) "procedural\\|") "units" "\\)\\>\\|\\)\\s-*\\(\\w*\\)") 5 'font-lock-function-name-face) ;; highlight labels in exit and next statements (list (concat "^\\s-*\\(\\w+\\s-*:\\s-*\\)?\\(exit\\|next\\)\\s-+\\(\\w*\\)") 3 'font-lock-function-name-face) ;; highlight entity name in attribute specifications (list (concat "^\\s-*attribute\\s-+\\w+\\s-+of\\s-+\\(\\w+\\(,\\s-*\\w+\\)*\\)\\s-*:") 1 'font-lock-function-name-face) ;; highlight labels in component specifications (list (concat "^\\s-*for\\s-+\\(\\w+\\(,\\s-*\\w+\\)*\\)\\s-*:" "\\(\\s-\\|\n\\)*\\(\\w+\\)") '(1 font-lock-function-name-face) '(4 font-lock-function-name-face)) ;; highlight attribute name in attribute declarations/specifications (list (concat "^\\s-*attribute\\s-+\\(\\w+\\)") 1 'vhdl-font-lock-attribute-face) ;; highlight type/nature name in (sub)type/(sub)nature declarations (list (concat "^\\s-*\\(sub\\|\\)\\(nature\\|type\\)\\s-+\\(\\w+\\)") 3 'font-lock-type-face) ;; highlight signal/variable/constant declaration names (list "\\(:[^=]\\)" '(vhdl-font-lock-match-item (progn (goto-char (match-beginning 1)) (skip-syntax-backward " ") (skip-syntax-backward "w_") (skip-syntax-backward " ") (while (= (preceding-char) ?,) (backward-char 1) (skip-syntax-backward " ") (skip-syntax-backward "w_") (skip-syntax-backward " "))) ; (skip-chars-backward "^-(\n\";") (goto-char (match-end 1)) (1 font-lock-variable-name-face))) ;; highlight alias/group declaration names and for-loop/-generate variables (list "\\<\\(alias\\|for\\|group\\)\\s-+\\w+\\s-+\\(in\\|is\\)\\>" '(vhdl-font-lock-match-item (progn (goto-char (match-end 1)) (match-beginning 2)) nil (1 font-lock-variable-name-face))) ) "For consideration as a value of `vhdl-font-lock-keywords'. This does context sensitive highlighting of names and labels.") (defvar vhdl-font-lock-keywords-3 nil ;; set in `vhdl-font-lock-init' because dependent on custom variables "For consideration as a value of `vhdl-font-lock-keywords'. This does highlighting of words with special syntax.") (defvar vhdl-font-lock-keywords-4 nil ;; set in `vhdl-font-lock-init' because dependent on custom variables "For consideration as a value of `vhdl-font-lock-keywords'. This does highlighting of additional reserved words.") (defconst vhdl-font-lock-keywords-5 ;; background highlight translate-off regions '((vhdl-match-translate-off (0 vhdl-font-lock-translate-off-face append))) "For consideration as a value of `vhdl-font-lock-keywords'. This does background highlighting of translate-off regions.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Font and color definitions (defvar vhdl-font-lock-prompt-face 'vhdl-font-lock-prompt-face "Face name to use for prompts.") (defvar vhdl-font-lock-attribute-face 'vhdl-font-lock-attribute-face "Face name to use for standardized attributes.") (defvar vhdl-font-lock-enumvalue-face 'vhdl-font-lock-enumvalue-face "Face name to use for standardized enumeration values.") (defvar vhdl-font-lock-function-face 'vhdl-font-lock-function-face "Face name to use for standardized functions and packages.") (defvar vhdl-font-lock-directive-face 'vhdl-font-lock-directive-face "Face name to use for directives.") (defvar vhdl-font-lock-reserved-words-face 'vhdl-font-lock-reserved-words-face "Face name to use for additional reserved words.") (defvar vhdl-font-lock-translate-off-face 'vhdl-font-lock-translate-off-face "Face name to use for translate-off regions.") ;; face names to use for words with special syntax. (let ((syntax-alist vhdl-special-syntax-alist) name) (while syntax-alist (setq name (vhdl-function-name "vhdl-font-lock" (nth 0 (car syntax-alist)) "face")) (eval (` (defvar (, name) '(, name) (, (concat "Face name to use for " (nth 0 (car syntax-alist)) "."))))) (setq syntax-alist (cdr syntax-alist)))) (defgroup vhdl-highlight-faces nil "Faces for highlighting." :group 'vhdl-highlight) ;; add faces used from `font-lock' (custom-add-to-group 'vhdl-highlight-faces 'font-lock-comment-face 'custom-face) (custom-add-to-group 'vhdl-highlight-faces 'font-lock-string-face 'custom-face) (custom-add-to-group 'vhdl-highlight-faces 'font-lock-keyword-face 'custom-face) (custom-add-to-group 'vhdl-highlight-faces 'font-lock-type-face 'custom-face) (custom-add-to-group 'vhdl-highlight-faces 'font-lock-function-name-face 'custom-face) (custom-add-to-group 'vhdl-highlight-faces 'font-lock-variable-name-face 'custom-face) (defface vhdl-font-lock-prompt-face '((((class color) (background light)) (:foreground "Red" :bold t)) (((class color) (background dark)) (:foreground "Pink" :bold t)) (t (:inverse-video t))) "Font lock mode face used to highlight prompts." :group 'vhdl-highlight-faces :group 'font-lock-highlighting-faces) (defface vhdl-font-lock-attribute-face '((((class color) (background light)) (:foreground "Orchid")) (((class color) (background dark)) (:foreground "LightSteelBlue")) (t (:italic t :bold t))) "Font lock mode face used to highlight standardized attributes." :group 'vhdl-highlight-faces :group 'font-lock-highlighting-faces) (defface vhdl-font-lock-enumvalue-face '((((class color) (background light)) (:foreground "Gold4")) (((class color) (background dark)) (:foreground "BurlyWood")) (t (:italic t :bold t))) "Font lock mode face used to highlight standardized enumeration values." :group 'vhdl-highlight-faces :group 'font-lock-highlighting-faces) (defface vhdl-font-lock-function-face '((((class color) (background light)) (:foreground "Orchid4")) (((class color) (background dark)) (:foreground "Orchid1")) (t (:italic t :bold t))) "Font lock mode face used to highlight standardized functions and packages." :group 'vhdl-highlight-faces :group 'font-lock-highlighting-faces) (defface vhdl-font-lock-directive-face '((((class color) (background light)) (:foreground "CadetBlue")) (((class color) (background dark)) (:foreground "Aquamarine")) (t (:italic t :bold t))) "Font lock mode face used to highlight directives." :group 'vhdl-highlight-faces :group 'font-lock-highlighting-faces) (defface vhdl-font-lock-reserved-words-face '((((class color) (background light)) (:foreground "Orange" :bold t)) (((class color) (background dark)) (:foreground "Yellow" :bold t)) (t ())) "Font lock mode face used to highlight additional reserved words." :group 'vhdl-highlight-faces :group 'font-lock-highlighting-faces) (defface vhdl-font-lock-translate-off-face '((((class color) (background light)) (:background "LightGray")) (((class color) (background dark)) (:background "DimGray")) (t ())) "Font lock mode face used to background highlight translate-off regions." :group 'vhdl-highlight-faces :group 'font-lock-highlighting-faces) ;; font lock mode faces used to highlight words with special syntax. (let ((syntax-alist vhdl-special-syntax-alist)) (while syntax-alist (eval (` (defface (, (vhdl-function-name "vhdl-font-lock" (car (car syntax-alist)) "face")) '((((class color) (background light)) (:foreground (, (nth 2 (car syntax-alist))))) (((class color) (background dark)) (:foreground (, (nth 3 (car syntax-alist))))) (t ())) (, (concat "Font lock mode face used to highlight " (nth 0 (car syntax-alist)) ".")) :group 'vhdl-highlight-faces :group 'font-lock-highlighting-faces))) (setq syntax-alist (cdr syntax-alist)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Font lock initialization (defun vhdl-font-lock-init () "Initialize fontification." ;; highlight keywords and standardized types, attributes, enumeration ;; values, and subprograms (setq vhdl-font-lock-keywords-1 (list (list (concat "'" vhdl-attributes-regexp) 1 'vhdl-font-lock-attribute-face) (list vhdl-types-regexp 1 'font-lock-type-face) (list vhdl-functions-regexp 1 'vhdl-font-lock-function-face) (list vhdl-packages-regexp 1 'vhdl-font-lock-function-face) (list vhdl-enum-values-regexp 1 'vhdl-font-lock-enumvalue-face) (list vhdl-keywords-regexp 1 'font-lock-keyword-face))) ;; highlight words with special syntax. (setq vhdl-font-lock-keywords-3 (let ((syntax-alist vhdl-special-syntax-alist) keywords) (while syntax-alist (setq keywords (cons (cons (concat "\\<\\(" (nth 1 (car syntax-alist)) "\\)\\>") (vhdl-function-name "vhdl-font-lock" (nth 0 (car syntax-alist)) "face")) keywords)) (setq syntax-alist (cdr syntax-alist))) keywords)) ;; highlight additional reserved words (setq vhdl-font-lock-keywords-4 (list (list vhdl-reserved-words-regexp 1 'vhdl-font-lock-reserved-words-face))) ;; highlight everything together (setq vhdl-font-lock-keywords (append vhdl-font-lock-keywords-0 (when vhdl-highlight-keywords vhdl-font-lock-keywords-1) (when (or vhdl-highlight-forbidden-words vhdl-highlight-verilog-keywords) vhdl-font-lock-keywords-4) (when vhdl-highlight-special-words vhdl-font-lock-keywords-3) (when vhdl-highlight-names vhdl-font-lock-keywords-2) (when vhdl-highlight-translate-off vhdl-font-lock-keywords-5)))) ;; initialize fontification for VHDL Mode (vhdl-font-lock-init) (defun vhdl-fontify-buffer () "Re-initialize fontification and fontify buffer." (interactive) (setq font-lock-defaults (list 'vhdl-font-lock-keywords nil (not vhdl-highlight-case-sensitive) '((?\_ . "w")) 'beginning-of-line '(font-lock-syntactic-keywords . vhdl-font-lock-syntactic-keywords))) (when (fboundp 'font-lock-unset-defaults) (font-lock-unset-defaults)) ; not implemented in XEmacs (font-lock-set-defaults) (font-lock-fontify-buffer)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Initialization for postscript printing (defun vhdl-ps-print-settings () "Initialize custom face and page settings for postscript printing." ;; define custom face settings (unless (or (not vhdl-print-customize-faces) ps-print-color-p) (set (make-local-variable 'ps-bold-faces) '(font-lock-keyword-face font-lock-type-face vhdl-font-lock-attribute-face vhdl-font-lock-enumvalue-face vhdl-font-lock-directive-face)) (set (make-local-variable 'ps-italic-faces) '(font-lock-comment-face font-lock-function-name-face font-lock-type-face vhdl-font-lock-attribute-face vhdl-font-lock-enumvalue-face vhdl-font-lock-directive-face)) (set (make-local-variable 'ps-underlined-faces) '(font-lock-string-face)) (setq ps-always-build-face-reference t)) ;; define page settings, so that a line containing 79 characters (default) ;; fits into one column (when vhdl-print-two-column (set (make-local-variable 'ps-landscape-mode) t) (set (make-local-variable 'ps-number-of-columns) 2) (set (make-local-variable 'ps-font-size) 7.0) (set (make-local-variable 'ps-header-title-font-size) 10.0) (set (make-local-variable 'ps-header-font-size) 9.0) (set (make-local-variable 'ps-header-offset) 12.0) (when (eq ps-paper-type 'letter) (set (make-local-variable 'ps-inter-column) 40.0) (set (make-local-variable 'ps-left-margin) 40.0) (set (make-local-variable 'ps-right-margin) 40.0)))) (defun vhdl-ps-print-init () "Initialize postscript printing." (if (string-match "XEmacs" emacs-version) (vhdl-ps-print-settings) (make-local-variable 'ps-print-hook) (add-hook 'ps-print-hook 'vhdl-ps-print-settings))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Hierarchy browser (using `speedbar.el') ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Allows displaying the hierarchy of all VHDL design units contained in a ;; directory by using the speedbar. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Variables (defvar vhdl-entity-alist nil "Cache with entities and corresponding architectures and configurations for each visited directory.") ;; structure: (parenthesised expression means list of such entries) ;; (directory-name ;; (ent-name ent-file ent-line ;; (arch-name arch-file arch-line ;; (inst-name inst-file inst-line inst-ent-name inst-arch-name)) ;; (conf-name conf-file conf-line)) (defvar vhdl-package-alist nil "Cache with packages for each visited directory.") ;; structure: (parenthesised expression means list of such entries) ;; (directory-name ;; (pack-name pack-file pack-line pack-body-file pack-body-line)) (defvar vhdl-ent-inst-alist nil "Cache with instantiated entities for each visited directory.") ;; structure: (parenthesised expression means list of such entries) ;; (directory-name (inst-ent-name)) (defvar vhdl-project-entity-alist nil "Cache with entities and corresponding architectures and configurations for each visited project.") ;; same structure as `vhdl-entity-alist' (defvar vhdl-project-package-alist nil "Cache with packages for each visited directory.") ;; same structure as `vhdl-package-alist' (defvar vhdl-project-ent-inst-list nil "Cache with instantiated entities for each visited directory.") ;; same structure as `vhdl-ent-inst-alist' (defvar vhdl-speedbar-shown-units-alist nil "Alist of design units simultaneously open in the current speedbar for each directory and project.") (defvar vhdl-speedbar-last-file-name nil "Last file for which design units were highlighted.") (defvar vhdl-file-alist nil "Cache with design units in each file.") ;; structure (parenthesised expression means list of such entries) ;; (file-name (ent-list) (arch-list) (conf-list) (pack-list) (inst-list)) ;; help function (defsubst vhdl-speedbar-project-p () "Return non-nil if a project is displayed, i.e. directories or files are specified." (nth 1 (aget vhdl-project-alist vhdl-project))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Scan functions (defun vhdl-scan-file-contents (name &optional num-string) "Scan contents of VHDL files in FILE-LIST." (string-match "\\(.*/\\)\\(.*\\)" name) ; (unless (file-directory-p (match-string 1 name)) ; (message "No such directory: \"%s\"" (match-string 1 name))) (let* ((is-directory (= (match-beginning 2) (match-end 2))) (file-list (if is-directory (nreverse (vhdl-get-source-files t name)) (vhdl-directory-files (match-string 1 name) t (wildcard-to-regexp (match-string 2 name))))) (case-fold-search t) (source-buffer (current-buffer)) ent-alist pack-alist ent-inst-list no-files) (when (and (not is-directory) (null file-list)) (message "No such file: \"%s\"" name)) (save-excursion (when file-list (setq no-files (length file-list)) ;; do for all files (while file-list (message "Scanning %s %s\"%s\"... (%2d%s)" (if is-directory "directory" "files") (or num-string "") name (/ (* 100 (- no-files (length file-list))) no-files) "%") (let ((file-name (abbreviate-file-name (car file-list))) opened arch-name ent-name ent-list arch-list conf-list pack-list inst-list) ;; open file (if (find-buffer-visiting file-name) (set-buffer (find-buffer-visiting file-name)) (set-buffer (find-file-noselect file-name nil t)) (setq opened t)) (let ((case-fold-search t)) (modify-syntax-entry ?_ "w" (syntax-table)) ;; scan for entities (goto-char (point-min)) (while (re-search-forward "^\\s-*entity\\s-+\\(\\w+\\)" nil t) (let* ((ent-entry (aget ent-alist (match-string 1))) (arch-alist (nth 2 ent-entry)) (conf-alist (nth 3 ent-entry))) (setq ent-list (cons (match-string 1) ent-list)) (aput 'ent-alist (match-string 1) (list file-name (vhdl-current-line) arch-alist conf-alist nil)))) ;; scan for architectures and instantiations (goto-char (point-min)) (while (re-search-forward (concat "^\\s-*\\(architecture\\s-+\\(\\w+\\)\\s-+of\\s-+\\(\\w+\\)\\|" "\\(\\w+\\)\\s-*:\\(\\s-\\|\n\\)*\\(entity\\s-+\\w+\\.\\)?" "\\(\\w+\\)\\(\\s-*(\\(\\w+\\))\\)?\\(\\s-\\|\n\\|--.*\n\\)*" "\\(generic\\|port\\)\\s-+map\\>\\)") nil t) (if (match-string 2) ;; architecture found (let* ((ent-entry (aget ent-alist (match-string 3))) (arch-alist (nth 2 ent-entry)) (conf-alist (nth 3 ent-entry))) (setq arch-name (match-string 2)) (setq ent-name (match-string 3)) (setq arch-list (cons arch-name arch-list)) (vhdl-aappend 'arch-alist arch-name (list file-name (vhdl-current-line) nil)) (setq ent-entry (list (nth 0 ent-entry) (nth 1 ent-entry) arch-alist conf-alist nil)) (aput 'ent-alist ent-name ent-entry)) ;; instantiation found (let* ((ent-entry (aget ent-alist ent-name)) (arch-alist (nth 2 ent-entry)) (arch-entry (aget arch-alist arch-name)) (inst-alist (nth 2 arch-entry)) (inst-name (match-string 4)) (inst-ent-name (match-string 7)) (inst-arch-name (match-string 9)) (conf-alist (nth 3 ent-entry))) (re-search-backward ":" nil t) (setq inst-list (cons inst-name inst-list)) (vhdl-aappend 'inst-alist inst-name (list file-name (vhdl-current-line) inst-ent-name inst-arch-name)) (setq arch-entry (list (nth 0 arch-entry) (nth 1 arch-entry) inst-alist)) (vhdl-aappend 'arch-alist arch-name arch-entry) (setq ent-entry (list (nth 0 ent-entry) (nth 1 ent-entry) arch-alist conf-alist nil)) (aput 'ent-alist ent-name ent-entry) (unless (member inst-ent-name ent-inst-list) (setq ent-inst-list (cons inst-ent-name ent-inst-list)))))) ;; scan for configurations (goto-char (point-min)) (while (re-search-forward "^\\s-*configuration\\s-+\\(\\w+\\)\\s-+of\\s-+\\(\\w+\\)" nil t) (let* ((ent-entry (aget ent-alist (match-string 2))) (arch-alist (nth 2 ent-entry)) (conf-alist (nth 3 ent-entry))) (setq conf-list (cons (match-string 1) conf-list)) (vhdl-aappend 'conf-alist (match-string 1) (list file-name (vhdl-current-line))) (setq ent-entry (list (nth 0 ent-entry) (nth 1 ent-entry) arch-alist conf-alist nil)) (aput 'ent-alist (match-string 2) ent-entry))) ;; scan for packages (goto-char (point-min)) (while (re-search-forward "^\\s-*package\\s-+\\(body\\s-+\\)?\\(\\w+\\)" nil t) (let ((pack-entry (aget pack-alist (match-string 2)))) (setq pack-list (cons (match-string 2) pack-list)) (aput 'pack-alist (match-string 2) (if (not (match-string 1)) (list file-name (vhdl-current-line) (nth 2 pack-entry) (nth 3 pack-entry)) (list (nth 0 pack-entry) (nth 1 pack-entry) file-name (vhdl-current-line)))))) (setq file-list (cdr file-list)) ;; add design units to variable `vhdl-file-alist' (aput 'vhdl-file-alist file-name (list ent-list arch-list conf-list pack-list inst-list))) ;; close file (if opened (kill-buffer (current-buffer)) (when (not vhdl-underscore-is-part-of-word) (modify-syntax-entry ?_ "_" vhdl-mode-syntax-table))) (set-buffer source-buffer))) ;; sort entities and packages (setq ent-alist (sort ent-alist (function (lambda (a b) (string-lessp (car a) (car b)))))) (setq pack-alist (sort pack-alist (function (lambda (a b) (string-lessp (car a) (car b)))))) ;; put directory contents into cache (when ent-alist (aput 'vhdl-entity-alist name ent-alist)) (when pack-alist (aput 'vhdl-package-alist name pack-alist)) (when ent-inst-list (aput 'vhdl-ent-inst-alist name (list ent-inst-list))) (message "Scanning %s %s\"%s\"...done" (if is-directory "directory" "files") (or num-string "") name) t)))) (defun vhdl-scan-project-contents (project &optional rescan) "Scan the contents of all VHDL files found in the directories and files of PROJECT." (let ((dir-list-tmp (nth 1 (aget vhdl-project-alist project))) dir-list pro-ent-alist pro-pack-alist pro-ent-inst-list dir name num-dir act-dir) ;; resolve environment variables and path wildcards (setq dir-list-tmp (vhdl-resolve-paths dir-list-tmp)) ;; expand directories (while dir-list-tmp (setq dir (car dir-list-tmp)) ;; get subdirectories (if (string-match "-r \\(.*/\\)" dir) (setq dir-list (append dir-list (vhdl-get-subdirs (match-string 1 dir)))) (setq dir-list (append dir-list (list dir)))) (setq dir-list-tmp (cdr dir-list-tmp))) ;; get entities and packages of each directory in DIR-LIST (setq num-dir (length dir-list) act-dir 1) (while dir-list (setq name (abbreviate-file-name (car dir-list))) (or (and (not rescan) (or (assoc name vhdl-entity-alist) (assoc name vhdl-package-alist))) (vhdl-scan-file-contents name (format "(%s/%s) " act-dir num-dir))) ;; merge entities and corresponding architectures and configurations (let ((ent-alist (aget vhdl-entity-alist name))) (while ent-alist (let* ((ent-name (car (car ent-alist))) (ent-entry (cdr (car ent-alist))) (pro-ent-entry (aget pro-ent-alist ent-name))) (aput 'pro-ent-alist ent-name (list (or (nth 0 pro-ent-entry) (nth 0 ent-entry)) (or (nth 1 pro-ent-entry) (nth 1 ent-entry)) (append (nth 2 pro-ent-entry) (nth 2 ent-entry)) (append (nth 3 pro-ent-entry) (nth 3 ent-entry))))) (setq ent-alist (cdr ent-alist)))) ;; merge packages and corresponding package bodies (let ((pack-alist (aget vhdl-package-alist name))) (while pack-alist (let* ((pack-name (car (car pack-alist))) (pack-entry (cdr (car pack-alist))) (pro-pack-entry (aget pro-pack-alist pack-name))) (aput 'pro-pack-alist pack-name (list (or (nth 0 pro-pack-entry) (nth 0 pack-entry)) (or (nth 1 pro-pack-entry) (nth 1 pack-entry)) (or (nth 2 pro-pack-entry) (nth 2 pack-entry)) (or (nth 3 pro-pack-entry) (nth 3 pack-entry))))) (setq pack-alist (cdr pack-alist)))) ;; merge list of instantiated entities (setq pro-ent-inst-list (append pro-ent-inst-list (copy-alist (car (aget vhdl-ent-inst-alist name))))) (setq dir-list (cdr dir-list) act-dir (1+ act-dir))) ;; sort lists and put them into the caches (when pro-ent-alist (aput 'vhdl-project-entity-alist project (sort pro-ent-alist (function (lambda (a b) (string-lessp (car a) (car b))))))) (when pro-pack-alist (aput 'vhdl-project-package-alist project (sort pro-pack-alist (function (lambda (a b) (string-lessp (car a) (car b))))))) (when pro-ent-inst-list (aput 'vhdl-project-ent-inst-list project pro-ent-inst-list)))) (defun vhdl-get-hierarchy (ent-name arch-name level indent &optional ent-hier) "Get instantiation hierarchy beginning in architecture ARCH-NAME of entity ENT-NAME." (let* ((ent-alist (if (vhdl-speedbar-project-p) (aget vhdl-project-entity-alist vhdl-project) (aget vhdl-entity-alist (abbreviate-file-name (file-name-as-directory (speedbar-line-path (1- indent))))))) (ent-entry (aget ent-alist ent-name)) (arch-entry (if arch-name (aget (nth 2 ent-entry) arch-name) (cdr (car (last (nth 2 ent-entry)))))) (inst-list (nth 2 arch-entry)) inst-entry inst-ent-entry inst-arch-entry hier-list) (when (= level 0) (message "Extract design hierarchy...")) (when (member ent-name ent-hier) (error (format "Instantiation loop detected; component \"%s\" instantiates itself" ent-name))) (while inst-list (setq inst-entry (car inst-list)) (setq inst-ent-entry (aget ent-alist (nth 3 inst-entry))) (setq inst-arch-entry (if (nth 4 inst-entry) (cons (nth 4 inst-entry) (aget (nth 2 inst-ent-entry) (nth 4 inst-entry))) (car (last (nth 2 inst-ent-entry))))) (setq hier-list (append hier-list (cons (list (nth 0 inst-entry) (cons (nth 1 inst-entry) (nth 2 inst-entry)) (nth 3 inst-entry) (cons (nth 0 inst-ent-entry) (nth 1 inst-ent-entry)) (nth 0 inst-arch-entry) (cons (nth 1 inst-arch-entry) (nth 2 inst-arch-entry)) level) (vhdl-get-hierarchy (nth 3 inst-entry) (nth 4 inst-entry) (1+ level) indent (cons ent-name ent-hier))))) (setq inst-list (cdr inst-list))) (when (= level 0) (message "Extract design hierarchy...done")) hier-list)) (defun vhdl-get-instantiations (ent-name indent) "Get all instantiations of entity ENT-NAME." (let ((ent-alist (if (vhdl-speedbar-project-p) (aget vhdl-project-entity-alist vhdl-project) (aget vhdl-entity-alist (abbreviate-file-name (file-name-as-directory (speedbar-line-path indent)))))) arch-alist inst-alist ent-inst-list ent-entry arch-entry inst-entry) (while ent-alist (setq ent-entry (car ent-alist)) (setq arch-alist (nth 3 ent-entry)) (while arch-alist (setq arch-entry (car arch-alist)) (setq inst-alist (nth 3 arch-entry)) (while inst-alist (setq inst-entry (car inst-alist)) (when (equal ent-name (nth 3 inst-entry)) (setq ent-inst-list (cons (list (nth 0 inst-entry) (cons (nth 1 inst-entry) (nth 2 inst-entry)) (nth 0 ent-entry) (cons (nth 1 ent-entry) (nth 2 ent-entry)) (nth 0 arch-entry) (cons (nth 1 arch-entry) (nth 2 arch-entry))) ent-inst-list))) (setq inst-alist (cdr inst-alist))) (setq arch-alist (cdr arch-alist))) (setq ent-alist (cdr ent-alist))) (nreverse ent-inst-list))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Add hierarchy browser functionality to speedbar. (defvar vhdl-speedbar-key-map nil "Keymap used when in the VHDL hierarchy browser mode.") (defvar vhdl-speedbar-menu-items '(["Edit Design Unit" speedbar-edit-line t] ["Expand Hierarchy" speedbar-expand-line (save-excursion (beginning-of-line) (looking-at "[0-9]+: *.\\+. "))] ["Contract Hierarchy" speedbar-contract-line (save-excursion (beginning-of-line) (looking-at "[0-9]+: *.-. "))] ["Rescan Hierarchy" vhdl-speedbar-rescan-hierarchy t] "--" ["Copy Port" vhdl-speedbar-port-copy (save-excursion (beginning-of-line) (looking-at "[0-9]+: *\\[[-+?]\\] "))]) "Additional menu-items to add to speedbar frame.") (defun vhdl-speedbar-initialize () "Initialize speedbar." ;; general settings ; (set (make-local-variable 'speedbar-tag-hierarchy-method) nil) ;; VHDL file extensions (extracted from `auto-mode-alist') (let ((mode-alist auto-mode-alist)) (while mode-alist (when (eq (cdr (car mode-alist)) 'vhdl-mode) (speedbar-add-supported-extension (car (car mode-alist)))) (setq mode-alist (cdr mode-alist)))) ;; hierarchy browser settings (when (boundp 'speedbar-mode-functions-list) (speedbar-add-mode-functions-list '("vhdl hierarchy" (speedbar-item-info . vhdl-speedbar-item-info) (speedbar-line-path . speedbar-files-line-path))) (unless vhdl-speedbar-key-map (setq vhdl-speedbar-key-map (speedbar-make-specialized-keymap)) (define-key vhdl-speedbar-key-map "e" 'speedbar-edit-line) (define-key vhdl-speedbar-key-map "\C-m" 'speedbar-edit-line) (define-key vhdl-speedbar-key-map "+" 'speedbar-expand-line) (define-key vhdl-speedbar-key-map "-" 'speedbar-contract-line) (define-key vhdl-speedbar-key-map "s" 'vhdl-speedbar-rescan-hierarchy) (define-key vhdl-speedbar-key-map "c" 'vhdl-speedbar-port-copy)) (define-key speedbar-key-map "h" (lambda () (interactive) (speedbar-change-initial-expansion-list "vhdl hierarchy"))) (speedbar-add-expansion-list '("vhdl hierarchy" vhdl-speedbar-menu-items vhdl-speedbar-key-map vhdl-speedbar-display-hierarchy)) (setq speedbar-stealthy-function-list (cons '("vhdl hierarchy" vhdl-speedbar-update-current-unit) speedbar-stealthy-function-list)) (when vhdl-speedbar-show-hierarchy (setq speedbar-initial-expansion-list-name "vhdl hierarchy")))) (defun vhdl-speedbar (&optional arg) "Open/close speedbar." (interactive) (if (not (fboundp 'speedbar)) (error "WARNING: Speedbar is only available in newer Emacs versions") (condition-case () ; due to bug in `speedbar-el' v0.7.2a (speedbar-frame-mode arg) (error (error "WARNING: Install included `speedbar.el' patch first"))))) ;; initialize speedbar for VHDL Mode (if (not (boundp 'speedbar-frame)) (add-hook 'speedbar-load-hook 'vhdl-speedbar-initialize) (vhdl-speedbar-initialize) (when speedbar-frame (speedbar-refresh))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Display functions ;; macros must be defined in the file they are used (copied from `speedbar.el') (defmacro speedbar-with-writable (&rest forms) "Allow the buffer to be writable and evaluate FORMS." (list 'let '((inhibit-read-only t)) (cons 'progn forms))) (put 'speedbar-with-writable 'lisp-indent-function 0) (defun vhdl-speedbar-display-hierarchy (directory depth &optional rescan) "Display directory and hierarchy information in speedbar." (setq directory (abbreviate-file-name (file-name-as-directory directory))) (setq speedbar-last-selected-file nil) (speedbar-with-writable (save-excursion (if (vhdl-speedbar-project-p) (progn ;; insert project title (vhdl-speedbar-make-title-line "Project:" 0) (let ((start (point))) (insert "p:") (put-text-property start (point) 'invisible t) (setq start (point)) (insert vhdl-project) (put-text-property start (point) 'face 'speedbar-directory-face)) (insert-char ?\n 1) ;; scan and insert hierarchy of project (vhdl-speedbar-insert-project-hierarchy vhdl-project speedbar-power-click)) ;; insert directory path (speedbar-directory-buttons directory depth) ;; insert subdirectories (vhdl-speedbar-insert-dirs (speedbar-file-lists directory) depth) ;; scan and insert hierarchy of current directory (vhdl-speedbar-insert-dir-hierarchy directory depth speedbar-power-click) ;; expand subdirectories (when (= depth 0) (vhdl-speedbar-expand-dirs directory)))))) (defun vhdl-speedbar-insert-hierarchy (ent-alist pack-alist ent-inst-list depth) "Insert hierarchy of ENT-ALIST and PACK-ALIST." (if (not (or ent-alist pack-alist)) (vhdl-speedbar-make-title-line "No design units!" depth) (let (ent-entry pack-entry) ;; insert entities (when ent-alist (vhdl-speedbar-make-title-line "Entities:" depth)) (while ent-alist (setq ent-entry (car ent-alist)) (speedbar-make-tag-line 'bracket ?+ 'vhdl-speedbar-expand-entity (nth 0 ent-entry) (nth 0 ent-entry) 'vhdl-speedbar-find-file (cons (nth 1 ent-entry) (nth 2 ent-entry)) 'vhdl-speedbar-entity-face depth) (when (not (member (nth 0 ent-entry) ent-inst-list)) (end-of-line 0) (insert " (top)") (forward-char 1)) (setq ent-alist (cdr ent-alist))) ;; insert packages (when pack-alist (vhdl-speedbar-make-title-line "Packages:" depth)) (while pack-alist (setq pack-entry (car pack-alist)) (vhdl-speedbar-make-pack-line (nth 0 pack-entry) (cons (nth 1 pack-entry) (nth 2 pack-entry)) (cons (nth 3 pack-entry) (nth 4 pack-entry)) depth) (setq pack-alist (cdr pack-alist)))))) (defun vhdl-speedbar-insert-project-hierarchy (project &optional rescan) "Insert hierarchy of project. Rescan directories if RESCAN is non-nil, otherwise use cached data of directories." (when (or rescan (and (not (assoc project vhdl-project-entity-alist)) (not (assoc project vhdl-project-package-alist)))) (vhdl-scan-project-contents project rescan)) ;; insert design hierarchy in speedbar (vhdl-speedbar-insert-hierarchy (aget vhdl-project-entity-alist project) (aget vhdl-project-package-alist project) (aget vhdl-project-ent-inst-list project) 0) ;; expand design units (vhdl-speedbar-expand-units project)) (defun vhdl-speedbar-insert-dir-hierarchy (directory depth &optional rescan) "Insert hierarchy of DIRECTORY. Rescan directory if RESCAN is non-nil, otherwise use cached data." (when (or rescan (and (not (assoc directory vhdl-entity-alist)) (not (assoc directory vhdl-package-alist)))) (vhdl-scan-file-contents directory)) (vhdl-speedbar-insert-hierarchy (aget vhdl-entity-alist directory) (aget vhdl-package-alist directory) (car (aget vhdl-ent-inst-alist directory)) depth) (vhdl-speedbar-expand-units directory)) (defun vhdl-speedbar-rescan-hierarchy () "Rescan hierarchy for the directory under the cursor or the current project." (interactive) (cond ;; the current project ((vhdl-speedbar-project-p) (vhdl-scan-project-contents vhdl-project t) (speedbar-refresh)) ;; the top-level directory ((save-excursion (beginning-of-line) (looking-at "[^0-9]")) (re-search-forward "[0-9]+:" nil t) (vhdl-scan-file-contents (abbreviate-file-name (speedbar-line-path))) (speedbar-refresh)) ;; the current directory (t (let ((path (speedbar-line-path))) (string-match "^\\(.+/\\)" path) (vhdl-scan-file-contents (abbreviate-file-name (match-string 1 path))) (speedbar-refresh))))) (defun vhdl-speedbar-expand-dirs (directory) "Expand subdirectories in DIRECTORY according to `speedbar-shown-directories'." ;; (nicked from `speedbar-default-directory-list') (let ((sf (cdr (reverse speedbar-shown-directories)))) (setq speedbar-shown-directories (list (expand-file-name default-directory))) (while sf (when (speedbar-goto-this-file (car sf)) (beginning-of-line) (when (looking-at "[0-9]+:\\s-*<") (goto-char (match-end 0)) (let* ((position (point)) (directory (abbreviate-file-name (file-name-as-directory (speedbar-line-file))))) (speedbar-do-function-pointer)))) (setq sf (cdr sf))))) (defun vhdl-speedbar-expand-units (directory) "Expand design units in DIRECTORY according to `vhdl-speedbar-shown-units-alist'." (let ((ent-alist (aget vhdl-speedbar-shown-units-alist directory))) (adelete 'vhdl-speedbar-shown-units-alist directory) (while ent-alist ; expand entities (vhdl-speedbar-goto-this-unit directory (car (car ent-alist))) (beginning-of-line) (let ((arch-alist (nth 1 (car ent-alist))) position) (when (looking-at "[0-9]+:\\s-*\\[") (goto-char (match-end 0)) (setq position (point)) (speedbar-do-function-pointer) (while arch-alist ; expand architectures (goto-char position) (when (re-search-forward (concat "[0-9]+:\\s-*\\(\\[\\|{.}\\s-+" (car arch-alist) "\\>\\)") nil t) (beginning-of-line) (when (looking-at "[0-9]+:\\s-*{") (goto-char (match-end 0)) (speedbar-do-function-pointer))) (setq arch-alist (cdr arch-alist)))) (setq ent-alist (cdr ent-alist)))))) (defun vhdl-speedbar-expand-entity (text token indent) "Expand/contract the entity under the cursor." (cond ((string-match "+" text) ; expand entity (let* ((ent-alist (if (vhdl-speedbar-project-p) (aget vhdl-project-entity-alist vhdl-project) (aget vhdl-entity-alist (abbreviate-file-name (file-name-as-directory (speedbar-line-path indent)))))) (arch-alist (nth 2 (aget ent-alist token))) (conf-alist (nth 3 (aget ent-alist token))) (inst-alist (vhdl-get-instantiations token indent)) arch-entry conf-entry inst-entry) (if (not (or arch-alist conf-alist inst-alist)) (speedbar-change-expand-button-char ??) (speedbar-change-expand-button-char ?-) ;; add entity to `vhdl-speedbar-shown-units-alist' (let* ((directory (if (vhdl-speedbar-project-p) vhdl-project (abbreviate-file-name (file-name-as-directory (speedbar-line-path))))) (ent-alist (aget vhdl-speedbar-shown-units-alist directory))) (aput 'ent-alist (speedbar-line-text) nil) (aput 'vhdl-speedbar-shown-units-alist directory ent-alist)) (speedbar-with-writable (save-excursion (end-of-line) (forward-char 1) ;; insert architectures (when arch-alist (vhdl-speedbar-make-title-line "Architectures:" (1+ indent))) (while arch-alist (setq arch-entry (car arch-alist)) (speedbar-make-tag-line 'curly ?+ 'vhdl-speedbar-expand-architecture (cons token (nth 0 arch-entry)) (nth 0 arch-entry) 'vhdl-speedbar-find-file (cons (nth 1 arch-entry) (nth 2 arch-entry)) 'vhdl-speedbar-architecture-face (1+ indent)) (setq arch-alist (cdr arch-alist))) ;; insert configurations (when conf-alist (vhdl-speedbar-make-title-line "Configurations:" (1+ indent))) (while conf-alist (setq conf-entry (car conf-alist)) (speedbar-make-tag-line nil nil nil (cons token (nth 0 conf-entry)) (nth 0 conf-entry) 'vhdl-speedbar-find-file (cons (nth 1 conf-entry) (nth 2 conf-entry)) 'vhdl-speedbar-configuration-face (1+ indent)) (setq conf-alist (cdr conf-alist))) ;; insert instantiations (when inst-alist (vhdl-speedbar-make-title-line "Instantiations:" (1+ indent))) (while inst-alist (setq inst-entry (car inst-alist)) (vhdl-speedbar-make-inst-line (nth 0 inst-entry) (nth 1 inst-entry) (nth 2 inst-entry) (nth 3 inst-entry) (nth 4 inst-entry) (nth 5 inst-entry) (1+ indent) 0) (setq inst-alist (cdr inst-alist))))) (setq speedbar-last-selected-file nil) (save-excursion (speedbar-stealthy-updates))))) ((string-match "-" text) ; contract entity (speedbar-change-expand-button-char ?+) ;; remove entity from `vhdl-speedbar-shown-units-alist' (let* ((directory (if (vhdl-speedbar-project-p) vhdl-project (abbreviate-file-name (file-name-as-directory (speedbar-line-path))))) (ent-alist (aget vhdl-speedbar-shown-units-alist directory))) (adelete 'ent-alist (speedbar-line-text)) (if ent-alist (aput 'vhdl-speedbar-shown-units-alist directory ent-alist) (adelete 'vhdl-speedbar-shown-units-alist directory))) (speedbar-delete-subblock indent)) (t (error "No architectures, configurations, nor instantiations exist for this entity"))) (speedbar-center-buffer-smartly)) (defun vhdl-speedbar-expand-architecture (text token indent) "Expand/contract the architecture under the cursor." (cond ((string-match "+" text) ; expand architecture (let ((hier-alist (vhdl-get-hierarchy (car token) (cdr token) 0 indent))) (if (not hier-alist) (speedbar-change-expand-button-char ??) (speedbar-change-expand-button-char ?-) ;; add architecture to `vhdl-speedbar-shown-units-alist' (let* ((path (speedbar-line-path)) (dummy (string-match "^\\(.+/\\)\\([^/ ]+\\)" path)) (ent-name (match-string 2 path)) (directory (if (vhdl-speedbar-project-p) vhdl-project (abbreviate-file-name (match-string 1 path)))) (ent-alist (aget vhdl-speedbar-shown-units-alist directory)) (arch-alist (nth 0 (aget ent-alist ent-name t)))) (aput 'ent-alist ent-name (list (cons (speedbar-line-text) arch-alist))) (aput 'vhdl-speedbar-shown-units-alist directory ent-alist)) (speedbar-with-writable (save-excursion (end-of-line) (forward-char 1) ;; insert instance hierarchy (when hier-alist (vhdl-speedbar-make-title-line "Subcomponents:" (1+ indent))) (while hier-alist (let ((entry (car hier-alist))) (vhdl-speedbar-make-inst-line (nth 0 entry) (nth 1 entry) (nth 2 entry) (nth 3 entry) (nth 4 entry) (nth 5 entry) (1+ indent) (nth 6 entry)) (setq hier-alist (cdr hier-alist)))))) (setq speedbar-last-selected-file nil) (save-excursion (speedbar-stealthy-updates))))) ((string-match "-" text) ; contract architecture (speedbar-change-expand-button-char ?+) ;; remove architecture from `vhdl-speedbar-shown-units-alist' (let* ((path (speedbar-line-path)) (dummy (string-match "^\\(.+/\\)\\([^/ ]+\\)" path)) (ent-name (match-string 2 path)) (directory (if (vhdl-speedbar-project-p) vhdl-project (abbreviate-file-name (match-string 1 path)))) (ent-alist (aget vhdl-speedbar-shown-units-alist directory)) (arch-alist (nth 0 (aget ent-alist ent-name t)))) (aput 'ent-alist ent-name (list (delete (speedbar-line-text) arch-alist))) (aput 'vhdl-speedbar-shown-units-alist directory ent-alist)) (speedbar-delete-subblock indent)) (t (error "No component instantiations contained in this architecture"))) (speedbar-center-buffer-smartly)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Display help functions (defun vhdl-speedbar-update-current-unit (&optional no-position) "Highlight all design units that are contained in the current file. NO-POSITION non-nil means do not re-position cursor." (let ((last-frame (selected-frame)) file-name position) ;; get current file name (select-frame speedbar-attached-frame) (setq file-name (abbreviate-file-name (or (buffer-file-name) ""))) (unless (equal file-name speedbar-last-selected-file) (select-frame speedbar-frame) (set-buffer speedbar-buffer) (speedbar-with-writable (save-excursion ;; unhighlight last units (let* ((file-entry (aget vhdl-file-alist speedbar-last-selected-file))) (vhdl-speedbar-update-units "\\[.\\]" (nth 0 file-entry) speedbar-last-selected-file 'vhdl-speedbar-entity-face) (vhdl-speedbar-update-units "{.}" (nth 1 file-entry) speedbar-last-selected-file 'vhdl-speedbar-architecture-face) (vhdl-speedbar-update-units ">" (nth 2 file-entry) speedbar-last-selected-file 'vhdl-speedbar-configuration-face) (vhdl-speedbar-update-units ">" (nth 3 file-entry) speedbar-last-selected-file 'vhdl-speedbar-package-face) (vhdl-speedbar-update-units ">" (nth 4 file-entry) speedbar-last-selected-file 'vhdl-speedbar-instantiation-face)) ;; highlight current units (let* ((file-entry (aget vhdl-file-alist file-name))) (vhdl-speedbar-update-units "\\[.\\]" (nth 0 file-entry) file-name 'vhdl-speedbar-entity-selected-face) (setq position (or position (point-marker))) (vhdl-speedbar-update-units "{.}" (nth 1 file-entry) file-name 'vhdl-speedbar-architecture-selected-face) (setq position (or position (point-marker))) (vhdl-speedbar-update-units ">" (nth 2 file-entry) file-name 'vhdl-speedbar-configuration-selected-face) (setq position (or position (point-marker))) (vhdl-speedbar-update-units ">" (nth 3 file-entry) file-name 'vhdl-speedbar-package-selected-face) (setq position (or position (point-marker))) (vhdl-speedbar-update-units ">" (nth 4 file-entry) file-name 'vhdl-speedbar-instantiation-selected-face)))) (setq position (or position (point-marker))) ;; move speedbar so the first highlighted unit is visible (when (and position (not no-position)) (goto-char position) (speedbar-center-buffer-smartly) (speedbar-position-cursor-on-line)) (setq speedbar-last-selected-file file-name)) (select-frame last-frame) t)) (defun vhdl-speedbar-update-units (text unit-list file-name face) "Help function to highlight design units." (let (position) (while unit-list (goto-char (point-min)) (while (re-search-forward (concat text " \\(" (car unit-list) "\\)\\>") nil t) (when (equal file-name (car (get-text-property (match-beginning 1) 'speedbar-token))) (setq position (or position (point-marker))) (put-text-property (match-beginning 1) (match-end 1) 'face face))) (setq unit-list (cdr unit-list))) (when position (goto-char position)))) (defun vhdl-speedbar-make-inst-line (inst-name inst-file-marker ent-name ent-file-marker arch-name arch-file-marker depth offset) "Insert instantiation entry." (let ((start (point))) (insert (int-to-string depth) ":") (put-text-property start (point) 'invisible t) (setq start (point)) (insert-char ? (+ depth (* offset vhdl-speedbar-hierarchy-indent))) (insert "> ") (put-text-property start (point) 'invisible nil) (setq start (point)) (insert inst-name) (speedbar-make-button start (point) 'vhdl-speedbar-instantiation-face 'speedbar-highlight-face 'vhdl-speedbar-find-file inst-file-marker) (setq start (point)) (insert ": ") (put-text-property start (point) 'invisible nil) (setq start (point)) (insert ent-name) (speedbar-make-button start (point) 'vhdl-speedbar-entity-face 'speedbar-highlight-face 'vhdl-speedbar-find-file ent-file-marker) (setq start (point)) (when arch-name (insert " (") (put-text-property start (point) 'invisible nil) (setq start (point)) (insert arch-name) (speedbar-make-button start (point) 'vhdl-speedbar-architecture-face 'speedbar-highlight-face 'vhdl-speedbar-find-file arch-file-marker) (setq start (point)) (insert ")")) (put-text-property start (point) 'invisible nil) (insert-char ?\n 1) (put-text-property (1- (point)) (point) 'invisible nil))) (defun vhdl-speedbar-make-pack-line (pack-name pack-file-marker body-file-marker depth) "Insert package entry." (let ((start (point))) (insert (int-to-string depth) ":") (put-text-property start (point) 'invisible t) (setq start (point)) (insert-char ? depth) (insert "> ") (put-text-property start (point) 'invisible nil) (setq start (point)) (insert pack-name) (speedbar-make-button start (point) 'vhdl-speedbar-package-face 'speedbar-highlight-face 'vhdl-speedbar-find-file pack-file-marker) (when (car body-file-marker) (setq start (point)) (insert " (") (put-text-property start (point) 'invisible nil) (setq start (point)) (insert "body") (speedbar-make-button start (point) 'vhdl-speedbar-package-face 'speedbar-highlight-face 'vhdl-speedbar-find-file body-file-marker) (setq start (point)) (insert ")") (put-text-property start (point) 'invisible nil)) (insert-char ?\n 1) (put-text-property (1- (point)) (point) 'invisible nil))) (defun vhdl-speedbar-make-title-line (text depth) "Insert design unit title entry." (let ((start (point))) (insert (int-to-string depth) ":") (put-text-property start (point) 'invisible t) (setq start (point)) (insert-char ? depth) (put-text-property start (point) 'invisible nil) (setq start (point)) (insert text) (speedbar-make-button start (point) nil nil nil nil) (insert-char ?\n 1) (put-text-property start (point) 'invisible nil))) (defun vhdl-speedbar-insert-dirs (files level) "Insert subdirectories." (let ((dirs (car files))) (while dirs (speedbar-make-tag-line 'angle ?+ 'vhdl-speedbar-dired (car dirs) (car dirs) 'speedbar-dir-follow nil 'speedbar-directory-face level) (setq dirs (cdr dirs))))) (defun vhdl-speedbar-dired (text token indent) "Speedbar click handler for directory expand button in hierarchy mode." (cond ((string-match "+" text) ; we have to expand this dir (setq speedbar-shown-directories (cons (expand-file-name (concat (speedbar-line-path indent) token "/")) speedbar-shown-directories)) (speedbar-change-expand-button-char ?-) (speedbar-reset-scanners) (speedbar-with-writable (save-excursion (end-of-line) (forward-char 1) (vhdl-speedbar-insert-dirs (speedbar-file-lists (concat (speedbar-line-path indent) token "/")) (1+ indent)) (speedbar-reset-scanners) (vhdl-speedbar-insert-dir-hierarchy (abbreviate-file-name (concat (speedbar-line-path indent) token "/")) (1+ indent) speedbar-power-click))) (setq speedbar-last-selected-file nil) (save-excursion (speedbar-stealthy-updates))) ((string-match "-" text) ; we have to contract this node (speedbar-reset-scanners) (let ((oldl speedbar-shown-directories) (newl nil) (td (expand-file-name (concat (speedbar-line-path indent) token)))) (while oldl (if (not (string-match (concat "^" (regexp-quote td)) (car oldl))) (setq newl (cons (car oldl) newl))) (setq oldl (cdr oldl))) (setq speedbar-shown-directories (nreverse newl))) (speedbar-change-expand-button-char ?+) (speedbar-delete-subblock indent)) (t (error "Ooops... not sure what to do"))) (speedbar-center-buffer-smartly)) (defun vhdl-speedbar-item-info () "Derive and display information about this line item." (save-excursion (beginning-of-line) ;; skip invisible number info (when (looking-at "[0-9]+:") (goto-char (match-end 0))) (when (looking-at "p:") (message "Project \"%s\"" (nth 0 (aget vhdl-project-alist vhdl-project)))) (cond ;; directory entry ((looking-at "\\s-*<[-+?]> ") (speedbar-files-item-info)) ;; design unit entry ((looking-at "\\s-*\\([[{][-+?][]}]\\|>\\) ") (goto-char (match-end 0)) (let ((face (get-text-property (point) 'face))) (message "%s \"%s\" in \"%s\"" ;; design unit kind (cond ((or (eq face 'vhdl-speedbar-entity-face) (eq face 'vhdl-speedbar-entity-selected-face)) "Entity") ((or (eq face 'vhdl-speedbar-architecture-face) (eq face 'vhdl-speedbar-architecture-selected-face)) "Architecture") ((or (eq face 'vhdl-speedbar-configuration-face) (eq face 'vhdl-speedbar-configuration-selected-face)) "Configuration") ((or (eq face 'vhdl-speedbar-package-face) (eq face 'vhdl-speedbar-package-selected-face)) "Package") ((or (eq face 'vhdl-speedbar-instantiation-face) (eq face 'vhdl-speedbar-instantiation-selected-face)) "Instantiation") (t "")) ;; design unit name (buffer-substring-no-properties (point) (progn (looking-at"\\(\\w\\|_\\)+") (match-end 0))) ;; file name (abbreviate-file-name (or (car (get-text-property (point) 'speedbar-token)) "?")))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Help functions (defun vhdl-get-subdirs (directory) "Recursively get subdirectories of DIRECTORY." (let ((dir-list (list (file-name-as-directory directory))) subdir-list file-list) (setq file-list (vhdl-directory-files directory t "\\w.*")) (while file-list (when (file-directory-p (car file-list)) (setq dir-list (append dir-list (vhdl-get-subdirs (car file-list))))) (setq file-list (cdr file-list))) dir-list)) (defun vhdl-resolve-paths (path-list) "Resolve environment variables and path wildcards in PATH-LIST." (let (path-list-1 path-list-2 path-list-3 path-beg path-end dir) ;; resolve environment variables (while path-list (setq dir (car path-list)) (while (string-match "\\(.*\\)${?\\(\\(\\w\\|_\\)+\\)}?\\(.*\\)" dir) (setq dir (concat (match-string 1 dir) (getenv (match-string 2 dir)) (match-string 4 dir)))) (setq path-list-1 (cons dir path-list-1)) (setq path-list (cdr path-list))) ;; eliminate non-existent directories (while path-list-1 (setq dir (car path-list-1)) (string-match "\\(-r \\)?\\(\\([^?*]*/\\)*\\)" dir) (if (file-directory-p (match-string 2 dir)) (setq path-list-2 (cons dir path-list-2)) (message "No such directory: \"%s\"" (match-string 2 dir))) (setq path-list-1 (cdr path-list-1))) ;; resolve path wildcards (while path-list-2 (setq dir (car path-list-2)) (if (string-match "\\(-r \\)?\\(\\([^?*]*/\\)*\\)\\([^/]*[?*][^/]*\\)\\(/.*\\)" dir) (progn (setq path-beg (match-string 1 dir) path-end (match-string 5 dir)) (setq path-list-2 (append (mapcar (function (lambda (var) (concat path-beg var path-end))) (let ((all-list (vhdl-directory-files (match-string 2 dir) t (concat "\\<" (wildcard-to-regexp (match-string 4 dir))))) dir-list) (while all-list (when (file-directory-p (car all-list)) (setq dir-list (cons (car all-list) dir-list))) (setq all-list (cdr all-list))) dir-list)) (cdr path-list-2)))) (string-match "\\(-r \\)?\\(.*\\)/.*" dir) (when (file-directory-p (match-string 2 dir)) (setq path-list-3 (cons dir path-list-3))) (setq path-list-2 (cdr path-list-2)))) path-list-3)) (defun vhdl-aappend (alist-symbol key value) "Append a key-value pair to an alist. Similar to `aput' but moves the key-value pair to the tail of the alist." (let ((elem (aelement key value)) (alist (adelete alist-symbol key))) (set alist-symbol (append alist elem)))) (defun vhdl-speedbar-goto-this-unit (directory unit) "If UNIT is displayed in DIRECTORY, goto this line and return t, else nil." (let ((dest (point))) (if (and (if (vhdl-speedbar-project-p) (progn (goto-char (point-min)) t) (speedbar-goto-this-file directory)) (re-search-forward (concat "[]}] " unit "\\>") nil t)) (progn (speedbar-position-cursor-on-line) t) (goto-char dest) nil))) (defun vhdl-speedbar-find-file (text token indent) "When user clicks on TEXT, load file with name and position in TOKEN." (if (not (car token)) (error "Design unit does not exist") (speedbar-find-file-in-frame (car token)) (goto-line (cdr token)) (recenter) (vhdl-speedbar-update-current-unit t) (speedbar-set-timer speedbar-update-speed) (speedbar-maybee-jump-to-attached-frame))) (defun vhdl-speedbar-toggle-hierarchy () "Toggle between hierarchy and file browsing mode." (interactive) (if (not (boundp 'speedbar-mode-functions-list)) (error "WARNING: Install included `speedbar.el' patch first") (if (equal speedbar-initial-expansion-list-name "vhdl hierarchy") (speedbar-change-initial-expansion-list "files") (speedbar-change-initial-expansion-list "vhdl hierarchy")))) (defun vhdl-speedbar-port-copy () "Copy the port of the entity under the cursor." (interactive) (beginning-of-line) (if (re-search-forward "\\([0-9]\\)+:\\s-*\\[[-+?]\\] \\(\\(\\w\\|\\s_\\)+\\)" (save-excursion (end-of-line) (point)) t) (condition-case () (let* ((indent (string-to-number (match-string 1))) (ent-name (match-string 2)) (ent-alist (if (vhdl-speedbar-project-p) (aget vhdl-project-entity-alist vhdl-project) (aget vhdl-entity-alist (abbreviate-file-name (file-name-as-directory (speedbar-line-path indent)))))) (ent-entry (aget ent-alist ent-name)) (file-name (nth 0 ent-entry)) opened) ;; open file (if (find-buffer-visiting file-name) (set-buffer (file-name-nondirectory file-name)) (set-buffer (find-file-noselect file-name nil t)) (modify-syntax-entry ?\- ". 12" (syntax-table)) (modify-syntax-entry ?\n ">" (syntax-table)) (modify-syntax-entry ?\^M ">" (syntax-table)) (setq opened t)) ;; scan port (goto-line (nth 1 ent-entry)) (end-of-line) (vhdl-port-copy) ;; close file (when opened (kill-buffer (current-buffer)))) (error (error "Port not scanned successfully"))) (error "No entity on current line"))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Fontification (defface vhdl-speedbar-entity-face '((((class color) (background light)) (:foreground "ForestGreen")) (((class color) (background dark)) (:foreground "PaleGreen"))) "Face used for displaying entity names." :group 'speedbar-faces) (defface vhdl-speedbar-architecture-face '((((class color) (background light)) (:foreground "Blue")) (((class color) (background dark)) (:foreground "LightSkyBlue"))) "Face used for displaying architecture names." :group 'speedbar-faces) (defface vhdl-speedbar-configuration-face '((((class color) (background light)) (:foreground "DarkGoldenrod")) (((class color) (background dark)) (:foreground "Salmon"))) "Face used for displaying configuration names." :group 'speedbar-faces) (defface vhdl-speedbar-package-face '((((class color) (background light)) (:foreground "Grey50")) (((class color) (background dark)) (:foreground "Grey80"))) "Face used for displaying package names." :group 'speedbar-faces) (defface vhdl-speedbar-instantiation-face '((((class color) (background light)) (:foreground "Brown")) (((class color) (background dark)) (:foreground "Yellow"))) "Face used for displaying instantiation names." :group 'speedbar-faces) (defface vhdl-speedbar-entity-selected-face '((((class color) (background light)) (:foreground "ForestGreen" :underline t)) (((class color) (background dark)) (:foreground "PaleGreen" :underline t))) "Face used for displaying entity names." :group 'speedbar-faces) (defface vhdl-speedbar-architecture-selected-face '((((class color) (background light)) (:foreground "Blue" :underline t)) (((class color) (background dark)) (:foreground "LightSkyBlue" :underline t))) "Face used for displaying architecture names." :group 'speedbar-faces) (defface vhdl-speedbar-configuration-selected-face '((((class color) (background light)) (:foreground "DarkGoldenrod" :underline t)) (((class color) (background dark)) (:foreground "Salmon" :underline t))) "Face used for displaying configuration names." :group 'speedbar-faces) (defface vhdl-speedbar-package-selected-face '((((class color) (background light)) (:foreground "Grey50" :underline t)) (((class color) (background dark)) (:foreground "Grey80" :underline t))) "Face used for displaying package names." :group 'speedbar-faces) (defface vhdl-speedbar-instantiation-selected-face '((((class color) (background light)) (:foreground "Brown" :underline t)) (((class color) (background dark)) (:foreground "Yellow" :underline t))) "Face used for displaying instantiation names." :group 'speedbar-faces) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Bug reports ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; (using `reporter.el') (defconst vhdl-mode-help-address "vhdl-mode@geocities.com" "Address for VHDL Mode bug reports.") (defun vhdl-version () "Echo the current version of VHDL Mode in the minibuffer." (interactive) (message "Using VHDL Mode version %s" vhdl-version) (vhdl-keep-region-active)) ;; get reporter-submit-bug-report when byte-compiling (eval-when-compile (require 'reporter)) (defun vhdl-submit-bug-report () "Submit via mail a bug report on VHDL Mode." (interactive) ;; load in reporter (and (y-or-n-p "Do you want to submit a report on VHDL Mode? ") (require 'reporter) (reporter-submit-bug-report vhdl-mode-help-address (concat "VHDL Mode " vhdl-version) (list ;; report all important variables 'vhdl-offsets-alist 'vhdl-comment-only-line-offset 'tab-width 'vhdl-electric-mode 'vhdl-stutter-mode 'vhdl-indent-tabs-mode 'vhdl-project-alist 'vhdl-project 'vhdl-compiler-alist 'vhdl-compiler 'vhdl-compiler-options 'vhdl-standard 'vhdl-basic-offset 'vhdl-upper-case-keywords 'vhdl-upper-case-types 'vhdl-upper-case-attributes 'vhdl-upper-case-enum-values 'vhdl-upper-case-constants 'vhdl-electric-keywords 'vhdl-optional-labels 'vhdl-insert-empty-lines 'vhdl-argument-list-indent 'vhdl-association-list-with-formals 'vhdl-conditions-in-parenthesis 'vhdl-zero-string 'vhdl-one-string 'vhdl-file-header 'vhdl-file-footer 'vhdl-company-name 'vhdl-platform-spec 'vhdl-date-format 'vhdl-modify-date-prefix-string 'vhdl-modify-date-on-saving 'vhdl-reset-kind 'vhdl-reset-active-high 'vhdl-clock-rising-edge 'vhdl-clock-edge-condition 'vhdl-clock-name 'vhdl-reset-name 'vhdl-model-alist 'vhdl-include-port-comments 'vhdl-include-direction-comments 'vhdl-actual-port-name 'vhdl-instance-name 'vhdl-testbench-entity-name 'vhdl-testbench-architecture-name 'vhdl-testbench-dut-name 'vhdl-testbench-entity-header 'vhdl-testbench-architecture-header 'vhdl-testbench-declarations 'vhdl-testbench-statements 'vhdl-testbench-initialize-signals 'vhdl-testbench-create-files 'vhdl-self-insert-comments 'vhdl-prompt-for-comments 'vhdl-inline-comment-column 'vhdl-end-comment-column 'vhdl-auto-align 'vhdl-align-groups 'vhdl-highlight-keywords 'vhdl-highlight-names 'vhdl-highlight-special-words 'vhdl-highlight-forbidden-words 'vhdl-highlight-verilog-keywords 'vhdl-highlight-translate-off 'vhdl-highlight-case-sensitive 'vhdl-special-syntax-alist 'vhdl-forbidden-words 'vhdl-forbidden-syntax 'vhdl-speedbar 'vhdl-speedbar-show-hierarchy 'vhdl-speedbar-hierarchy-indent 'vhdl-index-menu 'vhdl-source-file-menu 'vhdl-hideshow-menu 'vhdl-hide-all-init 'vhdl-print-two-column 'vhdl-print-customize-faces 'vhdl-intelligent-tab 'vhdl-word-completion-case-sensitive 'vhdl-word-completion-in-minibuffer 'vhdl-underscore-is-part-of-word 'vhdl-mode-hook 'vhdl-startup-warnings) (function (lambda () (insert (if vhdl-special-indent-hook (concat "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n" "vhdl-special-indent-hook is set to '" (format "%s" vhdl-special-indent-hook) ".\nPerhaps this is your problem?\n" "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n") "\n")))) nil "Dear VHDL Mode maintainers,"))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (provide 'vhdl-mode) ;;; vhdl-mode.el ends here ------=_Part_252221_12725027.1199450567569 Content-Type: application/octet-stream; name=vhdl-mode.elc Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=vhdl-mode.elc O0VMQxQAAAAKOzs7IENvbXBpbGVkIGJ5IGdlcmRAZ2VyZC5zZWd2LmRlIG9uIE1vbiBKdW4gMTIg MjE6NDA6MzkgMjAwMAo7OzsgZnJvbSBmaWxlIC91Mi9lbWFjcy0yMC43L2xpc3AvcHJvZ21vZGVz L3ZoZGwtbW9kZS5lbAo7OzsgaW4gRW1hY3MgdmVyc2lvbiAyMC43LjEKOzs7IHdpdGggYnl0ZWNv bXAgdmVyc2lvbiAyLjU2Cjs7OyB3aXRoIGFsbCBvcHRpbWl6YXRpb25zLgoKOzs7IFRoaXMgZmls ZSB1c2VzIGR5bmFtaWMgZG9jc3RyaW5ncywgZmlyc3QgYWRkZWQgaW4gRW1hY3MgMTkuMjkuCihp ZiAoYW5kIChib3VuZHAgJ2VtYWNzLXZlcnNpb24pCgkgKDwgKGFyZWYgZW1hY3MtdmVyc2lvbiAo MS0gKGxlbmd0aCBlbWFjcy12ZXJzaW9uKSkpID9BKQoJIChvciAoYW5kIChib3VuZHAgJ2Vwb2No Ojp2ZXJzaW9uKSBlcG9jaDo6dmVyc2lvbikKCSAgICAgKHN0cmluZy1sZXNzcCBlbWFjcy12ZXJz aW9uICIxOS4yOSIpKSkKICAgIChlcnJvciAiYHZoZGwtbW9kZS5lbCcgd2FzIGNvbXBpbGVkIGZv ciBFbWFjcyAxOS4yOSBvciBsYXRlciIpKQoKOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7 Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7CgoKI0A3MyBTZXQgdmFyaWFibGVzIGFzIGlu IGBjdXN0b20tc2V0LWRlZmF1bHQnIGFuZCBjYWxsIEZVTkNUSU9OUyBhZnRlcndhcmRzLh8KKGRl ZmFsaWFzICd2aGRsLWN1c3RvbS1zZXQgI1sodmFyaWFibGUgdmFsdWUgJnJlc3QgZnVuY3Rpb25z KSAiXDMwM1wzMDQhXDIwMw4AXDMwNAgJXCJcMjEwXDIwMhMAXDMwNQgJXCJcMjEwXG5cMjA1KgBc MzAzXG5AIVwyMDNcIgBcbkAgXDIxMFxuQVwyMTESXDIwNBcAXDMwNlwyMDciIFt2YXJpYWJsZSB2 YWx1ZSBmdW5jdGlvbnMgZmJvdW5kcCBjdXN0b20tc2V0LWRlZmF1bHQgc2V0LWRlZmF1bHQgbmls XSA0ICgjJCAuIDYwOCldKQooYnl0ZS1jb2RlICJcMzAzXDMwNFwzMDVcMzA2CFwzMDcJXDMxMFxu XDMxMSYJXDIxMFwzMDNcMzEyXDMwNVwzMTMJXDMwNCVcMjA3IiBbOnByZWZpeCA6Z3JvdXAgOnZl cnNpb24gY3VzdG9tLWRlY2xhcmUtZ3JvdXAgdmhkbCBuaWwgIkN1c3RvbWl6YXRpb25zIGZvciBW SERMIE1vZGUuIiAidmhkbC0iIGxhbmd1YWdlcyAiMjAuNCIgdmhkbC1tb2RlICJDdXN0b21pemF0 aW9ucyBmb3IgbW9kZXMuIl0gMTApCiNAMjUyICpOb24tbmlsIGVuYWJsZXMgZWxlY3RyaWZpY2F0 aW9uIChhdXRvbWF0aWMgdGVtcGxhdGUgZ2VuZXJhdGlvbikuCklmIG5pbCwgdGVtcGxhdGUgZ2Vu ZXJhdG9ycyBjYW4gc3RpbGwgYmUgaW52b2tlZCB0aHJvdWdoIGtleSBiaW5kaW5ncyBhbmQKbWVu dS4gIElzIGluZGljYXRlZCBpbiB0aGUgbW9kZWxpbmUgYnkgYC9lJyBhZnRlciB0aGUgbW9kZSBu YW1lIGFuZCBjYW4gYmUKdG9nZ2xlZCBieSBgXFt2aGRsLWVsZWN0cmljLW1vZGVdJy4fCihjdXN0 b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC1lbGVjdHJpYy1tb2RlICd0ICcoIyQgLiAtMTE2OCkg OnR5cGUgJ2Jvb2xlYW4gOmdyb3VwICd2aGRsLW1vZGUpCiNAMTMzICpOb24tbmlsIGVuYWJsZXMg c3R1dHRlcmluZy4KSXMgaW5kaWNhdGVkIGluIHRoZSBtb2RlbGluZSBieSBgL3MnIGFmdGVyIHRo ZSBtb2RlIG5hbWUgYW5kIGNhbiBiZSB0b2dnbGVkCmJ5IGBcW3ZoZGwtc3R1dHRlci1tb2RlXScu HwooY3VzdG9tLWRlY2xhcmUtdmFyaWFibGUgJ3ZoZGwtc3R1dHRlci1tb2RlICd0ICcoIyQgLiAt MTUyMikgOnR5cGUgJ2Jvb2xlYW4gOmdyb3VwICd2aGRsLW1vZGUpCiNAOTAgKk5vbi1uaWwgbWVh bnMgaW5kZW50YXRpb24gY2FuIGluc2VydCB0YWJzLgpPdmVycmlkZXMgbG9jYWwgdmFyaWFibGUg YGluZGVudC10YWJzLW1vZGUnLh8KKGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxlICd2aGRsLWluZGVu dC10YWJzLW1vZGUgJ25pbCAnKCMkIC4gLTE3NTUpIDp0eXBlICdib29sZWFuIDpncm91cCAndmhk bC1tb2RlKQooY3VzdG9tLWRlY2xhcmUtZ3JvdXAgJ3ZoZGwtcHJvamVjdCBuaWwgIkN1c3RvbWl6 YXRpb25zIGZvciBwcm9qZWN0cy4iIDpncm91cCAndmhkbCkKI0A4MTMgKkxpc3Qgb2YgcHJvamVj dHMgYW5kIHRoZWlyIHByb3BlcnRpZXMuCiAgTmFtZSAgICAgICA6IG5hbWUgb2YgcHJvamVjdAog IFRpdGxlICAgICAgOiB0aXRsZSBvZiBwcm9qZWN0IChvbmUtbGluZSBzdHJpbmcpCiAgU291cmNl cyAgICA6IGEpIHNvdXJjZSBmaWxlcyAgOiBwYXRoICsgIi8iICsgZmlsZSBuYW1lCiAgICAgICAg ICAgICAgIGIpIGRpcmVjdG9yeSAgICAgOiBwYXRoICsgIi8iCiAgICAgICAgICAgICAgIGMpIGRp cmVjdG9yeSB0cmVlOiAiLXIgIiArIHBhdGggKyAiLyIKICBEZXNjcmlwdGlvbjogZGVzY3JpcHRp b24gb2YgcHJvamVjdCAobXVsdGktbGluZSBzdHJpbmcpCgpQcm9qZWN0IG5hbWUgYW5kIGRlc2Ny aXB0aW9uIGFyZSB1c2VkIHRvIGluc2VydCBpbnRvIHRoZSBmaWxlIGhlYWRlciAoc2VlCnZhcmlh YmxlIGB2aGRsLWZpbGUtaGVhZGVyJykuCgpQYXRoIGFuZCBmaWxlIG5hbWUgY2FuIGNvbnRhaW4g d2lsZGNhcmRzIGAqJyBhbmQgYD8nLiAgRW52aXJvbm1lbnQgdmFyaWFibGVzCihlLmcuICIkRVhB TVBMRTIiKSBhcmUgcmVzb2x2ZWQuCgpUaGUgaGllcmFyY2h5IGJyb3dzZXIgc2hvd3MgdGhlIGhp ZXJhcmNoeSBvZiB0aGUgZGVzaWduIHVuaXRzIGZvdW5kIGluCmBTb3VyY2VzJy4gIElmIG5vIGRp cmVjdG9yaWVzIG9yIGZpbGVzIGFyZSBzcGVjaWZpZWQsIHRoZSBjdXJyZW50IGRpcmVjdG9yeSBp cwpzaG93bi4KCk5PVEU6IFJlZmxlY3QgdGhlIG5ldyBzZXR0aW5nIGluIHRoZSBjaG9pY2UgbGlz dCBvZiB2YXJpYWJsZSBgdmhkbC1wcm9qZWN0JwogICAgICBieSByZXN0YXJ0aW5nIEVtYWNzLh8K KGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxlICd2aGRsLXByb2plY3QtYWxpc3QgJycoKCJleGFtcGxl IDEiICJQcm9qZWN0IHdpdGggaW5kaXZpZHVhbCBzb3VyY2UgZmlsZXMiICgifi9leGFtcGxlMS92 aGRsL3N5c3RlbS52aGQiICJ+L2V4YW1wbGUxL3ZoZGwvY29tcG9uZW50XyoudmhkIikgIi0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS1cbi0tIFRoaXMgaXMgYSBtdWx0aS1saW5lIHByb2plY3QgZGVzY3Jp cHRpb25cbi0tIHRoYXQgY2FuIGJlIHVzZWQgYXMgYSBwcm9qZWN0IGRlcGVuZGVudCBwYXJ0IG9m IHRoZSBmaWxlIGhlYWRlci5cbiIpICgiZXhhbXBsZSAyIiAiUHJvamVjdCB3aGVyZSBzb3VyY2Ug ZmlsZXMgYXJlIGxvY2F0ZWQgaW4gdHdvIGRpcmVjdG9yaWVzIiAoIiRFWEFNUExFMi92aGRsL2Nv bXBvbmVudHMvIiAiJEVYQU1QTEUyL3ZoZGwvc3lzdGVtLyIpICIiKSAoImV4YW1wbGUgMyIgIlBy b2plY3Qgd2hlcmUgc291cmNlIGZpbGVzIGFyZSBsb2NhdGVkIGluIHNvbWUgZGlyZWN0b3J5IHRy ZWVzIiAoIi1yIH4vZXhhbXBsZTMvKi92aGRsLyIpICIiKSkgJygjJCAuIC0yMDM3KSA6dHlwZSAn KHJlcGVhdCAobGlzdCA6dGFnICJQcm9qZWN0IiA6aW5kZW50IDIgKHN0cmluZyA6dGFnICJOYW1l ICIpIChzdHJpbmcgOnRhZyAiVGl0bGUiKSAocmVwZWF0IDp0YWcgIlNvdXJjZXMiIDppbmRlbnQg NCAoc3RyaW5nIDpmb3JtYXQgIiV2IikpIChzdHJpbmcgOnRhZyAiRGVzY3JpcHRpb246ICh0eXBl IGBDLWonIGZvciBuZXdsaW5lKSIgOmZvcm1hdCAiJXRcbiV2IikpKSA6c2V0IChsYW1iZGEgKHZh cmlhYmxlIHZhbHVlKSAodmhkbC1jdXN0b20tc2V0IHZhcmlhYmxlIHZhbHVlICd2aGRsLXVwZGF0 ZS1tb2RlLW1lbnUpKSA6Z3JvdXAgJ3ZoZGwtcHJvamVjdCkKI0AzNTIgKlNwZWNpZmllcyB0aGUg ZGVmYXVsdCBmb3IgdGhlIGN1cnJlbnQgcHJvamVjdC4KU2VsZWN0IGEgcHJvamVjdCBuYW1lIGZy b20gdGhlIG9uZXMgZGVmaW5lZCBpbiB2YXJpYWJsZSBgdmhkbC1wcm9qZWN0LWFsaXN0Jy4KSXMg dXNlZCB0byBkZXRlcm1pbmUgdGhlIHByb2plY3QgdGl0bGUgYW5kIGRlc2NyaXB0aW9uIHRvIGJl IGluc2VydGVkIGluIGZpbGUKaGVhZGVycyBhbmQgdGhlIHNvdXJjZSBmaWxlcy9kaXJlY3Rvcmll cyB0byBiZSBzY2FubmVkIGluIHRoZSBoaWVyYXJjaHkKYnJvd3Nlci4gIFRoZSBjdXJyZW50IHBy b2plY3QgY2FuIGFsc28gYmUgY2hhbmdlZCB0ZW1wb3JhcmlseSBpbiB0aGUgbWVudS4fCihjdXN0 b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC1wcm9qZWN0ICciIiAnKCMkIC4gLTM4MDQpIDp0eXBl IChsZXQgKChwcm9qZWN0LWFsaXN0IHZoZGwtcHJvamVjdC1hbGlzdCkgY2hvaWNlLWxpc3QpICh3 aGlsZSBwcm9qZWN0LWFsaXN0IChzZXRxIGNob2ljZS1saXN0IChjb25zIChsaXN0ICdjb25zdCAo Y2FyIChjYXIgcHJvamVjdC1hbGlzdCkpKSBjaG9pY2UtbGlzdCkpIChzZXRxIHByb2plY3QtYWxp c3QgKGNkciBwcm9qZWN0LWFsaXN0KSkpIChhcHBlbmQgJyhjaG9pY2UgKGNvbnN0IDp0YWcgIk5v bmUiICIiKSAoY29uc3QgOnRhZyAiLS0iKSkgKG5yZXZlcnNlIGNob2ljZS1saXN0KSkpIDpncm91 cCAndmhkbC1wcm9qZWN0KQooY3VzdG9tLWRlY2xhcmUtZ3JvdXAgJ3ZoZGwtY29tcGlsZSBuaWwg IkN1c3RvbWl6YXRpb25zIGZvciBjb21waWxhdGlvbi4iIDpncm91cCAndmhkbCkKI0AxMzg5ICpM aXN0IG9mIGF2YWlsYWJsZSBWSERMIGNvbXBpbGVycyBhbmQgdGhlaXIgcHJvcGVydGllcy4KRWFj aCBsaXN0IGVudHJ5IHNwZWNpZmllcyB0aGUgZm9sbG93aW5nIGl0ZW1zIGZvciBhIGNvbXBpbGVy OgpDb21waWxlcjoKICBDb21waWxlciBOYW1lICAgIDogbmFtZSB1c2VkIGluIHZhcmlhYmxlIGB2 aGRsLWNvbXBpbGVyJyB0byBjaG9vc2UgY29tcGlsZXIKICBDb21waWxlIENvbW1hbmQgIDogY29t bWFuZCBpbmNsdWRpbmcgb3B0aW9ucyB1c2VkIGZvciBzeW50YXggYW5hbHlzaXMKICBNYWtlIENv bW1hbmQgICAgIDogY29tbWFuZCBpbmNsdWRpbmcgb3B0aW9ucyB1c2VkIGluc3RlYWQgb2YgYG1h a2UnIChkZWZhdWx0KQogIEdlbmVyYXRlIE1ha2VmaWxlOiBjb21tYW5kIHRvIGdlbmVyYXRlIGEg TWFrZWZpbGUgKHVzZWQgYnkgYG1ha2UnIGNvbW1hbmQpCiAgRnJvbSBEaXJlY3RvcnkgICA6IGRp cmVjdG9yeSB3aGVyZSBjb21waWxhdGlvbiBpcyBydW4gKG11c3QgZW5kIHdpdGggJy8nKQpFcnJv ciBNZXNzYWdlOgogIFJlZ2V4cCAgICAgICAgICAgOiByZWd1bGFyIGV4cHJlc3Npb24gdG8gbWF0 Y2ggZXJyb3IgbWVzc2FnZXMKICBGaWxlIFN1YmV4cCBJbmRleDogaW5kZXggb2Ygc3ViZXhwcmVz c2lvbiB0aGF0IG1hdGNoZXMgdGhlIGZpbGUgbmFtZQogIExpbmUgU3ViZXhwIEluZGV4OiBpbmRl eCBvZiBzdWJleHByZXNzaW9uIHRoYXQgbWF0Y2hlcyB0aGUgbGluZSBudW1iZXIKRmlsZSBNZXNz YWdlOgogIFJlZ2V4cCAgICAgICAgICAgOiByZWd1bGFyIGV4cHJlc3Npb24gdG8gbWF0Y2ggYSBm aWxlIG5hbWUgbWVzc2FnZQogIEZpbGUgU3ViZXhwIEluZGV4OiBpbmRleCBvZiBzdWJleHByZXNz aW9uIHRoYXQgbWF0Y2hlcyB0aGUgZmlsZSBuYW1lCgpTZWUgYWxzbyB2YXJpYWJsZSBgdmhkbC1j b21waWxlci1vcHRpb25zJyB0byBhZGQgb3B0aW9ucyB0byB0aGUgY29tcGlsZQpjb21tYW5kLgoK U29tZSBjb21waWxlcnMgZG8gbm90IGluY2x1ZGUgdGhlIGZpbGUgbmFtZSBpbiB0aGUgZXJyb3Ig bWVzc2FnZSwgYnV0IHByaW50Cm91dCBhIGZpbGUgbmFtZSBtZXNzYWdlIGluIGFkdmFuY2UuICBJ biB0aGlzIGNhc2UsIHNldCAiRmlsZSBTdWJleHAgSW5kZXgiCnRvIDAgYW5kIGZpbGwgb3V0IHRo ZSAiRmlsZSBNZXNzYWdlIiBlbnRyaWVzLgoKQSBjb21waWxlciBpcyBzZWxlY3RlZCBmb3Igc3lu dGF4IGFuYWx5c2lzIChgXFt2aGRsLWNvbXBpbGVdJykgYnkKYXNzaWduaW5nIGl0cyBuYW1lIHRv IHZhcmlhYmxlIGB2aGRsLWNvbXBpbGVyJy4KCk5PVEU6IFJlZmxlY3QgdGhlIG5ldyBzZXR0aW5n IGluIHRoZSBjaG9pY2UgbGlzdCBvZiB2YXJpYWJsZSBgdmhkbC1jb21waWxlcicKICAgICAgYnkg cmVzdGFydGluZyBFbWFjcy4fCihjdXN0b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC1jb21waWxl ci1hbGlzdCAnJygoIkNhZGVuY2UiICJjdiAtZmlsZSIgIiIgIiIgIi4vIiAoImR1bHV0aDogXFwq RSxbMC05XSsgKFxcKC4rXFwpLFxcKFswLTldK1xcKSk6IiAxIDIpICgiIiAwKSkgKCJJa29zIiAi YW5hbHl6ZSIgIiIgIiIgIi4vIiAoIkUgTFxcKFswLTldK1xcKS9DWzAtOV0rOiIgMCAxKSAoIl5h bmFseXplICtcXCguKyArXFwpKlxcKC4rXFwpJCIgMikpICgiTW9kZWxTaW0iICJ2Y29tIiAiIiAi dm1ha2UgPiBNYWtlZmlsZSIgIi4vIiAoIlxcKEVSUk9SXFx8V0FSTklOR1xcKVteOl0qOiBcXCgu K1xcKShcXChbMC05XStcXCkpOiIgMiAzKSAoIiIgMCkpICgiUXVpY2tIREwiICJxdmhjb20iICIi ICJxaG1ha2UgPiEgTWFrZWZpbGUiICIuLyIgKCJcXChFUlJPUlxcfFdBUk5JTkdcXClbXjpdKjog XFwoLitcXCkoXFwoWzAtOV0rXFwpKToiIDIgMykgKCIiIDApKSAoIlN5bm9wc3lzIiAidmhkbGFu IiAiIiAiIiAiLi8iICgiXFwqXFwqRXJyb3I6IHZoZGxhbixbMC05XSsgXFwoLitcXCkoXFwoWzAt OV0rXFwpKToiIDEgMikgKCIiIDApKSAoIlZhbnRhZ2UiICJhbmFseXplIC1saWJmaWxlIHZzc2xp Yi5pbmkgLXNyYyIgIiIgIiIgIi4vIiAoIlxcKlxcKkVycm9yOiBMSU5FIFxcKFswLTldK1xcKSBc XCpcXCpcXCoiIDAgMSkgKCJeICpDb21waWxpbmcgXCJcXCguK1xcKVwiICIgMSkpICgiVmlld2xv Z2ljIiAiYW5hbHl6ZSAtbGliZmlsZSB2c3NsaWIuaW5pIC1zcmMiICIiICIiICIuLyIgKCJcXCpc XCpFcnJvcjogTElORSBcXChbMC05XStcXCkgXFwqXFwqXFwqIiAwIDEpICgiXiAqQ29tcGlsaW5n IFwiXFwoLitcXClcIiAiIDEpKSkgJygjJCAuIC00NjE1KSA6dHlwZSAnKHJlcGVhdCAobGlzdCA6 dGFnICJDb21waWxlciIgOmluZGVudCAyIChzdHJpbmcgOnRhZyAiQ29tcGlsZXIgTmFtZSAgICAi KSAoc3RyaW5nIDp0YWcgIkNvbXBpbGUgQ29tbWFuZCAgIikgKHN0cmluZyA6dGFnICJNYWtlIENv bW1hbmQgICAgICIpIChzdHJpbmcgOnRhZyAiR2VuZXJhdGUgTWFrZWZpbGUiKSAoc3RyaW5nIDp0 YWcgIkZyb20gRGlyZWN0b3J5ICAgIiAiLi8iKSAobGlzdCA6dGFnICJFcnJvciBNZXNzYWdlIiA6 aW5kZW50IDQgKHJlZ2V4cCA6dGFnICJSZWdleHAgICAgICAgICAgICIpIChpbnRlZ2VyIDp0YWcg IkZpbGUgU3ViZXhwIEluZGV4IikgKGludGVnZXIgOnRhZyAiTGluZSBTdWJleHAgSW5kZXgiKSkg KGxpc3QgOnRhZyAiRmlsZSBNZXNzYWdlIiA6aW5kZW50IDQgKHJlZ2V4cCA6dGFnICJSZWdleHAg ICAgICAgICAgICIpIChpbnRlZ2VyIDp0YWcgIkZpbGUgU3ViZXhwIEluZGV4IikpKSkgOnNldCAo bGFtYmRhICh2YXJpYWJsZSB2YWx1ZSkgKHZoZGwtY3VzdG9tLXNldCB2YXJpYWJsZSB2YWx1ZSAn dmhkbC11cGRhdGUtbW9kZS1tZW51KSkgOmdyb3VwICd2aGRsLWNvbXBpbGUpCiNAMTQyICpTcGVj aWZpZXMgdGhlIFZIREwgY29tcGlsZXIgdG8gYmUgdXNlZCBmb3Igc3ludGF4IGFuYWx5c2lzLgpT ZWxlY3QgYSBjb21waWxlciBuYW1lIGZyb20gdGhlIG9uZXMgZGVmaW5lZCBpbiB2YXJpYWJsZSBg dmhkbC1jb21waWxlci1hbGlzdCcuHwooY3VzdG9tLWRlY2xhcmUtdmFyaWFibGUgJ3ZoZGwtY29t cGlsZXIgJyJNb2RlbFNpbSIgJygjJCAuIC03NDYyKSA6dHlwZSAobGV0ICgoY29tcGlsZXItYWxp c3QgdmhkbC1jb21waWxlci1hbGlzdCkgY2hvaWNlLWxpc3QpICh3aGlsZSBjb21waWxlci1hbGlz dCAoc2V0cSBjaG9pY2UtbGlzdCAoY29ucyAobGlzdCAnY29uc3QgKGNhciAoY2FyIGNvbXBpbGVy LWFsaXN0KSkpIGNob2ljZS1saXN0KSkgKHNldHEgY29tcGlsZXItYWxpc3QgKGNkciBjb21waWxl ci1hbGlzdCkpKSAoYXBwZW5kICcoY2hvaWNlKSAobnJldmVyc2UgY2hvaWNlLWxpc3QpKSkgOmdy b3VwICd2aGRsLWNvbXBpbGUpCiNANDYgKk9wdGlvbnMgdG8gYmUgYWRkZWQgdG8gdGhlIGNvbXBp bGUgY29tbWFuZC4fCihjdXN0b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC1jb21waWxlci1vcHRp b25zICciIiAnKCMkIC4gLTc5NDcpIDp0eXBlICdzdHJpbmcgOmdyb3VwICd2aGRsLWNvbXBpbGUp CihjdXN0b20tZGVjbGFyZS1ncm91cCAndmhkbC1zdHlsZSBuaWwgIkN1c3RvbWl6YXRpb25zIGZv ciBjb2RlIHN0eWxlcy4iIDpncm91cCAndmhkbCkKI0AzNTggKlZIREwgc3RhbmRhcmRzIHVzZWQu CkJhc2ljIHN0YW5kYXJkOgogIFZIREwnODcgICAgICA6IElFRUUgU3RkIDEwNzYtMTk4NwogIFZI REwnOTMgICAgICA6IElFRUUgU3RkIDEwNzYtMTk5MwpBZGRpdGlvbmFsIHN0YW5kYXJkczoKICBW SERMLUFNUyAgICAgOiBJRUVFIFN0ZCAxMDc2LjEgKGFuYWxvZy1taXhlZC1zaWduYWwpCiAgTWF0 aCBQYWNrYWdlczogSUVFRSBTdGQgMTA3Ni4yIChgbWF0aF9yZWFsJywgYG1hdGhfY29tcGxleCcp CgpOT1RFOiBBY3RpdmF0ZSB0aGUgbmV3IHNldHRpbmcgaW4gYSBWSERMIGJ1ZmZlciB1c2luZyB0 aGUgbWVudSBlbnRyeQogICAgICAiQWN0aXZhdGUgTmV3IEN1c3RvbWl6YXRpb25zIi4fCihjdXN0 b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC1zdGFuZGFyZCAnJyg4NyBuaWwpICcoIyQgLiAtODE4 NykgOnR5cGUgJyhsaXN0IChjaG9pY2UgOnRhZyAiQmFzaWMgc3RhbmRhcmQiIChjb25zdCA6dGFn ICJWSERMJzg3IiA4NykgKGNvbnN0IDp0YWcgIlZIREwnOTMiIDkzKSkgKHNldCA6dGFnICJBZGRp dGlvbmFsIHN0YW5kYXJkcyIgOmluZGVudCAyIChjb25zdCA6dGFnICJWSERMLUFNUyIgYW1zKSAo Y29uc3QgOnRhZyAiTWF0aCBQYWNrYWdlcyIgbWF0aCkpKSA6c2V0IChsYW1iZGEgKHZhcmlhYmxl IHZhbHVlKSAodmhkbC1jdXN0b20tc2V0IHZhcmlhYmxlIHZhbHVlICd2aGRsLXRlbXBsYXRlLW1h cC1pbml0ICd2aGRsLW1vZGUtYWJicmV2LXRhYmxlLWluaXQgJ3ZoZGwtdGVtcGxhdGUtY29uc3Ry dWN0LWFsaXN0LWluaXQgJ3ZoZGwtdGVtcGxhdGUtcGFja2FnZS1hbGlzdC1pbml0ICd2aGRsLXVw ZGF0ZS1tb2RlLW1lbnUgJ3ZoZGwtd29yZHMtaW5pdCAndmhkbC1mb250LWxvY2staW5pdCkpIDpn cm91cCAndmhkbC1zdHlsZSkKI0AxMTAgKkFtb3VudCBvZiBiYXNpYyBvZmZzZXQgdXNlZCBmb3Ig aW5kZW50YXRpb24uClRoaXMgdmFsdWUgaXMgdXNlZCBieSArIGFuZCAtIHN5bWJvbHMgaW4gYHZo ZGwtb2Zmc2V0cy1hbGlzdCcuHwooY3VzdG9tLWRlY2xhcmUtdmFyaWFibGUgJ3ZoZGwtYmFzaWMt b2Zmc2V0ICcyICcoIyQgLiAtOTA4NykgOnR5cGUgJ2ludGVnZXIgOmdyb3VwICd2aGRsLXN0eWxl KQojQDExNCAqTm9uLW5pbCBtZWFucyBjb252ZXJ0IGtleXdvcmRzIHRvIHVwcGVyIGNhc2UuClRo aXMgaXMgZG9uZSB3aGVuIHR5cGVkIG9yIGV4cGFuZGVkIG9yIGJ5IHRoZSBmaXggY2FzZSBmdW5j dGlvbnMuHwooY3VzdG9tLWRlY2xhcmUtdmFyaWFibGUgJ3ZoZGwtdXBwZXItY2FzZS1rZXl3b3Jk cyAnbmlsICcoIyQgLiAtOTI5OSkgOnR5cGUgJ2Jvb2xlYW4gOnNldCAobGFtYmRhICh2YXJpYWJs ZSB2YWx1ZSkgKHZoZGwtY3VzdG9tLXNldCB2YXJpYWJsZSB2YWx1ZSAndmhkbC1hYmJyZXYtbGlz dC1pbml0KSkgOmdyb3VwICd2aGRsLXN0eWxlKQojQDExNSAqTm9uLW5pbCBtZWFucyBjb252ZXJ0 IHN0YW5kYXJkaXplZCB0eXBlcyB0byB1cHBlciBjYXNlLgpUaGlzIGlzIGRvbmUgd2hlbiBleHBh bmRlZCBvciBieSB0aGUgZml4IGNhc2UgZnVuY3Rpb25zLh8KKGN1c3RvbS1kZWNsYXJlLXZhcmlh YmxlICd2aGRsLXVwcGVyLWNhc2UtdHlwZXMgJ25pbCAnKCMkIC4gLTk2MTEpIDp0eXBlICdib29s ZWFuIDpzZXQgKGxhbWJkYSAodmFyaWFibGUgdmFsdWUpICh2aGRsLWN1c3RvbS1zZXQgdmFyaWFi bGUgdmFsdWUgJ3ZoZGwtYWJicmV2LWxpc3QtaW5pdCkpIDpncm91cCAndmhkbC1zdHlsZSkKI0Ax MjAgKk5vbi1uaWwgbWVhbnMgY29udmVydCBzdGFuZGFyZGl6ZWQgYXR0cmlidXRlcyB0byB1cHBl ciBjYXNlLgpUaGlzIGlzIGRvbmUgd2hlbiBleHBhbmRlZCBvciBieSB0aGUgZml4IGNhc2UgZnVu Y3Rpb25zLh8KKGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxlICd2aGRsLXVwcGVyLWNhc2UtYXR0cmli dXRlcyAnbmlsICcoIyQgLiAtOTkyMSkgOnR5cGUgJ2Jvb2xlYW4gOnNldCAobGFtYmRhICh2YXJp YWJsZSB2YWx1ZSkgKHZoZGwtY3VzdG9tLXNldCB2YXJpYWJsZSB2YWx1ZSAndmhkbC1hYmJyZXYt bGlzdC1pbml0KSkgOmdyb3VwICd2aGRsLXN0eWxlKQojQDEyOCAqTm9uLW5pbCBtZWFucyBjb252 ZXJ0IHN0YW5kYXJkaXplZCBlbnVtZXJhdGlvbiB2YWx1ZXMgdG8gdXBwZXIgY2FzZS4KVGhpcyBp cyBkb25lIHdoZW4gZXhwYW5kZWQgb3IgYnkgdGhlIGZpeCBjYXNlIGZ1bmN0aW9ucy4fCihjdXN0 b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC11cHBlci1jYXNlLWVudW0tdmFsdWVzICduaWwgJygj JCAuIC0xMDI0MSkgOnR5cGUgJ2Jvb2xlYW4gOnNldCAobGFtYmRhICh2YXJpYWJsZSB2YWx1ZSkg KHZoZGwtY3VzdG9tLXNldCB2YXJpYWJsZSB2YWx1ZSAndmhkbC1hYmJyZXYtbGlzdC1pbml0KSkg Omdyb3VwICd2aGRsLXN0eWxlKQojQDkwICpOb24tbmlsIG1lYW5zIGNvbnZlcnQgc3RhbmRhcmRp emVkIGNvbnN0YW50cyB0byB1cHBlciBjYXNlLgpUaGlzIGlzIGRvbmUgd2hlbiBleHBhbmRlZC4f CihjdXN0b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC11cHBlci1jYXNlLWNvbnN0YW50cyAndCAn KCMkIC4gLTEwNTcwKSA6dHlwZSAnYm9vbGVhbiA6c2V0IChsYW1iZGEgKHZhcmlhYmxlIHZhbHVl KSAodmhkbC1jdXN0b20tc2V0IHZhcmlhYmxlIHZhbHVlICd2aGRsLWFiYnJldi1saXN0LWluaXQp KSA6Z3JvdXAgJ3ZoZGwtc3R5bGUpCihjdXN0b20tZGVjbGFyZS1ncm91cCAndmhkbC1lbGVjdHJp YyBuaWwgIkN1c3RvbWl6YXRpb25zIGZvciBlbGVjdHJpZmljYXRpb24uIiA6Z3JvdXAgJ3ZoZGwp CiNAMTcwICpUeXBlIG9mIGtleXdvcmRzIGZvciB3aGljaCBlbGVjdHJpZmljYXRpb24gaXMgZW5h YmxlZC4KICBWSERMIGtleXdvcmRzOiBpbnZva2UgYnVpbHQtaW4gdGVtcGxhdGVzCiAgVXNlciBr ZXl3b3JkczogaW52b2tlIHVzZXIgbW9kZWxzIChzZWUgdmFyaWFibGUgYHZoZGwtbW9kZWwtYWxp c3QnKR8KKGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxlICd2aGRsLWVsZWN0cmljLWtleXdvcmRzICcn KHZoZGwgdXNlcikgJygjJCAuIC0xMDk1MSkgOnR5cGUgJyhzZXQgKGNvbnN0IDp0YWcgIlZIREwg a2V5d29yZHMiIHZoZGwpIChjb25zdCA6dGFnICJVc2VyIGtleXdvcmRzIiB1c2VyKSkgOnNldCAo bGFtYmRhICh2YXJpYWJsZSB2YWx1ZSkgKHZoZGwtY3VzdG9tLXNldCB2YXJpYWJsZSB2YWx1ZSAn dmhkbC1tb2RlLWFiYnJldi10YWJsZS1pbml0KSkgOmdyb3VwICd2aGRsLWVsZWN0cmljKQojQDI2 NyAqQ29uc3RydWN0cyBmb3Igd2hpY2ggbGFiZWxzIGFyZSB0byBiZSBxdWVyaWVkLgpUZW1wbGF0 ZSBnZW5lcmF0b3JzIHByb21wdCBmb3Igb3B0aW9uYWwgbGFiZWxzIGZvcjoKICBOb25lICAgICAg ICAgIDogbm8gY29uc3RydWN0cwogIFByb2Nlc3NlcyBvbmx5OiBwcm9jZXNzZXMgb25seSAoYWxz byBwcm9jZWR1cmFscyBpbiBWSERMLUFNUykKICBBbGwgY29uc3RydWN0czogYWxsIGNvbnN0cnVj dHMgd2l0aCBvcHRpb25hbCBsYWJlbHMgYW5kIGtleXdvcmQgRU5EHwooY3VzdG9tLWRlY2xhcmUt dmFyaWFibGUgJ3ZoZGwtb3B0aW9uYWwtbGFiZWxzICcncHJvY2VzcyAnKCMkIC4gLTExNDAyKSA6 dHlwZSAnKGNob2ljZSAoY29uc3QgOnRhZyAiTm9uZSIgbm9uZSkgKGNvbnN0IDp0YWcgIlByb2Nl c3NlcyBvbmx5IiBwcm9jZXNzKSAoY29uc3QgOnRhZyAiQWxsIGNvbnN0cnVjdHMiIGFsbCkpIDpn cm91cCAndmhkbC1lbGVjdHJpYykKI0AzNTEgKlNwZWNpZmllcyB3aGV0aGVyIHRvIGluc2VydCBl bXB0eSBsaW5lcyBpbiBzb21lIHRlbXBsYXRlcy4KVGhpcyBpbXByb3ZlcyByZWFkYWJpbGl0eSBv ZiBjb2RlLiAgRW1wdHkgbGluZXMgYXJlIGluc2VydGVkIGluOgogIE5vbmUgICAgICAgICAgICAg OiBubyBjb25zdHJ1Y3RzCiAgRGVzaWduIHVuaXRzIG9ubHk6IGVudGl0aWVzLCBhcmNoaXRlY3R1 cmVzLCBjb25maWd1cmF0aW9ucywgcGFja2FnZXMgb25seQogIEFsbCBjb25zdHJ1Y3RzICAgOiBh bHNvIGFsbCBjb25zdHJ1Y3RzIHdpdGggQkVHSU4uLi5FTkQgcGFydHMKClJlcGxhY2VzIHZhcmlh YmxlIGB2aGRsLWFkZGl0aW9uYWwtZW1wdHktbGluZXMnLh8KKGN1c3RvbS1kZWNsYXJlLXZhcmlh YmxlICd2aGRsLWluc2VydC1lbXB0eS1saW5lcyAnJ3VuaXQgJygjJCAuIC0xMTg4MykgOnR5cGUg JyhjaG9pY2UgKGNvbnN0IDp0YWcgIk5vbmUiIG5vbmUpIChjb25zdCA6dGFnICJEZXNpZ24gdW5p dHMgb25seSIgdW5pdCkgKGNvbnN0IDp0YWcgIkFsbCBjb25zdHJ1Y3RzIiBhbGwpKSA6Z3JvdXAg J3ZoZGwtZWxlY3RyaWMpCiNAMjg1ICpOb24tbmlsIG1lYW5zIGluZGVudCBhcmd1bWVudCBsaXN0 cyByZWxhdGl2ZSB0byBvcGVuaW5nIHBhcmVudGhlc2lzLgpUaGF0IGlzLCBhcmd1bWVudCwgYXNz b2NpYXRpb24sIGFuZCBwb3J0IGxpc3RzIHN0YXJ0IG9uIHRoZSBzYW1lIGxpbmUgYXMgdGhlCm9w ZW5pbmcgcGFyZW50aGVzaXMgYW5kIHN1YnNlcXVlbnQgbGluZXMgYXJlIGluZGVudGVkIGFjY29y ZGluZ2x5LgpPdGhlcndpc2UsIGxpc3RzIHN0YXJ0IG9uIGEgbmV3IGxpbmUgYW5kIGFyZSBpbmRl bnRlZCBhcyBub3JtYWwgY29kZS4fCihjdXN0b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC1hcmd1 bWVudC1saXN0LWluZGVudCAnbmlsICcoIyQgLiAtMTI0NDgpIDp0eXBlICdib29sZWFuIDpncm91 cCAndmhkbC1lbGVjdHJpYykKI0AxODIgKk5vbi1uaWwgbWVhbnMgd3JpdGUgYXNzb2NpYXRpb24g bGlzdHMgd2l0aCBmb3JtYWwgcGFyYW1ldGVycy4KSW4gdGVtcGxhdGVzLCB5b3UgYXJlIHByb21w dGVkIGZvciBmb3JtYWwgYW5kIGFjdHVhbCBwYXJhbWV0ZXJzLgpJZiBuaWwsIG9ubHkgYSBsaXN0 IG9mIGFjdHVhbCBwYXJhbWV0ZXJzIGlzIGVudGVyZWQuHwooY3VzdG9tLWRlY2xhcmUtdmFyaWFi bGUgJ3ZoZGwtYXNzb2NpYXRpb24tbGlzdC13aXRoLWZvcm1hbHMgJ3QgJygjJCAuIC0xMjg0OSkg OnR5cGUgJ2Jvb2xlYW4gOmdyb3VwICd2aGRsLWVsZWN0cmljKQojQDY0ICpOb24tbmlsIG1lYW5z IHBsYWNlIHBhcmVudGhlc2lzIGFyb3VuZCBjb25kaXRpb24gZXhwcmVzc2lvbnMuHwooY3VzdG9t LWRlY2xhcmUtdmFyaWFibGUgJ3ZoZGwtY29uZGl0aW9ucy1pbi1wYXJlbnRoZXNpcyAnbmlsICco IyQgLiAtMTMxNTMpIDp0eXBlICdib29sZWFuIDpncm91cCAndmhkbC1lbGVjdHJpYykKI0AzNCAq U3RyaW5nIHRvIHVzZSBmb3IgYSBsb2dpYyB6ZXJvLh8KKGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxl ICd2aGRsLXplcm8tc3RyaW5nICciJzAnIiAnKCMkIC4gLTEzMzM3KSA6dHlwZSAnc3RyaW5nIDpn cm91cCAndmhkbC1lbGVjdHJpYykKI0AzMyAqU3RyaW5nIHRvIHVzZSBmb3IgYSBsb2dpYyBvbmUu HwooY3VzdG9tLWRlY2xhcmUtdmFyaWFibGUgJ3ZoZGwtb25lLXN0cmluZyAnIicxJyIgJygjJCAu IC0xMzQ3OCkgOnR5cGUgJ3N0cmluZyA6Z3JvdXAgJ3ZoZGwtZWxlY3RyaWMpCihjdXN0b20tZGVj bGFyZS1ncm91cCAndmhkbC1oZWFkZXIgbmlsICJDdXN0b21pemF0aW9ucyBmb3IgZmlsZSBoZWFk ZXIuIiA6Z3JvdXAgJ3ZoZGwtZWxlY3RyaWMpCiNAMTIzNSAqU3RyaW5nIG9yIGZpbGUgdG8gaW5z ZXJ0IGFzIGZpbGUgaGVhZGVyLgpJZiB0aGUgc3RyaW5nIHNwZWNpZmllcyBhbiBleGlzdGluZyBm aWxlIG5hbWUsIHRoZSBjb250ZW50cyBvZiB0aGUgZmlsZSBpcwppbnNlcnRlZCwgb3RoZXJ3aXNl IHRoZSBzdHJpbmcgaXRzZWxmIGlzIGluc2VydGVkIGFzIGZpbGUgaGVhZGVyLgpUeXBlIGBDLWon IGZvciBuZXdsaW5lcy4KSWYgdGhlIGhlYWRlciBjb250YWlucyBSQ1Mga2V5d29yZHMsIHRoZXkg bWF5IGJlIHdyaXR0ZW4gYXMgPFJDUz5LZXl3b3JkPFJDUz4KaWYgdGhlIGhlYWRlciBuZWVkcyB0 byBiZSB2ZXJzaW9uIGNvbnRyb2xsZWQuCgpUaGUgZm9sbG93aW5nIGtleXdvcmRzIGZvciB0ZW1w bGF0ZSBnZW5lcmF0aW9uIGFyZSBzdXBwb3J0ZWQ6CiAgPGZpbGVuYW1lPiAgIDogcmVwbGFjZWQg YnkgdGhlIG5hbWUgb2YgdGhlIGJ1ZmZlcgogIDxhdXRob3I+ICAgICA6IHJlcGxhY2VkIGJ5IHRo ZSB1c2VyIG5hbWUgYW5kIGVtYWlsIGFkZHJlc3MgKGN1c3RvbWl6ZQogICAgICAgICAgICAgICAg IGBtYWlsLWhvc3QtYWRkcmVzcycgb3IgYHVzZXItbWFpbC1hZGRyZXNzJyBpZiByZXF1aXJlZCkK ICA8bG9naW4+ICAgICAgOiByZXBsYWNlZCBieSB1c2VyIGxvZ2luIG5hbWUKICA8Y29tcGFueT4g ICAgOiByZXBsYWNlZCBieSBjb250ZW50cyBvZiB2YXJpYWJsZSBgdmhkbC1jb21wYW55LW5hbWUn CiAgPGRhdGU+ICAgICAgIDogcmVwbGFjZWQgYnkgdGhlIGN1cnJlbnQgZGF0ZQogIDxwcm9qZWN0 PiAgICA6IHJlcGxhY2VkIGJ5IHRpdGxlIG9mIGN1cnJlbnQgcHJvamVjdCAoYHZoZGwtcHJvamVj dCcpCiAgPHByb2plY3RkZXNjPjogcmVwbGFjZWQgYnkgZGVzY3JpcHRpb24gb2YgY3VycmVudCBw cm9qZWN0IChgdmhkbC1wcm9qZWN0JykKICA8cGxhdGZvcm0+ICAgOiByZXBsYWNlZCBieSBjb250 ZW50cyBvZiB2YXJpYWJsZSBgdmhkbC1wbGF0Zm9ybS1zcGVjJwogIDwuLi4gc3RyaW5nPiA6IHJl cGxhY2VkIGJ5IGEgcXVlcmllZCBzdHJpbmcgKC4uLiBpcyB0aGUgcHJvbXB0IHdvcmQpCiAgPGN1 cnNvcj4gICAgIDogZmluYWwgY3Vyc29yIHBvc2l0aW9uCgpUaGUgKG11bHRpLWxpbmUpIHByb2pl Y3QgZGVzY3JpcHRpb24gPHByb2plY3RkZXNjPiBjYW4gYmUgdXNlZCBhcyBhIHByb2plY3QKZGVw ZW5kZW50IHBhcnQgb2YgdGhlIGZpbGUgaGVhZGVyIGFuZCBjYW4gYWxzbyBjb250YWluIHRoZSBh Ym92ZSBrZXl3b3Jkcy4fCihjdXN0b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC1maWxlLWhlYWRl ciAnIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi0tIFRpdGxlICAgICAgOiA8dGl0bGUgc3RyaW5n PlxuLS0gUHJvamVjdCAgICA6IDxwcm9qZWN0PlxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLS0g RmlsZSAgICAgICA6IDxmaWxlbmFtZT5cbi0tIEF1dGhvciAgICAgOiA8YXV0aG9yPlxuLS0gQ29t cGFueSAgICA6IDxjb21wYW55PlxuLS0gTGFzdCB1cGRhdGU6IDxkYXRlPlxuLS0gUGxhdGZvcm0g ICA6IDxwbGF0Zm9ybT5cbjxwcm9qZWN0ZGVzYz4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4tLSBE ZXNjcmlwdGlvbjogPGN1cnNvcj5cbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi0tIFJldmlzaW9u cyAgOlxuLS0gRGF0ZSAgICAgICAgVmVyc2lvbiAgQXV0aG9yICBEZXNjcmlwdGlvblxuLS0gPGRh dGU+ICAxLjAgICAgICA8bG9naW4+CUNyZWF0ZWRcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxu IiAnKCMkIC4gLTEzNzE1KSA6dHlwZSAnc3RyaW5nIDpncm91cCAndmhkbC1oZWFkZXIpCiNAMjM5 ICpTdHJpbmcgb3IgZmlsZSB0byBpbnNlcnQgYXMgZmlsZSBmb290ZXIuCklmIHRoZSBzdHJpbmcg c3BlY2lmaWVzIGFuIGV4aXN0aW5nIGZpbGUgbmFtZSwgdGhlIGNvbnRlbnRzIG9mIHRoZSBmaWxl IGlzCmluc2VydGVkLCBvdGhlcndpc2UgdGhlIHN0cmluZyBpdHNlbGYgaXMgaW5zZXJ0ZWQgYXMg ZmlsZSBmb290ZXIgKGkuZS4gYXQKdGhlIGVuZCBvZiB0aGUgZmlsZSkuClR5cGUgYEMtaicgZm9y IG5ld2xpbmVzLh8KKGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxlICd2aGRsLWZpbGUtZm9vdGVyICci IiAnKCMkIC4gLTE1NzkwKSA6dHlwZSAnc3RyaW5nIDpncm91cCAndmhkbC1oZWFkZXIpCiNANDQg Kk5hbWUgb2YgY29tcGFueSB0byBpbnNlcnQgaW4gZmlsZSBoZWFkZXIuHwooY3VzdG9tLWRlY2xh cmUtdmFyaWFibGUgJ3ZoZGwtY29tcGFueS1uYW1lICciIiAnKCMkIC4gLTE2MTMxKSA6dHlwZSAn c3RyaW5nIDpncm91cCAndmhkbC1oZWFkZXIpCiNAMTY0ICpTcGVjaWZpY2F0aW9uIG9mIFZIREwg cGxhdGZvcm0gdG8gaW5zZXJ0IGluIGZpbGUgaGVhZGVyLgpUaGUgcGxhdGZvcm0gc3BlY2lmaWNh dGlvbiBzaG91bGQgY29udGFpbiBuYW1lcyBhbmQgdmVyc2lvbnMgb2YgdGhlCnNpbXVsYXRpb24g YW5kIHN5bnRoZXNpcyB0b29scyB1c2VkLh8KKGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxlICd2aGRs LXBsYXRmb3JtLXNwZWMgJyIiICcoIyQgLiAtMTYyNzkpIDp0eXBlICdzdHJpbmcgOmdyb3VwICd2 aGRsLWhlYWRlcikKI0AyNTAgKlNwZWNpZmllcyB0aGUgZGF0ZSBmb3JtYXQgdG8gdXNlIGluIHRo ZSBoZWFkZXIuClRoaXMgc3RyaW5nIGlzIHBhc3NlZCBhcyBhcmd1bWVudCB0byB0aGUgY29tbWFu ZCBgZm9ybWF0LXRpbWUtc3RyaW5nJy4KRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gZm9ybWF0IHN0 cmluZ3MsIHNlZSB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgdGhlCmBmb3JtYXQtdGltZS1zdHJpbmcn IGNvbW1hbmQgKEMtaCBmIGBmb3JtYXQtdGltZS1zdHJpbmcnKS4fCihjdXN0b20tZGVjbGFyZS12 YXJpYWJsZSAndmhkbC1kYXRlLWZvcm1hdCAnIiVZLyVtLyVkIiAnKCMkIC4gLTE2NTQ4KSA6dHlw ZSAnc3RyaW5nIDpncm91cCAndmhkbC1oZWFkZXIpCiNAMjI0ICpQcmVmaXggc3RyaW5nIG9mIG1v ZGlmaWNhdGlvbiBkYXRlIGluIFZIREwgZmlsZSBoZWFkZXIuCklmIGFjdHVhbGl6YXRpb24gb2Yg dGhlIG1vZGlmaWNhdGlvbiBkYXRlIGlzIGNhbGxlZCAobWVudSwKYFxbdmhkbC10ZW1wbGF0ZS1t b2RpZnldJyksIHRoaXMgc3RyaW5nIGlzIHNlYXJjaGVkIGFuZCB0aGUgcmVzdApvZiB0aGUgbGlu ZSByZXBsYWNlZCBieSB0aGUgY3VycmVudCBkYXRlLh8KKGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxl ICd2aGRsLW1vZGlmeS1kYXRlLXByZWZpeC1zdHJpbmcgJyItLSBMYXN0IHVwZGF0ZTogIiAnKCMk IC4gLTE2OTA5KSA6dHlwZSAnc3RyaW5nIDpncm91cCAndmhkbC1oZWFkZXIpCiNAMjIwICpOb24t bmlsIG1lYW5zIHVwZGF0ZSB0aGUgbW9kaWZpY2F0aW9uIGRhdGUgd2hlbiB0aGUgYnVmZmVyIGlz IHNhdmVkLgpDYWxscyBmdW5jdGlvbiBgXFt2aGRsLXRlbXBsYXRlLW1vZGlmeV0nKS4KCk5PVEU6 IEFjdGl2YXRlIHRoZSBuZXcgc2V0dGluZyBpbiBhIFZIREwgYnVmZmVyIHVzaW5nIHRoZSBtZW51 IGVudHJ5CiAgICAgICJBY3RpdmF0ZSBOZXcgQ3VzdG9taXphdGlvbnMiHwooY3VzdG9tLWRlY2xh cmUtdmFyaWFibGUgJ3ZoZGwtbW9kaWZ5LWRhdGUtb24tc2F2aW5nICd0ICcoIyQgLiAtMTcyNjYp IDp0eXBlICdib29sZWFuIDpncm91cCAndmhkbC1oZWFkZXIpCihjdXN0b20tZGVjbGFyZS1ncm91 cCAndmhkbC1zZXF1ZW50aWFsLXByb2Nlc3MgbmlsICJDdXN0b21pemF0aW9ucyBmb3Igc2VxdWVu dGlhbCBwcm9jZXNzZXMuIiA6Z3JvdXAgJ3ZoZGwtZWxlY3RyaWMpCiNANjQgKlNwZWNpZmllcyB3 aGljaCBraW5kIG9mIHJlc2V0IHRvIHVzZSBpbiBzZXF1ZW50aWFsIHByb2Nlc3Nlcy4fCihjdXN0 b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC1yZXNldC1raW5kICcnYXN5bmMgJygjJCAuIC0xNzcx NSkgOnR5cGUgJyhjaG9pY2UgKGNvbnN0IDp0YWcgIk5vbmUiIG5vbmUpIChjb25zdCA6dGFnICJT eW5jaHJvbm91cyIgc3luYykgKGNvbnN0IDp0YWcgIkFzeW5jaHJvbm91cyIgYXN5bmMpKSA6Z3Jv dXAgJ3ZoZGwtc2VxdWVudGlhbC1wcm9jZXNzKQojQDg0ICpOb24tbmlsIG1lYW5zIHJlc2V0IGlu IHNlcXVlbnRpYWwgcHJvY2Vzc2VzIGlzIGFjdGl2ZSBoaWdoLgpOaWwgbWVhbnMgYWN0aXZlIGxv dy4fCihjdXN0b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC1yZXNldC1hY3RpdmUtaGlnaCAnbmls ICcoIyQgLiAtMTc5ODkpIDp0eXBlICdib29sZWFuIDpncm91cCAndmhkbC1zZXF1ZW50aWFsLXBy b2Nlc3MpCiNAOTIgKk5vbi1uaWwgbWVhbnMgcmlzaW5nIGVkZ2Ugb2YgY2xvY2sgdHJpZ2dlcnMg c2VxdWVudGlhbCBwcm9jZXNzZXMuCk5pbCBtZWFucyBmYWxsaW5nIGVkZ2UuHwooY3VzdG9tLWRl Y2xhcmUtdmFyaWFibGUgJ3ZoZGwtY2xvY2stcmlzaW5nLWVkZ2UgJ3QgJygjJCAuIC0xODE5NSkg OnR5cGUgJ2Jvb2xlYW4gOmdyb3VwICd2aGRsLXNlcXVlbnRpYWwtcHJvY2VzcykKI0AxMDcgKlN5 bnRheCBvZiB0aGUgY2xvY2sgZWRnZSBjb25kaXRpb24uCiAgU3RhbmRhcmQ6ICJjbGsnZXZlbnQg YW5kIGNsayA9ICcxJyIKICBGdW5jdGlvbjogInJpc2luZ19lZGdlKGNsaykiHwooY3VzdG9tLWRl Y2xhcmUtdmFyaWFibGUgJ3ZoZGwtY2xvY2stZWRnZS1jb25kaXRpb24gJydzdGFuZGFyZCAnKCMk IC4gLTE4NDA4KSA6dHlwZSAnKGNob2ljZSAoY29uc3QgOnRhZyAiU3RhbmRhcmQiIHN0YW5kYXJk KSAoY29uc3QgOnRhZyAiRnVuY3Rpb24iIGZ1bmN0aW9uKSkgOmdyb3VwICd2aGRsLXNlcXVlbnRp YWwtcHJvY2VzcykKI0A0NCAqTmFtZSBvZiBjbG9jayBzaWduYWwgdG8gdXNlIGluIHRlbXBsYXRl cy4fCihjdXN0b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC1jbG9jay1uYW1lICciIiAnKCMkIC4g LTE4NzEzKSA6dHlwZSAnc3RyaW5nIDpncm91cCAndmhkbC1zZXF1ZW50aWFsLXByb2Nlc3MpCiNA NDQgKk5hbWUgb2YgcmVzZXQgc2lnbmFsIHRvIHVzZSBpbiB0ZW1wbGF0ZXMuHwooY3VzdG9tLWRl Y2xhcmUtdmFyaWFibGUgJ3ZoZGwtcmVzZXQtbmFtZSAnIiIgJygjJCAuIC0xODg3MCkgOnR5cGUg J3N0cmluZyA6Z3JvdXAgJ3ZoZGwtc2VxdWVudGlhbC1wcm9jZXNzKQooY3VzdG9tLWRlY2xhcmUt Z3JvdXAgJ3ZoZGwtbW9kZWwgbmlsICJDdXN0b21pemF0aW9ucyBmb3IgdXNlciBtb2RlbHMuIiA6 Z3JvdXAgJ3ZoZGwpCiNAMTI3MSAqTGlzdCBvZiB1c2VyIG1vZGVscy4KVkhETCBtb2RlbHMgKHRl bXBsYXRlcykgY2FuIGJlIHNwZWNpZmllZCBieSB0aGUgdXNlciBpbiB0aGlzIGxpc3QuICBUaGV5 IGNhbiBiZQppbnZva2VkIGZyb20gdGhlIG1lbnUsIHRocm91Z2gga2V5IGJpbmRpbmdzIChgQy1j IEMtbSAuLi4nKSwgb3IgYnkga2V5d29yZAplbGVjdHJpZmljYXRpb24gKGkuZS4gb3ZlcnJpZGlu ZyBleGlzdGluZyBvciBjcmVhdGluZyBuZXcga2V5d29yZHMsIHNlZQp2YXJpYWJsZSBgdmhkbC1l bGVjdHJpYy1rZXl3b3JkcycpLgogIE5hbWUgICAgICAgOiBuYW1lIG9mIG1vZGVsIChzdHJpbmcg b2Ygd29yZHMgYW5kIHNwYWNlcykKICBTdHJpbmcgICAgIDogc3RyaW5nIG9yIG5hbWUgb2YgZmls ZSB0byBiZSBpbnNlcnRlZCBhcyBtb2RlbCAobmV3bGluZTogYEMtaicpCiAgS2V5IEJpbmRpbmc6 IGtleSBiaW5kaW5nIHRvIGludm9rZSBtb2RlbCwgYWRkZWQgdG8gcHJlZml4IGBDLWMgQy1tJwog ICAgICAgICAgICAgICAgKG11c3QgYmUgaW4gZG91YmxlLXF1b3RlcywgZXhhbXBsZXM6ICJpIiwg IlxDLXAiLCAiXE0tcyIpCiAgS2V5d29yZCAgICA6IGtleXdvcmQgdG8gaW52b2tlIG1vZGVsCgpU aGUgbW9kZWxzIGNhbiBjb250YWluIHByb21wdHMgdG8gYmUgcXVlcmllZC4gIEEgcHJvbXB0IGlz IG9mIHRoZSBmb3JtICI8Li4uPiIuCkEgcHJvbXB0IHRoYXQgYXBwZWFycyBzZXZlcmFsIHRpbWVz IGlzIHF1ZXJpZWQgb25jZSBhbmQgcmVwbGFjZWQgdGhyb3VnaG91dAp0aGUgbW9kZWwuICBTcGVj aWFsIHByb21wdHMgYXJlOgogIDxjbG9jaz4gOiBuYW1lIHNwZWNpZmllZCBpbiBgdmhkbC1jbG9j ay1uYW1lJyAoaWYgbm90IGVtcHR5KQogIDxyZXNldD4gOiBuYW1lIHNwZWNpZmllZCBpbiBgdmhk bC1yZXNldC1uYW1lJyAoaWYgbm90IGVtcHR5KQogIDxjdXJzb3I+OiBmaW5hbCBjdXJzb3IgcG9z aXRpb24KCklmIHRoZSBzdHJpbmcgc3BlY2lmaWVzIGFuIGV4aXN0aW5nIGZpbGUgbmFtZSwgdGhl IGNvbnRlbnRzIG9mIHRoZSBmaWxlIGlzCmluc2VydGVkLCBvdGhlcndpc2UgdGhlIHN0cmluZyBp dHNlbGYgaXMgaW5zZXJ0ZWQuClRoZSBjb2RlIHdpdGhpbiB0aGUgbW9kZWxzIHNob3VsZCBiZSBj b3JyZWN0bHkgaW5kZW50ZWQuClR5cGUgYEMtaicgZm9yIG5ld2xpbmVzLgoKTk9URTogQWN0aXZh dGUgdGhlIG5ldyBzZXR0aW5nIGluIGEgVkhETCBidWZmZXIgdXNpbmcgdGhlIG1lbnUgZW50cnkK ICAgICAgIkFjdGl2YXRlIE5ldyBDdXN0b21pemF0aW9ucyIfCihjdXN0b20tZGVjbGFyZS12YXJp YWJsZSAndmhkbC1tb2RlbC1hbGlzdCAnJygoImV4YW1wbGUgbW9kZWwiICI8bGFiZWw+IDogcHJv Y2VzcyAoPGNsb2NrPiwgPHJlc2V0PilcbmJlZ2luICAtLSBwcm9jZXNzIDxsYWJlbD5cbiAgaWYg PHJlc2V0PiA9ICcwJyB0aGVuICAtLSBhc3luY2hyb25vdXMgcmVzZXQgKGFjdGl2ZSBsb3cpXG4g ICAgPGN1cnNvcj5cbiAgZWxzaWYgPGNsb2NrPidldmVudCBhbmQgPGNsb2NrPiA9ICcxJyB0aGVu ICAtLSByaXNpbmcgY2xvY2sgZWRnZVxuICAgIGlmIDxlbmFibGU+ID0gJzEnIHRoZW4gIC0tIHN5 bmNocm9ub3VzIGxvYWRcbiAgICAgIFxuICAgIGVuZCBpZjtcbiAgZW5kIGlmO1xuZW5kIHByb2Nl c3MgPGxhYmVsPjsiICJlIiAiIikpICcoIyQgLiAtMTkxMTUpIDp0eXBlICcocmVwZWF0IChsaXN0 IDp0YWcgIk1vZGVsIiA6aW5kZW50IDIgKHN0cmluZyA6dGFnICJOYW1lICAgICAgICIpIChzdHJp bmcgOnRhZyAiU3RyaW5nICAgICA6ICh0eXBlIGBDLWonIGZvciBuZXdsaW5lKSIgOmZvcm1hdCAi JXRcbiV2IikgKHNleHAgOnRhZyAiS2V5IEJpbmRpbmciIHgpIChzdHJpbmcgOnRhZyAiS2V5d29y ZCAgICAiKSkpIDpzZXQgKGxhbWJkYSAodmFyaWFibGUgdmFsdWUpICh2aGRsLWN1c3RvbS1zZXQg dmFyaWFibGUgdmFsdWUgJ3ZoZGwtbW9kZWwtbWFwLWluaXQgJ3ZoZGwtbW9kZWwtZGVmdW4gJ3Zo ZGwtbW9kZS1hYmJyZXYtdGFibGUtaW5pdCAndmhkbC11cGRhdGUtbW9kZS1tZW51KSkgOmdyb3Vw ICd2aGRsLW1vZGVsKQooY3VzdG9tLWRlY2xhcmUtZ3JvdXAgJ3ZoZGwtcG9ydCBuaWwgIkN1c3Rv bWl6YXRpb25zIGZvciBwb3J0IHRyYW5zZm9ybWF0aW9uIGZ1bmN0aW9ucy4iIDpncm91cCAndmhk bCkKI0A2MSAqTm9uLW5pbCBtZWFucyBpbmNsdWRlIHBvcnQgY29tbWVudHMgd2hlbiBhIHBvcnQg aXMgcGFzdGVkLh8KKGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxlICd2aGRsLWluY2x1ZGUtcG9ydC1j b21tZW50cyAnbmlsICcoIyQgLiAtMjEyNjkpIDp0eXBlICdib29sZWFuIDpncm91cCAndmhkbC1w b3J0KQojQDcyICpOb24tbmlsIG1lYW5zIGluY2x1ZGUgc2lnbmFsIGRpcmVjdGlvbiBpbiBpbnN0 YW50aWF0aW9ucyBhcyBjb21tZW50cy4fCihjdXN0b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC1p bmNsdWRlLWRpcmVjdGlvbi1jb21tZW50cyAnbmlsICcoIyQgLiAtMjE0NDIpIDp0eXBlICdib29s ZWFuIDpncm91cCAndmhkbC1wb3J0KQooYnl0ZS1jb2RlICJcMzAyEFwzMDAJQhFcMzAwXDIwNyIg W3ZoZGwtbmFtZS1kb2Mtc3RyaW5nIGN1cnJlbnQtbG9hZC1saXN0ICJcblxuRlJPTSBSRUdFWFAg aXMgYSByZWd1bGFyIGV4cHJlc3Npb24gbWF0Y2hpbmcgdGhlIGZvcm1hbCBwb3J0IG5hbWU6XG4g IGAuKicgICAgICAgbWF0Y2hlcyB0aGUgZW50aXJlIG5hbWVcbiAgYFxcKC4uLlxcKScgIG1hdGNo ZXMgYSBzdWJzdHJpbmdcblRPIFNUUklORyBzcGVjaWZpZXMgdGhlIHN0cmluZyB0byBiZSBpbnNl cnRlZCBhcyBhY3R1YWwgcG9ydCBuYW1lOlxuICBgXFwmJyAgbWVhbnMgc3Vic3RpdHV0ZSBvcmln aW5hbCBtYXRjaGVkIHRleHRcbiAgYFxcTicgIG1lYW5zIHN1YnN0aXR1dGUgd2hhdCBtYXRjaGVk IHRoZSBOdGggYFxcKC4uLlxcKSdcbkV4YW1wbGVzOlxuICBgLionICAgICAgICAgICBgXFwmJyAg ICBsZWF2ZXMgbmFtZSBhcyBpdCBpc1xuICBgLionICAgICAgICAgICBgXFwmX2knICBhdHRhY2hl cyBgX2knIHRvIG9yaWdpbmFsIG5hbWVcbiAgYFxcKC4qXFwpX1tpb10kJyBgXFwxJyAgICBzdHJp cHMgb2ZmIGBfaScgb3IgYF9vJyBmcm9tIG9yaWdpbmFsIG5hbWVcbiAgYC4qJyAgICAgICAgICAg YCcgICAgICBsZWF2ZXMgbmFtZSBlbXB0eSJdIDIpCihjdXN0b20tZGVjbGFyZS12YXJpYWJsZSAn dmhkbC1hY3R1YWwtcG9ydC1uYW1lICcnKCIuKiIgLiAiXFwmX2kiKSAoY29uY2F0ICIqU3BlY2lm aWVzIGhvdyBhY3R1YWwgcG9ydCBuYW1lcyBhcmUgb2J0YWluZWQgZnJvbSBmb3JtYWwgcG9ydCBu YW1lcy5cbkluIGEgY29tcG9uZW50IGluc3RhbnRpYXRpb24sIGFuIGFjdHVhbCBwb3J0IG5hbWUg Y2FuIGJlIG9idGFpbmVkIGJ5XG5tb2RpZnlpbmcgdGhlIGZvcm1hbCBwb3J0IG5hbWUgKGUuZy4g YXR0YWNoaW5nIG9yIHN0cmlwcGluZyBvZmYgYSBzdWJzdHJpbmcpLiIgdmhkbC1uYW1lLWRvYy1z dHJpbmcpIDp0eXBlICcoY29ucyAocmVnZXhwIDp0YWcgIkZyb20gUmVnZXhwIikgKHN0cmluZyA6 dGFnICJUbyBTdHJpbmcgICIpKSA6Z3JvdXAgJ3ZoZGwtcG9ydCkKKGN1c3RvbS1kZWNsYXJlLXZh cmlhYmxlICd2aGRsLWluc3RhbmNlLW5hbWUgJycoIi4qIiAuICIiKSAoY29uY2F0ICIqU3BlY2lm aWVzIGhvdyBhbiBpbnN0YW5jZSBuYW1lIGlzIG9idGFpbmVkLlxuVGhlIGluc3RhbmNlIG5hbWUg Y2FuIGJlIG9idGFpbmVkIGJ5IG1vZGlmeWluZyB0aGUgbmFtZSBvZiB0aGUgY29tcG9uZW50IHRv IGJlXG5pbnN0YW50aWF0ZWQgKGUuZy4gYXR0YWNoaW5nIG9yIHN0cmlwcGluZyBvZmYgYSBzdWJz dHJpbmcpLlxuSWYgVE8gU1RSSU5HIGlzIGVtcHR5LCB0aGUgaW5zdGFuY2UgbmFtZSBpcyBxdWVy aWVkLiIgdmhkbC1uYW1lLWRvYy1zdHJpbmcpIDp0eXBlICcoY29ucyAocmVnZXhwIDp0YWcgIkZy b20gUmVnZXhwIikgKHN0cmluZyA6dGFnICJUbyBTdHJpbmcgICIpKSA6Z3JvdXAgJ3ZoZGwtcG9y dCkKKGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxlICd2aGRsLXRlc3RiZW5jaC1lbnRpdHktbmFtZSAn JygiLioiIC4gIlxcJl90YiIpIChjb25jYXQgIipTcGVjaWZpZXMgaG93IHRoZSB0ZXN0IGJlbmNo IGVudGl0eSBuYW1lIGlzIG9idGFpbmVkLlxuVGhlIGVudGl0eSBuYW1lIG9mIGEgdGVzdCBiZW5j aCBjYW4gYmUgb2J0YWluZWQgYnkgbW9kaWZ5aW5nIHRoZSBuYW1lIG9mXG50aGUgY29tcG9uZW50 IHRvIGJlIHRlc3RlZCAoZS5nLiBhdHRhY2hpbmcgb3Igc3RyaXBwaW5nIG9mZiBhIHN1YnN0cmlu ZykuIiB2aGRsLW5hbWUtZG9jLXN0cmluZykgOnR5cGUgJyhjb25zIChyZWdleHAgOnRhZyAiRnJv bSBSZWdleHAiKSAoc3RyaW5nIDp0YWcgIlRvIFN0cmluZyAgIikpIDpncm91cCAndmhkbC1wb3J0 KQooY3VzdG9tLWRlY2xhcmUtdmFyaWFibGUgJ3ZoZGwtdGVzdGJlbmNoLWFyY2hpdGVjdHVyZS1u YW1lICcnKCIuKiIgLiAiIikgKGNvbmNhdCAiKlNwZWNpZmllcyBob3cgdGhlIHRlc3QgYmVuY2gg YXJjaGl0ZWN0dXJlIG5hbWUgaXMgb2J0YWluZWQuXG5UaGUgdGVzdCBiZW5jaCBhcmNoaXRlY3R1 cmUgbmFtZSBjYW4gYmUgb2J0YWluZWQgYnkgbW9kaWZ5aW5nIHRoZSBuYW1lIG9mXG50aGUgY29t cG9uZW50IHRvIGJlIHRlc3RlZCAoZS5nLiBhdHRhY2hpbmcgb3Igc3RyaXBwaW5nIG9mZiBhIHN1 YnN0cmluZykuXG5JZiBUTyBTVFJJTkcgaXMgZW1wdHksIHRoZSBhcmNoaXRlY3R1cmUgbmFtZSBp cyBxdWVyaWVkLiIgdmhkbC1uYW1lLWRvYy1zdHJpbmcpIDp0eXBlICcoY29ucyAocmVnZXhwIDp0 YWcgIkZyb20gUmVnZXhwIikgKHN0cmluZyA6dGFnICJUbyBTdHJpbmcgICIpKSA6Z3JvdXAgJ3Zo ZGwtcG9ydCkKKGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxlICd2aGRsLXRlc3RiZW5jaC1kdXQtbmFt ZSAnJygiLioiIC4gIkRVVCIpIChjb25jYXQgIipTcGVjaWZpZXMgaG93IGEgRFVUIGluc3RhbmNl IG5hbWUgaXMgb2J0YWluZWQuXG5UaGUgZGVzaWduLXVuZGVyLXRlc3QgaW5zdGFuY2UgbmFtZSAo aS5lLiB0aGUgY29tcG9uZW50IGluc3RhbnRpYXRlZCBpbiB0aGVcbnRlc3QgYmVuY2gpIGNhbiBi ZSBvYnRhaW5lZCBieSBtb2RpZnlpbmcgdGhlIGNvbXBvbmVudCBuYW1lIChlLmcuIGF0dGFjaGlu Z1xub3Igc3RyaXBwaW5nIG9mZiBhIHN1YnN0cmluZykuIiB2aGRsLW5hbWUtZG9jLXN0cmluZykg OnR5cGUgJyhjb25zIChyZWdleHAgOnRhZyAiRnJvbSBSZWdleHAiKSAoc3RyaW5nIDp0YWcgIlRv IFN0cmluZyAgIikpIDpncm91cCAndmhkbC1wb3J0KQojQDI2MyAqU3RyaW5nIG9yIGZpbGUgdG8g YmUgaW5zZXJ0ZWQgYXMgdGVzdCBiZW5jaCBlbnRpdHkgaGVhZGVyLgpJZiB0aGUgc3RyaW5nIHNw ZWNpZmllcyBhbiBleGlzdGluZyBmaWxlIG5hbWUsIHRoZSBjb250ZW50cyBvZiB0aGUgZmlsZSBp cwppbnNlcnRlZCwgb3RoZXJ3aXNlIHRoZSBzdHJpbmcgaXRzZWxmIGlzIGluc2VydGVkIGF0IHRo ZSBiZWdpbm5pbmcgb2YgdGhlIHRlc3QKYmVuY2ggZW50aXR5IHRlbXBsYXRlLgpUeXBlIGBDLWon IGZvciBuZXdsaW5lcy4fCihjdXN0b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC10ZXN0YmVuY2gt ZW50aXR5LWhlYWRlciAnIiIgJygjJCAuIC0yNDM3NykgOnR5cGUgJ3N0cmluZyA6Z3JvdXAgJ3Zo ZGwtcG9ydCkKI0AzMjcgKlN0cmluZyBvciBmaWxlIHRvIGJlIGluc2VydGVkIGFzIHRlc3QgYmVu Y2ggYXJjaGl0ZWN0dXJlIGhlYWRlci4KSWYgdGhlIHN0cmluZyBzcGVjaWZpZXMgYW4gZXhpc3Rp bmcgZmlsZSBuYW1lLCB0aGUgY29udGVudHMgb2YgdGhlIGZpbGUgaXMKaW5zZXJ0ZWQsIG90aGVy d2lzZSB0aGUgc3RyaW5nIGl0c2VsZiBpcyBpbnNlcnRlZCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRo ZSB0ZXN0CmJlbmNoIGFyY2hpdGVjdHVyZSB0ZW1wbGF0ZSwgaWYgYSBzZXBhcmF0ZSBmaWxlIGlz IGNyZWF0ZWQgZm9yIHRoZQphcmNoaXRlY3R1cmUuClR5cGUgYEMtaicgZm9yIG5ld2xpbmVzLh8K KGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxlICd2aGRsLXRlc3RiZW5jaC1hcmNoaXRlY3R1cmUtaGVh ZGVyICciIiAnKCMkIC4gLTI0NzUzKSA6dHlwZSAnc3RyaW5nIDpncm91cCAndmhkbC1wb3J0KQoj QDI3NSAqU3RyaW5nIG9yIGZpbGUgdG8gYmUgaW5zZXJ0ZWQgaW4gdGhlIHRlc3QgYmVuY2ggZGVj bGFyYXRpdmUgcGFydC4KSWYgdGhlIHN0cmluZyBzcGVjaWZpZXMgYW4gZXhpc3RpbmcgZmlsZSBu YW1lLCB0aGUgY29udGVudHMgb2YgdGhlIGZpbGUgaXMKaW5zZXJ0ZWQsIG90aGVyd2lzZSB0aGUg c3RyaW5nIGl0c2VsZiBpcyBpbnNlcnRlZCBpbiB0aGUgdGVzdCBiZW5jaAphcmNoaXRlY3R1cmUg YmVmb3JlIHRoZSBCRUdJTiBrZXl3b3JkLgpUeXBlIGBDLWonIGZvciBuZXdsaW5lcy4fCihjdXN0 b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC10ZXN0YmVuY2gtZGVjbGFyYXRpb25zICciIiAnKCMk IC4gLTI1MTk5KSA6dHlwZSAnc3RyaW5nIDpncm91cCAndmhkbC1wb3J0KQojQDI3MSAqU3RyaW5n IG9yIGZpbGUgdG8gYmUgaW5zZXJ0ZWQgaW4gdGhlIHRlc3QgYmVuY2ggc3RhdGVtZW50IHBhcnQu CklmIHRoZSBzdHJpbmcgc3BlY2lmaWVzIGFuIGV4aXN0aW5nIGZpbGUgbmFtZSwgdGhlIGNvbnRl bnRzIG9mIHRoZSBmaWxlIGlzCmluc2VydGVkLCBvdGhlcndpc2UgdGhlIHN0cmluZyBpdHNlbGYg aXMgaW5zZXJ0ZWQgaW4gdGhlIHRlc3QgYmVuY2gKYXJjaGl0ZWN0dXJlIGJlZm9yZSB0aGUgRU5E IGtleXdvcmQuClR5cGUgYEMtaicgZm9yIG5ld2xpbmVzLh8KKGN1c3RvbS1kZWNsYXJlLXZhcmlh YmxlICd2aGRsLXRlc3RiZW5jaC1zdGF0ZW1lbnRzICciIiAnKCMkIC4gLTI1NTg2KSA6dHlwZSAn c3RyaW5nIDpncm91cCAndmhkbC1wb3J0KQojQDczICpOb24tbmlsIG1lYW5zIGluaXRpYWxpemUg c2lnbmFscyB3aXRoIGAwJyB3aGVuIGRlY2xhcmVkIGluIHRlc3QgYmVuY2guHwooY3VzdG9tLWRl Y2xhcmUtdmFyaWFibGUgJ3ZoZGwtdGVzdGJlbmNoLWluaXRpYWxpemUtc2lnbmFscyAnbmlsICco IyQgLiAtMjU5NjYpIDp0eXBlICdib29sZWFuIDpncm91cCAndmhkbC1wb3J0KQojQDI5OSAqU3Bl Y2lmaWVzIHdoZXRoZXIgbmV3IGZpbGVzIHNob3VsZCBiZSBjcmVhdGVkIGZvciB0aGUgdGVzdCBi ZW5jaC4KVGVzdCBiZW5jaCBlbnRpdHkgYW5kIGFyY2hpdGVjdHVyZSBhcmUgaW5zZXJ0ZWQ6CiAg Tm9uZSAgICAgICAgICA6IGluIGN1cnJlbnQgYnVmZmVyCiAgU2luZ2xlIGZpbGUgICA6IGluIG5l dyBzaW5nbGUgZmlsZQogIFNlcGFyYXRlIGZpbGVzOiBpbiB0d28gc2VwYXJhdGUgZmlsZXMKTm90 ZSB0aGF0IHRoZSBmaWxlcyBoYXZlIHRoZSBzYW1lIG5hbWUgYXMgdGhlIGNvbnRhaW5lZCBkZXNp Z24gdW5pdC4fCihjdXN0b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC10ZXN0YmVuY2gtY3JlYXRl LWZpbGVzICcnc2luZ2xlICcoIyQgLiAtMjYxNTkpIDp0eXBlICcoY2hvaWNlIChjb25zdCA6dGFn ICJOb25lIiBub25lKSAoY29uc3QgOnRhZyAiU2luZ2xlIGZpbGUiIHNpbmdsZSkgKGNvbnN0IDp0 YWcgIlNlcGFyYXRlIGZpbGVzIiBzZXBhcmF0ZSkpIDpncm91cCAndmhkbC1wb3J0KQooY3VzdG9t LWRlY2xhcmUtZ3JvdXAgJ3ZoZGwtY29tbWVudCBuaWwgIkN1c3RvbWl6YXRpb25zIGZvciBjb21t ZW50cy4iIDpncm91cCAndmhkbCkKI0A3MCAqTm9uLW5pbCBtZWFucyB2YXJpb3VzIHRlbXBsYXRl cyBhdXRvbWF0aWNhbGx5IGluc2VydCBoZWxwIGNvbW1lbnRzLh8KKGN1c3RvbS1kZWNsYXJlLXZh cmlhYmxlICd2aGRsLXNlbGYtaW5zZXJ0LWNvbW1lbnRzICd0ICcoIyQgLiAtMjY3NTkpIDp0eXBl ICdib29sZWFuIDpncm91cCAndmhkbC1jb21tZW50KQojQDcwICpOb24tbmlsIG1lYW5zIHZhcmlv dXMgdGVtcGxhdGVzIHByb21wdCBmb3IgdXNlciBkZWZpbmFibGUgY29tbWVudHMuHwooY3VzdG9t LWRlY2xhcmUtdmFyaWFibGUgJ3ZoZGwtcHJvbXB0LWZvci1jb21tZW50cyAndCAnKCMkIC4gLTI2 OTQxKSA6dHlwZSAnYm9vbGVhbiA6Z3JvdXAgJ3ZoZGwtY29tbWVudCkKI0AxODggKkNvbHVtbiB0 byBpbmRlbnQgaW5saW5lIGNvbW1lbnRzIHRvLgpPdmVycmlkZXMgbG9jYWwgdmFyaWFibGUgYGNv bW1lbnQtY29sdW1uJy4KCk5PVEU6IEFjdGl2YXRlIHRoZSBuZXcgc2V0dGluZyBpbiBhIFZIREwg YnVmZmVyIHVzaW5nIHRoZSBtZW51IGVudHJ5CiAgICAgICJBY3RpdmF0ZSBOZXcgQ3VzdG9taXph dGlvbnMiHwooY3VzdG9tLWRlY2xhcmUtdmFyaWFibGUgJ3ZoZGwtaW5saW5lLWNvbW1lbnQtY29s dW1uICc0MCAnKCMkIC4gLTI3MTIzKSA6dHlwZSAnaW50ZWdlciA6Z3JvdXAgJ3ZoZGwtY29tbWVu dCkKI0AxODQgKkVuZCBvZiBjb21tZW50IGNvbHVtbi4KQ29tbWVudHMgdGhhdCBleGNlZWQgdGhp cyBjb2x1bW4gbnVtYmVyIGFyZSB3cmFwcGVkLgoKTk9URTogQWN0aXZhdGUgdGhlIG5ldyBzZXR0 aW5nIGluIGEgVkhETCBidWZmZXIgdXNpbmcgdGhlIG1lbnUgZW50cnkKICAgICAgIkFjdGl2YXRl IE5ldyBDdXN0b21pemF0aW9ucyIfCihjdXN0b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC1lbmQt Y29tbWVudC1jb2x1bW4gJzc5ICcoIyQgLiAtMjc0MjYpIDp0eXBlICdpbnRlZ2VyIDpncm91cCAn dmhkbC1jb21tZW50KQooYnl0ZS1jb2RlICJcMzAyCEIQXDMwM1wzMDRcMzA1XDMwNglcMzA3JVwy MDciIFtjdXJyZW50LWxvYWQtbGlzdCA6Z3JvdXAgZW5kLWNvbW1lbnQtY29sdW1uIGN1c3RvbS1k ZWNsYXJlLWdyb3VwIHZoZGwtYWxpZ24gbmlsICJDdXN0b21pemF0aW9ucyBmb3IgYWxpZ25tZW50 LiIgdmhkbF0gNikKI0A2OSAqTm9uLW5pbCBtZWFucyBhbGlnbiBzb21lIHRlbXBsYXRlcyBhdXRv bWF0aWNhbGx5IGFmdGVyIGdlbmVyYXRpb24uHwooY3VzdG9tLWRlY2xhcmUtdmFyaWFibGUgJ3Zo ZGwtYXV0by1hbGlnbiAndCAnKCMkIC4gLTI3ODkwKSA6dHlwZSAnYm9vbGVhbiA6Z3JvdXAgJ3Zo ZGwtYWxpZ24pCiNAMTI5ICpOb24tbmlsIG1lYW5zIGFsaWduIGdyb3VwcyBvZiBjb2RlIGxpbmVz IHNlcGFyYXRlbHkuCkEgZ3JvdXAgb2YgY29kZSBsaW5lcyBpcyBhIHJlZ2lvbiBvZiBsaW5lcyB3 aXRoIG5vIGVtcHR5IGxpbmVzIGluYmV0d2Vlbi4fCihjdXN0b20tZGVjbGFyZS12YXJpYWJsZSAn dmhkbC1hbGlnbi1ncm91cHMgJ3QgJygjJCAuIC0yODA2MCkgOnR5cGUgJ2Jvb2xlYW4gOmdyb3Vw ICd2aGRsLWFsaWduKQooY3VzdG9tLWRlY2xhcmUtZ3JvdXAgJ3ZoZGwtaGlnaGxpZ2h0IG5pbCAi Q3VzdG9taXphdGlvbnMgZm9yIGhpZ2hsaWdodGluZy4iIDpncm91cCAndmhkbCkKI0A1NDkgKk5v bi1uaWwgbWVhbnMgaGlnaGxpZ2h0IFZIREwga2V5d29yZHMgYW5kIG90aGVyIHN0YW5kYXJkaXpl ZCB3b3Jkcy4KVGhlIGZvbGxvd2luZyBmYWNlcyBhcmUgdXNlZDoKICBgZm9udC1sb2NrLWtleXdv cmQtZmFjZScgICAgICAgIDoga2V5d29yZHMKICBgZm9udC1sb2NrLXR5cGUtZmFjZScgICAgICAg ICAgIDogc3RhbmRhcmRpemVkIHR5cGVzCiAgYHZoZGwtZm9udC1sb2NrLWF0dHJpYnV0ZS1mYWNl JyA6IHN0YW5kYXJkaXplZCBhdHRyaWJ1dGVzCiAgYHZoZGwtZm9udC1sb2NrLWVudW12YWx1ZS1m YWNlJyA6IHN0YW5kYXJkaXplZCBlbnVtZXJhdGlvbiB2YWx1ZXMKICBgdmhkbC1mb250LWxvY2st ZnVuY3Rpb24tZmFjZScgIDogc3RhbmRhcmRpemVkIGZ1bmN0aW9uIGFuZCBwYWNrYWdlIG5hbWVz CgpOT1RFOiBBY3RpdmF0ZSB0aGUgbmV3IHNldHRpbmcgaW4gYSBWSERMIGJ1ZmZlciBieSByZS1m b250aWZ5aW5nIGl0IChtZW51CiAgICAgIGVudHJ5ICJGb250aWZ5IEJ1ZmZlciIpLiAgWEVtYWNz OiB0dXJuIG9mZiBhbmQgb24gZm9udCBsb2NraW5nLh8KKGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxl ICd2aGRsLWhpZ2hsaWdodC1rZXl3b3JkcyAndCAnKCMkIC4gLTI4MzgzKSA6dHlwZSAnYm9vbGVh biA6c2V0IChsYW1iZGEgKHZhcmlhYmxlIHZhbHVlKSAodmhkbC1jdXN0b20tc2V0IHZhcmlhYmxl IHZhbHVlICd2aGRsLWZvbnQtbG9jay1pbml0KSkgOmdyb3VwICd2aGRsLWhpZ2hsaWdodCkKI0A2 NTQgKk5vbi1uaWwgbWVhbnMgaGlnaGxpZ2h0IGRlY2xhcmF0aW9uIG5hbWVzIGFuZCBjb25zdHJ1 Y3QgbGFiZWxzLgpUaGUgZm9sbG93aW5nIGZhY2VzIGFyZSB1c2VkOgogIGBmb250LWxvY2stZnVu Y3Rpb24tbmFtZS1mYWNlJyAgOiBuYW1lcyBpbiBkZWNsYXJhdGlvbnMgb2YgdW5pdHMsCiAgICAg c3VicHJvZ3JhbXMsIGNvbXBvbmVudHMsIGFzIHdlbGwgYXMgbGFiZWxzIG9mIFZIREwgY29uc3Ry dWN0cwogIGBmb250LWxvY2stdHlwZS1mYWNlJyAgICAgICAgICAgOiBuYW1lcyBpbiB0eXBlL25h dHVyZSBkZWNsYXJhdGlvbnMKICBgdmhkbC1mb250LWxvY2stYXR0cmlidXRlLWZhY2UnIDogbmFt ZXMgaW4gYXR0cmlidXRlIGRlY2xhcmF0aW9ucwogIGBmb250LWxvY2stdmFyaWFibGUtbmFtZS1m YWNlJyAgOiBuYW1lcyBpbiBkZWNsYXJhdGlvbnMgb2Ygc2lnbmFscywKICAgICB2YXJpYWJsZXMs IGNvbnN0YW50cywgc3VicHJvZ3JhbSBwYXJhbWV0ZXJzLCBnZW5lcmljcywgYW5kIHBvcnRzCgpO T1RFOiBBY3RpdmF0ZSB0aGUgbmV3IHNldHRpbmcgaW4gYSBWSERMIGJ1ZmZlciBieSByZS1mb250 aWZ5aW5nIGl0IChtZW51CiAgICAgIGVudHJ5ICJGb250aWZ5IEJ1ZmZlciIpLiAgWEVtYWNzOiB0 dXJuIG9mZiBhbmQgb24gZm9udCBsb2NraW5nLh8KKGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxlICd2 aGRsLWhpZ2hsaWdodC1uYW1lcyAndCAnKCMkIC4gLTI5MTMwKSA6dHlwZSAnYm9vbGVhbiA6c2V0 IChsYW1iZGEgKHZhcmlhYmxlIHZhbHVlKSAodmhkbC1jdXN0b20tc2V0IHZhcmlhYmxlIHZhbHVl ICd2aGRsLWZvbnQtbG9jay1pbml0KSkgOmdyb3VwICd2aGRsLWhpZ2hsaWdodCkKI0AzNjMgKk5v bi1uaWwgbWVhbnMgaGlnaGxpZ2h0IHdvcmRzIHdpdGggc3BlY2lhbCBzeW50YXguClRoZSB3b3Jk cyB3aXRoIHN5bnRheCBhbmQgY29sb3Igc3BlY2lmaWVkIGluIHZhcmlhYmxlCmB2aGRsLXNwZWNp YWwtc3ludGF4LWFsaXN0JyBhcmUgaGlnaGxpZ2h0ZWQgYWNjb3JkaW5nbHkuCkNhbiBiZSB1c2Vk IGZvciB2aXN1YWwgc3VwcG9ydCBvZiBuYW1pbmcgY29udmVudGlvbnMuCgpOT1RFOiBBY3RpdmF0 ZSB0aGUgbmV3IHNldHRpbmcgaW4gYSBWSERMIGJ1ZmZlciBieSByZS1mb250aWZ5aW5nIGl0ICht ZW51CiAgICAgIGVudHJ5ICJGb250aWZ5IEJ1ZmZlciIpLiAgWEVtYWNzOiB0dXJuIG9mZiBhbmQg b24gZm9udCBsb2NraW5nLh8KKGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxlICd2aGRsLWhpZ2hsaWdo dC1zcGVjaWFsLXdvcmRzICduaWwgJygjJCAuIC0yOTk3OSkgOnR5cGUgJ2Jvb2xlYW4gOnNldCAo bGFtYmRhICh2YXJpYWJsZSB2YWx1ZSkgKHZoZGwtY3VzdG9tLXNldCB2YXJpYWJsZSB2YWx1ZSAn dmhkbC1mb250LWxvY2staW5pdCkpIDpncm91cCAndmhkbC1oaWdobGlnaHQpCiNANDI3ICpOb24t bmlsIG1lYW5zIGhpZ2hsaWdodCBmb3JiaWRkZW4gd29yZHMuClRoZSByZXNlcnZlZCB3b3JkcyBz cGVjaWZpZWQgaW4gdmFyaWFibGUgYHZoZGwtZm9yYmlkZGVuLXdvcmRzJyBvciBoYXZpbmcgdGhl CnN5bnRheCBzcGVjaWZpZWQgaW4gdmFyaWFibGUgYHZoZGwtZm9yYmlkZGVuLXN5bnRheCcgYXJl IGhpZ2hsaWdodGVkIGluIGEKd2FybmluZyBjb2xvciAoZmFjZSBgdmhkbC1mb250LWxvY2stcmVz ZXJ2ZWQtd29yZHMtZmFjZScpIHRvIGluZGljYXRlIG5vdCB0bwp1c2UgdGhlbS4KCk5PVEU6IEFj dGl2YXRlIHRoZSBuZXcgc2V0dGluZyBpbiBhIFZIREwgYnVmZmVyIGJ5IHJlLWZvbnRpZnlpbmcg aXQgKG1lbnUKICAgICAgZW50cnkgIkZvbnRpZnkgQnVmZmVyIikuICBYRW1hY3M6IHR1cm4gb2Zm IGFuZCBvbiBmb250IGxvY2tpbmcuHwooY3VzdG9tLWRlY2xhcmUtdmFyaWFibGUgJ3ZoZGwtaGln aGxpZ2h0LWZvcmJpZGRlbi13b3JkcyAnbmlsICcoIyQgLiAtMzA1NDcpIDp0eXBlICdib29sZWFu IDpzZXQgKGxhbWJkYSAodmFyaWFibGUgdmFsdWUpICh2aGRsLWN1c3RvbS1zZXQgdmFyaWFibGUg dmFsdWUgJ3ZoZGwtd29yZHMtaW5pdCAndmhkbC1mb250LWxvY2staW5pdCkpIDpncm91cCAndmhk bC1oaWdobGlnaHQpCiNAMzMyICpOb24tbmlsIG1lYW5zIGhpZ2hsaWdodCBWZXJpbG9nIGtleXdv cmRzIGFzIHJlc2VydmVkIHdvcmRzLgpWZXJpbG9nIGtleXdvcmRzIGFyZSBoaWdobGlnaHRlZCBp biBhIHdhcm5pbmcgY29sb3IgKGZhY2UKYHZoZGwtZm9udC1sb2NrLXJlc2VydmVkLXdvcmRzLWZh Y2UnKSB0byBpbmRpY2F0ZSBub3QgdG8gdXNlIHRoZW0uCgpOT1RFOiBBY3RpdmF0ZSB0aGUgbmV3 IHNldHRpbmcgaW4gYSBWSERMIGJ1ZmZlciBieSByZS1mb250aWZ5aW5nIGl0IChtZW51CiAgICAg IGVudHJ5ICJGb250aWZ5IEJ1ZmZlciIpLiAgWEVtYWNzOiB0dXJuIG9mZiBhbmQgb24gZm9udCBs b2NraW5nLh8KKGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxlICd2aGRsLWhpZ2hsaWdodC12ZXJpbG9n LWtleXdvcmRzICduaWwgJygjJCAuIC0zMTE5OCkgOnR5cGUgJ2Jvb2xlYW4gOnNldCAobGFtYmRh ICh2YXJpYWJsZSB2YWx1ZSkgKHZoZGwtY3VzdG9tLXNldCB2YXJpYWJsZSB2YWx1ZSAndmhkbC13 b3Jkcy1pbml0ICd2aGRsLWZvbnQtbG9jay1pbml0KSkgOmdyb3VwICd2aGRsLWhpZ2hsaWdodCkK I0A0NjEgKk5vbi1uaWwgbWVhbnMgYmFja2dyb3VuZC1oaWdobGlnaHQgY29kZSBleGNsdWRlZCBm cm9tIHRyYW5zbGF0aW9uLgpUaGF0IGlzLCBhbGwgY29kZSBiZXR3ZWVuICItLSBwcmFnbWEgdHJh bnNsYXRlX29mZiIgYW5kCiItLSBwcmFnbWEgdHJhbnNsYXRlX29uIiBpcyBoaWdobGlnaHRlZCB1 c2luZyBhIGRpZmZlcmVudCBiYWNrZ3JvdW5kIGNvbG9yCihmYWNlIGB2aGRsLWZvbnQtbG9jay10 cmFuc2xhdGUtb2ZmLWZhY2UnKS4KTm90ZTogdGhpcyBtaWdodCBzbG93IGRvd24gb24tdGhlLWZs eSBmb250aWZpY2F0aW9uIChhbmQgdGh1cyBlZGl0aW5nKS4KCk5PVEU6IEFjdGl2YXRlIHRoZSBu ZXcgc2V0dGluZyBpbiBhIFZIREwgYnVmZmVyIGJ5IHJlLWZvbnRpZnlpbmcgaXQgKG1lbnUKICAg ICAgZW50cnkgIkZvbnRpZnkgQnVmZmVyIikuICBYRW1hY3M6IHR1cm4gb2ZmIGFuZCBvbiBmb250 IGxvY2tpbmcuHwooY3VzdG9tLWRlY2xhcmUtdmFyaWFibGUgJ3ZoZGwtaGlnaGxpZ2h0LXRyYW5z bGF0ZS1vZmYgJ25pbCAnKCMkIC4gLTMxNzU1KSA6dHlwZSAnYm9vbGVhbiA6c2V0IChsYW1iZGEg KHZhcmlhYmxlIHZhbHVlKSAodmhkbC1jdXN0b20tc2V0IHZhcmlhYmxlIHZhbHVlICd2aGRsLWZv bnQtbG9jay1pbml0KSkgOmdyb3VwICd2aGRsLWhpZ2hsaWdodCkKI0A1MTcgKk5vbi1uaWwgbWVh bnMgY29uc2lkZXIgY2FzZSBmb3IgaGlnaGxpZ2h0aW5nLgpQb3NzaWJsZSB0cmFkZS1vZmY6CiAg bm9uLW5pbCAgYWxzbyB1cHBlci1jYXNlIFZIREwgd29yZHMgYXJlIGhpZ2hsaWdodGVkLCBidXQg Y2FzZSBvZiB3b3JkcyB3aXRoCiAgICAgICAgICAgc3BlY2lhbCBzeW50YXggaXMgbm90IGNvbnNp ZGVyZWQKICBuaWwgICAgICBvbmx5IGxvd2VyLWNhc2UgVkhETCB3b3JkcyBhcmUgaGlnaGxpZ2h0 ZWQsIGJ1dCBjYXNlIG9mIHdvcmRzIHdpdGgKICAgICAgICAgICBzcGVjaWFsIHN5bnRheCBpcyBj b25zaWRlcmVkCk92ZXJyaWRlcyBsb2NhbCB2YXJpYWJsZSBgZm9udC1sb2NrLWtleXdvcmRzLWNh c2UtZm9sZC1zZWFyY2gnLgoKTk9URTogQWN0aXZhdGUgdGhlIG5ldyBzZXR0aW5nIGluIGEgVkhE TCBidWZmZXIgYnkgcmUtZm9udGlmeWluZyBpdCAobWVudQogICAgICBlbnRyeSAiRm9udGlmeSBC dWZmZXIiKS4gIFhFbWFjczogdHVybiBvZmYgYW5kIG9uIGZvbnQgbG9ja2luZy4fCihjdXN0b20t ZGVjbGFyZS12YXJpYWJsZSAndmhkbC1oaWdobGlnaHQtY2FzZS1zZW5zaXRpdmUgJ25pbCAnKCMk IC4gLTMyNDIxKSA6dHlwZSAnYm9vbGVhbiA6Z3JvdXAgJ3ZoZGwtaGlnaGxpZ2h0KQojQDEyOTgg Kkxpc3Qgb2Ygc3BlY2lhbCBzeW50YXggdG8gYmUgaGlnaGxpZ2h0ZWQuCklmIHZhcmlhYmxlIGB2 aGRsLWhpZ2hsaWdodC1zcGVjaWFsLXdvcmRzJyBpcyBub24tbmlsLCB3b3JkcyB3aXRoIHRoZSBz cGVjaWZpZWQKc3ludGF4IChhcyByZWd1bGFyIGV4cHJlc3Npb24pIGFyZSBoaWdobGlnaHRlZCBp biB0aGUgY29ycmVzcG9uZGluZyBjb2xvci4KCiAgTmFtZSAgICAgICAgIDogc3RyaW5nIG9mIHdv cmRzIGFuZCBzcGFjZXMKICBSZWdleHAgICAgICAgOiByZWd1bGFyIGV4cHJlc3Npb24gZGVzY3Jp YmluZyB3b3JkIHN5bnRheAogICAgICAgICAgICAgICAgICAoZS5nLiAiXHcrX2MiIG1hdGNoZXMg d29yZCB3aXRoIHN1ZmZpeCAiX2MiKQogIENvbG9yIChsaWdodCk6IGZvcmVncm91bmQgY29sb3Ig Zm9yIGxpZ2h0IGJhY2tncm91bmQKICAgICAgICAgICAgICAgICAobWF0Y2hpbmcgY29sb3IgZXhh bXBsZXM6IEdvbGQzLCBHcmV5NTAsIExpbWVHcmVlbiwgVG9tYXRvLAogICAgICAgICAgICAgICAg IExpZ2h0U2VhR3JlZW4sIERvZGdlckJsdWUsIEdvbGQsIFBhbGVWaW9sZXRSZWQpCiAgQ29sb3Ig KGRhcmspIDogZm9yZWdyb3VuZCBjb2xvciBmb3IgZGFyayBiYWNrZ3JvdW5kCiAgICAgICAgICAg ICAgICAgKG1hdGNoaW5nIGNvbG9yIGV4YW1wbGVzOiBCdXJseVdvb2QxLCBHcmV5ODAsIEdyZWVu LCBDb3JhbCwKICAgICAgICAgICAgICAgICBBcXVhTWFyaW5lMiwgTGlnaHRTa3lCbHVlMSwgWWVs bG93LCBQYWxlVmlvbGV0UmVkMSkKCkNhbiBiZSB1c2VkIGZvciB2aXN1YWwgc3VwcG9ydCBvZiBu YW1pbmcgY29udmVudGlvbnMsIHN1Y2ggYXMgaGlnaGxpZ2h0aW5nCmRpZmZlcmVudCBraW5kcyBv ZiBzaWduYWxzIChlLmcuICJDbGtfYyIsICJSc3RfciIpIG9yIG9iamVjdHMgKGUuZy4KIlNpZ25h bF9zIiwgIlZhcmlhYmxlX3YiLCAiQ29uc3RhbnRfYyIpIGJ5IGRpc3Rpbmd1aXNoaW5nIHRoZW0g dXNpbmcKbmFtZSBzdWZmaWNlcy4KRm9yIGVhY2ggZW50cnksIGEgbmV3IGZhY2UgaXMgZ2VuZXJh dGVkIHdpdGggdGhlIHNwZWNpZmllZCBjb2xvcnMgYW5kIG5hbWUKInZoZGwtZm9udC1sb2NrLSIg KyBuYW1lICsgIi1mYWNlIi4KCk5PVEU6IEFjdGl2YXRlIGEgY2hhbmdlZCByZWdleHAgaW4gYSBW SERMIGJ1ZmZlciBieSByZS1mb250aWZ5aW5nIGl0IChtZW51CiAgICAgIGVudHJ5ICJGb250aWZ5 IEJ1ZmZlciIpLiAgWEVtYWNzOiB0dXJuIG9mZiBhbmQgb24gZm9udCBsb2NraW5nLgogICAgICBB bGwgb3RoZXIgY2hhbmdlcyByZXF1aXJlIHJlc3RhcnRpbmcgRW1hY3MuHwooY3VzdG9tLWRlY2xh cmUtdmFyaWFibGUgJ3ZoZGwtc3BlY2lhbC1zeW50YXgtYWxpc3QgJ25pbCAnKCMkIC4gLTMzMDYw KSA6dHlwZSAnKHJlcGVhdCAobGlzdCA6dGFnICJGYWNlIiA6aW5kZW50IDIgKHN0cmluZyA6dGFn ICJOYW1lICAgICAgICAgIikgKHJlZ2V4cCA6dGFnICJSZWdleHAgICAgICAgIiAiXFx3K18iKSAo c3RyaW5nIDp0YWcgIkNvbG9yIChsaWdodCkiKSAoc3RyaW5nIDp0YWcgIkNvbG9yIChkYXJrKSAi KSkpIDpzZXQgKGxhbWJkYSAodmFyaWFibGUgdmFsdWUpICh2aGRsLWN1c3RvbS1zZXQgdmFyaWFi bGUgdmFsdWUgJ3ZoZGwtZm9udC1sb2NrLWluaXQpKSA6Z3JvdXAgJ3ZoZGwtaGlnaGxpZ2h0KQoj QDMzMiAqTGlzdCBvZiBmb3JiaWRkZW4gd29yZHMgdG8gYmUgaGlnaGxpZ2h0ZWQuCklmIHZhcmlh YmxlIGB2aGRsLWhpZ2hsaWdodC1mb3JiaWRkZW4td29yZHMnIGlzIG5vbi1uaWwsIHRoZXNlIHJl c2VydmVkCndvcmRzIGFyZSBoaWdobGlnaHRlZCBpbiBhIHdhcm5pbmcgY29sb3IgdG8gaW5kaWNh dGUgbm90IHRvIHVzZSB0aGVtLgoKTk9URTogQWN0aXZhdGUgdGhlIG5ldyBzZXR0aW5nIGluIGEg VkhETCBidWZmZXIgYnkgcmUtZm9udGlmeWluZyBpdCAobWVudQogICAgICBlbnRyeSAiRm9udGlm eSBCdWZmZXIiKS4gIFhFbWFjczogdHVybiBvZmYgYW5kIG9uIGZvbnQgbG9ja2luZy4fCihjdXN0 b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC1mb3JiaWRkZW4td29yZHMgJyduaWwgJygjJCAuIC0z NDcxOCkgOnR5cGUgJyhyZXBlYXQgKHN0cmluZyA6Zm9ybWF0ICIldiIpKSA6c2V0IChsYW1iZGEg KHZhcmlhYmxlIHZhbHVlKSAodmhkbC1jdXN0b20tc2V0IHZhcmlhYmxlIHZhbHVlICd2aGRsLXdv cmRzLWluaXQgJ3ZoZGwtZm9udC1sb2NrLWluaXQpKSA6Z3JvdXAgJ3ZoZGwtaGlnaGxpZ2h0KQoj QDQ2NCAqU3ludGF4IG9mIGZvcmJpZGRlbiB3b3JkcyB0byBiZSBoaWdobGlnaHRlZC4KSWYgdmFy aWFibGUgYHZoZGwtaGlnaGxpZ2h0LWZvcmJpZGRlbi13b3JkcycgaXMgbm9uLW5pbCwgd29yZHMg d2l0aCB0aGlzCnN5bnRheCBhcmUgaGlnaGxpZ2h0ZWQgaW4gYSB3YXJuaW5nIGNvbG9yIHRvIGlu ZGljYXRlIG5vdCB0byB1c2UgdGhlbS4KQ2FuIGJlIHVzZWQgdG8gaGlnaGxpZ2h0IHRvbyBsb25n IGlkZW50aWZpZXJzIChlLmcuICJcd1x3XHdcd1x3XHdcd1x3XHdcdysiCmhpZ2hsaWdodHMgaWRl bnRpZmllcnMgd2l0aCAxMCBvciBtb3JlIGNoYXJhY3RlcnMpLgoKTk9URTogQWN0aXZhdGUgdGhl IG5ldyBzZXR0aW5nIGluIGEgVkhETCBidWZmZXIgYnkgcmUtZm9udGlmeWluZyBpdCAobWVudQog ICAgICBlbnRyeSAiRm9udGlmeSBCdWZmZXIiKS4gIFhFbWFjczogdHVybiBvZmYgYW5kIG9uIGZv bnQgbG9ja2luZy4fCihjdXN0b20tZGVjbGFyZS12YXJpYWJsZSAndmhkbC1mb3JiaWRkZW4tc3lu dGF4ICciIiAnKCMkIC4gLTM1Mjg4KSA6dHlwZSAncmVnZXhwIDpzZXQgKGxhbWJkYSAodmFyaWFi bGUgdmFsdWUpICh2aGRsLWN1c3RvbS1zZXQgdmFyaWFibGUgdmFsdWUgJ3ZoZGwtd29yZHMtaW5p dCAndmhkbC1mb250LWxvY2staW5pdCkpIDpncm91cCAndmhkbC1oaWdobGlnaHQpCihjdXN0b20t ZGVjbGFyZS1ncm91cCAndmhkbC1tZW51IG5pbCAiQ3VzdG9taXphdGlvbnMgZm9yIHNwZWVkYmFy IGFuZCBtZW51ZXMuIiA6Z3JvdXAgJ3ZoZGwpCiNAMTIyICpOb24tbmlsIG1lYW5zIG9wZW4gdGhl IHNwZWVkYmFyIGF1dG9tYXRpY2FsbHkgYXQgc3RhcnR1cC4KQWx0ZXJuYXRpdmVseSwgdGhlIHNw ZWVkYmFyIGNhbiBiZSBvcGVuZWQgZnJvbSB0aGUgVkhETCBtZW51Lh8KKGN1c3RvbS1kZWNsYXJl LXZhcmlhYmxlICd2aGRsLXNwZWVkYmFyICduaWwgJygjJCAuIC0zNjA1OCkgOnR5cGUgJ2Jvb2xl YW4gOmdyb3VwICd2aGRsLW1lbnUpCiNAMTI1ICpOb24tbmlsIG1lYW5zIG9wZW4gdGhlIHNwZWVk YmFyIGFzIGhpZXJhcmNoeSBicm93c2VyIGF0IHN0YXJ0dXAuCk90aGVyd2lzZSwgdGhlIHNwZWVk YmFyIGlzIG9wZW5lZCBhcyBub3JtYWwgZmlsZSBicm93c2VyLh8KKGN1c3RvbS1kZWNsYXJlLXZh cmlhYmxlICd2aGRsLXNwZWVkYmFyLXNob3ctaGllcmFyY2h5ICduaWwgJygjJCAuIC0zNjI4MCkg OnR5cGUgJ2Jvb2xlYW4gOmdyb3VwICd2aGRsLW1lbnUpCiNANjIgKkFtb3VudCBvZiBpbmRlbnRh dGlvbiBpbiBoaWVyYXJjaHkgZGlzcGxheSBvZiBzdWJjb21wb25lbnQuHwooY3VzdG9tLWRlY2xh cmUtdmFyaWFibGUgJ3ZoZGwtc3BlZWRiYXItaGllcmFyY2h5LWluZGVudCAnMSAnKCMkIC4gLTM2 NTE5KSA6dHlwZSAnaW50ZWdlciA6Z3JvdXAgJ3ZoZGwtbWVudSkKI0AyNDIgKk5vbi1uaWwgbWVh bnMgYWRkIGFuIGluZGV4IG1lbnUgZm9yIGEgc291cmNlIGZpbGUgd2hlbiBsb2FkaW5nLgpBbHRl cm5hdGl2ZWx5LCB0aGUgc3BlZWRiYXIgY2FuIGJlIHVzZWQuICBOb3RlIHRoYXQgdGhlIGluZGV4 IG1lbnUgc2NhbnMgYSBmaWxlCndoZW4gaXQgaXMgb3BlbmVkLCB3aGlsZSBzcGVlZGJhciBvbmx5 IHNjYW5zIHRoZSBmaWxlIHVwb24gcmVxdWVzdC4KRG9lcyBub3Qgd29yayB1bmRlciBYRW1hY3Mu HwooY3VzdG9tLWRlY2xhcmUtdmFyaWFibGUgJ3ZoZGwtaW5kZXgtbWVudSAnbmlsICcoIyQgLiAt MzY2OTYpIDp0eXBlICdib29sZWFuIDpncm91cCAndmhkbC1tZW51KQojQDExMCAqTm9uLW5pbCBt ZWFucyBhZGQgYSBtZW51IG9mIGFsbCBzb3VyY2UgZmlsZXMgaW4gY3VycmVudCBkaXJlY3Rvcnku CkFsdGVybmF0aXZlbHksIHRoZSBzcGVlZGJhciBjYW4gYmUgdXNlZC4fCihjdXN0b20tZGVjbGFy ZS12YXJpYWJsZSAndmhkbC1zb3VyY2UtZmlsZS1tZW51ICduaWwgJygjJCAuIC0zNzA0MCkgOnR5 cGUgJ2Jvb2xlYW4gOmdyb3VwICd2aGRsLW1lbnUpCiNAMjM3ICpOb24tbmlsIG1lYW5zIGFkZCBo aWRlc2hvdyBtZW51IGFuZCBmdW5jdGlvbmFsaXR5LgpIaWRlc2hvdyBhbGxvd3MgaGlkaW5nIGNv ZGUgb2YgVkhETCBkZXNpZ24gdW5pdHMuCkRvZXMgbm90IHdvcmsgdW5kZXIgWEVtYWNzLgoKTk9U RTogQWN0aXZhdGUgdGhlIG5ldyBzZXR0aW5nIGluIGEgVkhETCBidWZmZXIgdXNpbmcgdGhlIG1l bnUgZW50cnkKICAgICAgIkFjdGl2YXRlIE5ldyBDdXN0b21pemF0aW9ucyIfCihjdXN0b20tZGVj bGFyZS12YXJpYWJsZSAndmhkbC1oaWRlc2hvdy1tZW51ICduaWwgJygjJCAuIC0zNzI1OCkgOnR5 cGUgJ2Jvb2xlYW4gOmdyb3VwICd2aGRsLW1lbnUpCiNANzIgKk5vbi1uaWwgbWVhbnMgaGlkZSBh bGwgZGVzaWduIHVuaXRzIGluaXRpYWxseSBhZnRlciBhIGZpbGUgaXMgbG9hZGVkLh8KKGN1c3Rv bS1kZWNsYXJlLXZhcmlhYmxlICd2aGRsLWhpZGUtYWxsLWluaXQgJ25pbCAnKCMkIC4gLTM3NTk5 KSA6dHlwZSAnYm9vbGVhbiA6Z3JvdXAgJ3ZoZGwtbWVudSkKKGN1c3RvbS1kZWNsYXJlLWdyb3Vw ICd2aGRsLXByaW50IG5pbCAiQ3VzdG9taXphdGlvbnMgZm9yIHByaW50aW5nLiIgOmdyb3VwICd2 aGRsKQojQDE2MiAqTm9uLW5pbCBtZWFucyBwcmludCBjb2RlIGluIHR3byBjb2x1bW5zIGFuZCBs YW5kc2NhcGUgZm9ybWF0LgoKTk9URTogQWN0aXZhdGUgdGhlIG5ldyBzZXR0aW5nIGJ5IHJlc3Rh cnRpbmcgRW1hY3MuCiAgICAgIE92ZXJyaWRlcyBgcHMtcHJpbnQnIHNldHRpbmdzIGxvY2FsbHku HwooY3VzdG9tLWRlY2xhcmUtdmFyaWFibGUgJ3ZoZGwtcHJpbnQtdHdvLWNvbHVtbiAndCAnKCMk IC4gLTM3ODU5KSA6dHlwZSAnYm9vbGVhbiA6Z3JvdXAgJ3ZoZGwtcHJpbnQpCiNAMTY5ICpOb24t bmlsIG1lYW5zIHVzZSBhbiBvcHRpbWl6ZWQgc2V0IG9mIGZhY2VzIGZvciBwb3N0c2NyaXB0IHBy aW50aW5nLgoKTk9URTogQWN0aXZhdGUgdGhlIG5ldyBzZXR0aW5nIGJ5IHJlc3RhcnRpbmcgRW1h Y3MuCiAgICAgIE92ZXJyaWRlcyBgcHMtcHJpbnQnIHNldHRpbmdzIGxvY2FsbHkuHwooY3VzdG9t LWRlY2xhcmUtdmFyaWFibGUgJ3ZoZGwtcHJpbnQtY3VzdG9taXplLWZhY2VzICd0ICcoIyQgLiAt MzgxMjgpIDp0eXBlICdib29sZWFuIDpncm91cCAndmhkbC1wcmludCkKKGN1c3RvbS1kZWNsYXJl LWdyb3VwICd2aGRsLW1pc2MgbmlsICJNaXNjZWxsYW5lb3VzIGN1c3RvbWl6YXRpb25zLiIgOmdy b3VwICd2aGRsKQojQDUyMiAqTm9uLW5pbCBtZWFucyBgVEFCJyBkb2VzIGluZGVudGF0aW9uLCB3 b3JkIGNvbXBsZXRpb24gYW5kIHRhYiBpbnNlcnRpb24uClRoYXQgaXMsIGlmIHByZWNlZWRpbmcg Y2hhcmFjdGVyIGlzIHBhcnQgb2YgYSB3b3JkIHRoZW4gY29tcGxldGUgd29yZCwKZWxzZSBpZiBu b3QgYXQgYmVnaW5uaW5nIG9mIGxpbmUgdGhlbiBpbnNlcnQgdGFiLAplbHNlIGlmIGxhc3QgY29t bWFuZCB3YXMgYSBgVEFCJyBvciBgUkVUJyB0aGVuIGRlZGVudCBvbmUgc3RlcCwKZWxzZSBpbmRl bnQgY3VycmVudCBsaW5lIChpLmUuIGBUQUInIGlzIGJvdW5kIHRvIGB2aGRsLWVsZWN0cmljLXRh YicpLgpJZiBuaWwsIFRBQiBhbHdheXMgaW5kZW50cyBjdXJyZW50IGxpbmUgKGkuZS4gYFRBQicg aXMgYm91bmQgdG8KYHZoZGwtaW5kZW50LWxpbmUnKS4KCk5PVEU6IEFjdGl2YXRlIHRoZSBuZXcg c2V0dGluZyBpbiBhIFZIREwgYnVmZmVyIHVzaW5nIHRoZSBtZW51IGVudHJ5CiAgICAgICJBY3Rp dmF0ZSBOZXcgQ3VzdG9taXphdGlvbnMiHwooY3VzdG9tLWRlY2xhcmUtdmFyaWFibGUgJ3ZoZGwt aW50ZWxsaWdlbnQtdGFiICd0ICcoIyQgLiAtMzg0OTIpIDp0eXBlICdib29sZWFuIDpncm91cCAn dmhkbC1taXNjKQojQDE2NSAqTm9uLW5pbCBtZWFucyB3b3JkIGNvbXBsZXRpb24gdXNpbmcgYFRB QicgaXMgY2FzZSBzZW5zaXRpdmUuClRoYXQgaXMsIGBUQUInIGNvbXBsZXRlcyB3b3JkcyB0aGF0 IHN0YXJ0IHdpdGggdGhlIHNhbWUgbGV0dGVycyBhbmQgY2FzZS4KT3RoZXJ3aXNlLCBjYXNlIGlz IGlnbm9yZWQuHwooY3VzdG9tLWRlY2xhcmUtdmFyaWFibGUgJ3ZoZGwtd29yZC1jb21wbGV0aW9u LWNhc2Utc2Vuc2l0aXZlICduaWwgJygjJCAuIC0zOTExOSkgOnR5cGUgJ2Jvb2xlYW4gOmdyb3Vw ICd2aGRsLW1pc2MpCiNAMTI1ICpOb24tbmlsIGVuYWJsZXMgd29yZCBjb21wbGV0aW9uIGluIG1p bmlidWZmZXIgKGZvciB0ZW1wbGF0ZSBwcm9tcHRzKS4KCk5PVEU6IEFjdGl2YXRlIHRoZSBuZXcg c2V0dGluZyBieSByZXN0YXJ0aW5nIEVtYWNzLh8KKGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxlICd2 aGRsLXdvcmQtY29tcGxldGlvbi1pbi1taW5pYnVmZmVyICd0ICcoIyQgLiAtMzk0MDYpIDp0eXBl ICdib29sZWFuIDpncm91cCAndmhkbC1taXNjKQojQDM2OSAqTm9uLW5pbCBtZWFucyBjb25zaWRl ciB0aGUgdW5kZXJzY29yZSBjaGFyYWN0ZXIgYF8nIGFzIHBhcnQgb2Ygd29yZC4KQW4gaWRlbnRp ZmllciBjb250YWluaW5nIHVuZGVyc2NvcmVzIGlzIHRoZW4gdHJlYXRlZCBhcyBhIHNpbmdsZSB3 b3JkIGluCnNlbGVjdCBhbmQgbW92ZSBvcGVyYXRpb25zLiAgQWxsIHBhcnRzIG9mIGFuIGlkZW50 aWZpZXIgc2VwYXJhdGVkIGJ5IHVuZGVyc2NvcmUKYXJlIHRyZWF0ZWQgYXMgc2luZ2xlIHdvcmRz IG90aGVyd2lzZS4KCk5PVEU6IEFjdGl2YXRlIHRoZSBuZXcgc2V0dGluZyBpbiBhIFZIREwgYnVm ZmVyIHVzaW5nIHRoZSBtZW51IGVudHJ5CiAgICAgICJBY3RpdmF0ZSBOZXcgQ3VzdG9taXphdGlv bnMiHwooY3VzdG9tLWRlY2xhcmUtdmFyaWFibGUgJ3ZoZGwtdW5kZXJzY29yZS1pcy1wYXJ0LW9m LXdvcmQgJ25pbCAnKCMkIC4gLTM5NjUwKSA6dHlwZSAnYm9vbGVhbiA6c2V0IChsYW1iZGEgKHZh cmlhYmxlIHZhbHVlKSAodmhkbC1jdXN0b20tc2V0IHZhcmlhYmxlIHZhbHVlICd2aGRsLW1vZGUt c3ludGF4LXRhYmxlLWluaXQpKSA6Z3JvdXAgJ3ZoZGwtbWlzYykKKGJ5dGUtY29kZSAiXDMwMlwz MDNcMzA0XDMwNQhcMzA2JVwyMTBcMzA3XDMwM1wzMTBcMzExI1wyMTBcMzEyXDMxMwlcIlwyMDMe AFwzMDdcMzAzXDMxNFwzMTEjXDIxMFwyMDIkAFwzMDdcMzAzXDMxNVwzMTYjXDIxMFwzMTJcMzEz CVwiXDIwNDEAXDMwN1wzMDNcMzE3XDMxMSNcMjEwXDMwN1wzMDNcMzIwXDMxNiNcMjEwXDMwN1wz MDNcMzIxXDMxMSNcMjEwXDMwN1wzMDNcMzIyXDMxMSNcMjA3IiBbOmdyb3VwIGVtYWNzLXZlcnNp b24gY3VzdG9tLWRlY2xhcmUtZ3JvdXAgdmhkbC1yZWxhdGVkIG5pbCAiUmVsYXRlZCBnZW5lcmFs IGN1c3RvbWl6YXRpb25zLiIgdmhkbCBjdXN0b20tYWRkLXRvLWdyb3VwIGxpbmUtbnVtYmVyLW1v ZGUgY3VzdG9tLXZhcmlhYmxlIHN0cmluZy1tYXRjaCAiWEVtYWNzIiBwYXJlbi1tb2RlIHBhcmVu LXNob3dpbmcgY3VzdG9tLWdyb3VwIHRyYW5zaWVudC1tYXJrLW1vZGUgcHMtcHJpbnQgbWFpbC1o b3N0LWFkZHJlc3MgdXNlci1tYWlsLWFkZHJlc3NdIDYpCiNAMjcgVkhETCBNb2RlIHZlcnNpb24g bnVtYmVyLh8KKGRlZmNvbnN0IHZoZGwtdmVyc2lvbiAiMy4yOSIgKCMkIC4gNDA3MzcpKQojQDIw NyAqSW50ZXJ2YWwgdXNlZCB0byB1cGRhdGUgcHJvZ3Jlc3Mgc3RhdHVzIGR1cmluZyBsb25nIG9w ZXJhdGlvbnMuCklmIGEgbnVtYmVyLCBwZXJjZW50YWdlIGNvbXBsZXRlIGdldHMgdXBkYXRlZCBh ZnRlciBlYWNoIGludGVydmFsIG9mCnRoYXQgbWFueSBzZWNvbmRzLiAgIFRvIGluaGliaXQgYWxs IG1lc3NhZ2VzLCBzZXQgdGhpcyB2YXJpYWJsZSB0byBuaWwuHwooZGVmdmFyIHZoZGwtcHJvZ3Jl c3MtaW50ZXJ2YWwgMSAoIyQgLiAtNDA4MTQpKQojQDU2ICpJZiBub24tbmlsLCBpbmhpYml0cyBz dGFydCB1cCBjb21wYXRpYmlsaXR5IHdhcm5pbmdzLh8KKGRlZnZhciB2aGRsLWluaGliaXQtc3Rh cnR1cC13YXJuaW5ncy1wIG5pbCAoIyQgLiAtNDEwNzQpKQojQDI1OCAqSWYgbm9uLW5pbCwgYWxs IHN5bnRhY3RpYyBzeW1ib2xzIG11c3QgYmUgZm91bmQgaW4gYHZoZGwtb2Zmc2V0cy1hbGlzdCcu CklmIHRoZSBzeW50YWN0aWMgc3ltYm9sIGZvciBhIHBhcnRpY3VsYXIgbGluZSBkb2VzIG5vdCBt YXRjaCBhIHN5bWJvbAppbiB0aGUgb2Zmc2V0cyBhbGlzdCwgYW4gZXJyb3IgaXMgZ2VuZXJhdGVk LCBvdGhlcndpc2Ugbm8gZXJyb3IgaXMKcmVwb3J0ZWQgYW5kIHRoZSBzeW50YWN0aWMgc3ltYm9s IGlzIGlnbm9yZWQuHwooZGVmdmFyIHZoZGwtc3RyaWN0LXN5bnRheC1wIG5pbCAoIyQgLiAtNDEx OTUpKQojQDY2ICpJZiBub24tbmlsLCBzeW50YWN0aWMgaW5mbyBpcyBlY2hvZWQgd2hlbiB0aGUg bGluZSBpcyBpbmRlbnRlZC4fCihkZWZ2YXIgdmhkbC1lY2hvLXN5bnRhY3RpYy1pbmZvcm1hdGlv bi1wIG5pbCAoIyQgLiAtNDE1MDYpKQojQDE0MyBEZWZhdWx0IHNldHRpbmdzIGZvciBvZmZzZXRz IG9mIHN5bnRhY3RpYyBlbGVtZW50cy4KRG8gbm90IGNoYW5nZSB0aGlzIGNvbnN0YW50ISAgU2Vl IHRoZSB2YXJpYWJsZSBgdmhkbC1vZmZzZXRzLWFsaXN0JyBmb3IKbW9yZSBpbmZvcm1hdGlvbi4f CihkZWZjb25zdCB2aGRsLW9mZnNldHMtYWxpc3QtZGVmYXVsdCAnKChzdHJpbmcgLiAtMTAwMCkg KGJsb2NrLW9wZW4gLiAwKSAoYmxvY2stY2xvc2UgLiAwKSAoc3RhdGVtZW50IC4gMCkgKHN0YXRl bWVudC1jb250IC4gdmhkbC1saW5ldXAtc3RhdGVtZW50LWNvbnQpIChzdGF0ZW1lbnQtYmxvY2st aW50cm8gLiArKSAoc3RhdGVtZW50LWNhc2UtaW50cm8gLiArKSAoY2FzZS1hbHRlcm5hdGl2ZSAu ICspIChjb21tZW50IC4gdmhkbC1saW5ldXAtY29tbWVudCkgKGFyZ2xpc3QtaW50cm8gLiArKSAo YXJnbGlzdC1jb250IC4gMCkgKGFyZ2xpc3QtY29udC1ub25lbXB0eSAuIHZoZGwtbGluZXVwLWFy Z2xpc3QpIChhcmdsaXN0LWNsb3NlIC4gdmhkbC1saW5ldXAtYXJnbGlzdCkgKGVudGl0eSAuIDAp IChjb25maWd1cmF0aW9uIC4gMCkgKHBhY2thZ2UgLiAwKSAoYXJjaGl0ZWN0dXJlIC4gMCkgKHBh Y2thZ2UtYm9keSAuIDApKSAoIyQgLiA0MTYzOSkpCiNAMzE1NyAqQXNzb2NpYXRpb24gbGlzdCBv ZiBzeW50YWN0aWMgZWxlbWVudCBzeW1ib2xzIGFuZCBpbmRlbnRhdGlvbiBvZmZzZXRzLgpBcyBk ZXNjcmliZWQgYmVsb3csIGVhY2ggY29ucyBjZWxsIGluIHRoaXMgbGlzdCBoYXMgdGhlIGZvcm06 CgogICAgKFNZTlRBQ1RJQy1TWU1CT0wgLiBPRkZTRVQpCgpXaGVuIGEgbGluZSBpcyBpbmRlbnRl ZCwgYHZoZGwtbW9kZScgZmlyc3QgZGV0ZXJtaW5lcyB0aGUgc3ludGFjdGljCmNvbnRleHQgb2Yg dGhlIGxpbmUgYnkgZ2VuZXJhdGluZyBhIGxpc3Qgb2Ygc3ltYm9scyBjYWxsZWQgc3ludGFjdGlj CmVsZW1lbnRzLiAgVGhpcyBsaXN0IGNhbiBjb250YWluIG1vcmUgdGhhbiBvbmUgc3ludGFjdGlj IGVsZW1lbnQgYW5kCnRoZSBnbG9iYWwgdmFyaWFibGUgYHZoZGwtc3ludGFjdGljLWNvbnRleHQn IGNvbnRhaW5zIHRoZSBjb250ZXh0IGxpc3QKZm9yIHRoZSBsaW5lIGJlaW5nIGluZGVudGVkLiAg RWFjaCBlbGVtZW50IGluIHRoaXMgbGlzdCBpcyBhY3R1YWxseSBhCmNvbnMgY2VsbCBvZiB0aGUg c3ludGFjdGljIHN5bWJvbCBhbmQgYSBidWZmZXIgcG9zaXRpb24uICBUaGlzIGJ1ZmZlcgpwb3Np dGlvbiBpcyBjYWxsIHRoZSByZWxhdGl2ZSBpbmRlbnQgcG9pbnQgZm9yIHRoZSBsaW5lLiAgU29t ZQpzeW50YWN0aWMgc3ltYm9scyBtYXkgbm90IGhhdmUgYSByZWxhdGl2ZSBpbmRlbnQgcG9pbnQg YXNzb2NpYXRlZCB3aXRoCnRoZW0uCgpBZnRlciB0aGUgc3ludGFjdGljIGNvbnRleHQgbGlzdCBm b3IgYSBsaW5lIGlzIGdlbmVyYXRlZCwgYHZoZGwtbW9kZScKY2FsY3VsYXRlcyB0aGUgYWJzb2x1 dGUgaW5kZW50YXRpb24gZm9yIHRoZSBsaW5lIGJ5IGxvb2tpbmcgYXQgZWFjaApzeW50YWN0aWMg ZWxlbWVudCBpbiB0aGUgbGlzdC4gIEZpcnN0LCBpdCBjb21wYXJlcyB0aGUgc3ludGFjdGljCmVs ZW1lbnQgYWdhaW5zdCB0aGUgU1lOVEFDVElDLVNZTUJPTCdzIGluIGB2aGRsLW9mZnNldHMtYWxp c3QnLiAgV2hlbiBpdApmaW5kcyBhIG1hdGNoLCBpdCBhZGRzIHRoZSBPRkZTRVQgdG8gdGhlIGNv bHVtbiBvZiB0aGUgcmVsYXRpdmUgaW5kZW50CnBvaW50LiAgVGhlIHN1bSBvZiB0aGlzIGNhbGN1 bGF0aW9uIGZvciBlYWNoIGVsZW1lbnQgaW4gdGhlIHN5bnRhY3RpYwpsaXN0IGlzIHRoZSBhYnNv bHV0ZSBvZmZzZXQgZm9yIGxpbmUgYmVpbmcgaW5kZW50ZWQuCgpJZiB0aGUgc3ludGFjdGljIGVs ZW1lbnQgZG9lcyBub3QgbWF0Y2ggYW55IGluIHRoZSBgdmhkbC1vZmZzZXRzLWFsaXN0JywKYW4g ZXJyb3IgaXMgZ2VuZXJhdGVkIGlmIGB2aGRsLXN0cmljdC1zeW50YXgtcCcgaXMgbm9uLW5pbCwg b3RoZXJ3aXNlCnRoZSBlbGVtZW50IGlzIGlnbm9yZWQuCgpBY3R1YWxseSwgT0ZGU0VUIGNhbiBi ZSBhbiBpbnRlZ2VyLCBhIGZ1bmN0aW9uLCBhIHZhcmlhYmxlLCBvciBvbmUgb2YKdGhlIGZvbGxv d2luZyBzeW1ib2xzOiBgKycsIGAtJywgYCsrJywgb3IgYC0tJy4gIFRoZXNlIGxhdHRlcgpkZXNp Z25hdGUgcG9zaXRpdmUgb3IgbmVnYXRpdmUgbXVsdGlwbGVzIG9mIGB2aGRsLWJhc2ljLW9mZnNl dCcsCnJlc3BlY3RpdmVseTogKjEsICotMSwgKjIsIGFuZCAqLTIuICBJZiBPRkZTRVQgaXMgYSBm dW5jdGlvbiwgaXQgaXMKY2FsbGVkIHdpdGggYSBzaW5nbGUgYXJndW1lbnQgY29udGFpbmluZyB0 aGUgY29ucyBvZiB0aGUgc3ludGFjdGljCmVsZW1lbnQgc3ltYm9sIGFuZCB0aGUgcmVsYXRpdmUg aW5kZW50IHBvaW50LiAgVGhlIGZ1bmN0aW9uIHNob3VsZApyZXR1cm4gYW4gaW50ZWdlciBvZmZz ZXQuCgpIZXJlIGlzIHRoZSBjdXJyZW50IGxpc3Qgb2YgdmFsaWQgc3ludGFjdGljIGVsZW1lbnQg c3ltYm9sczoKCiBzdHJpbmcgICAgICAgICAgICAgICAgIC0tIGluc2lkZSBtdWx0aS1saW5lIHN0 cmluZwogYmxvY2stb3BlbiAgICAgICAgICAgICAtLSBzdGF0ZW1lbnQgYmxvY2sgb3BlbgogYmxv Y2stY2xvc2UgICAgICAgICAgICAtLSBzdGF0ZW1lbnQgYmxvY2sgY2xvc2UKIHN0YXRlbWVudCAg ICAgICAgICAgICAgLS0gYSBWSERMIHN0YXRlbWVudAogc3RhdGVtZW50LWNvbnQgICAgICAgICAt LSBhIGNvbnRpbnVhdGlvbiBvZiBhIFZIREwgc3RhdGVtZW50CiBzdGF0ZW1lbnQtYmxvY2staW50 cm8gIC0tIHRoZSBmaXJzdCBsaW5lIGluIGEgbmV3IHN0YXRlbWVudCBibG9jawogc3RhdGVtZW50 LWNhc2UtaW50cm8gICAtLSB0aGUgZmlyc3QgbGluZSBpbiBhIGNhc2UgYWx0ZXJuYXRpdmUgYmxv Y2sKIGNhc2UtYWx0ZXJuYXRpdmUgICAgICAgLS0gYSBjYXNlIHN0YXRlbWVudCBhbHRlcm5hdGl2 ZSBjbGF1c2UKIGNvbW1lbnQgICAgICAgICAgICAgICAgLS0gYSBsaW5lIGNvbnRhaW5pbmcgb25s eSBhIGNvbW1lbnQKIGFyZ2xpc3QtaW50cm8gICAgICAgICAgLS0gdGhlIGZpcnN0IGxpbmUgaW4g YW4gYXJndW1lbnQgbGlzdAogYXJnbGlzdC1jb250ICAgICAgICAgICAtLSBzdWJzZXF1ZW50IGFy Z3VtZW50IGxpc3QgbGluZXMgd2hlbiBubwogICAgICAgICAgICAgICAgICAgICAgICAgICBhcmd1 bWVudHMgZm9sbG93IG9uIHRoZSBzYW1lIGxpbmUgYXMgdGhlCiAgICAgICAgICAgICAgICAgICAg ICAgICAgIHRoZSBhcmdsaXN0IG9wZW5pbmcgcGFyZW4KIGFyZ2xpc3QtY29udC1ub25lbXB0eSAg LS0gc3Vic2VxdWVudCBhcmd1bWVudCBsaXN0IGxpbmVzIHdoZW4gYXQKICAgICAgICAgICAgICAg ICAgICAgICAgICAgbGVhc3Qgb25lIGFyZ3VtZW50IGZvbGxvd3Mgb24gdGhlIHNhbWUKICAgICAg ICAgICAgICAgICAgICAgICAgICAgbGluZSBhcyB0aGUgYXJnbGlzdCBvcGVuaW5nIHBhcmVuCiBh cmdsaXN0LWNsb3NlICAgICAgICAgIC0tIHRoZSBzb2xvIGNsb3NlIHBhcmVuIG9mIGFuIGFyZ3Vt ZW50IGxpc3QKIGVudGl0eSAgICAgICAgICAgICAgICAgLS0gaW5zaWRlIGFuIGVudGl0eSBkZWNs YXJhdGlvbgogY29uZmlndXJhdGlvbiAgICAgICAgICAtLSBpbnNpZGUgYSBjb25maWd1cmF0aW9u IGRlY2xhcmF0aW9uCiBwYWNrYWdlICAgICAgICAgICAgICAgIC0tIGluc2lkZSBhIHBhY2thZ2Ug ZGVjbGFyYXRpb24KIGFyY2hpdGVjdHVyZSAgICAgICAgICAgLS0gaW5zaWRlIGFuIGFyY2hpdGVj dHVyZSBib2R5CiBwYWNrYWdlLWJvZHkgICAgICAgICAgIC0tIGluc2lkZSBhIHBhY2thZ2UgYm9k eR8KKGRlZnZhciB2aGRsLW9mZnNldHMtYWxpc3QgKGNvcHktYWxpc3QgdmhkbC1vZmZzZXRzLWFs aXN0LWRlZmF1bHQpICgjJCAuIC00MjI3NSkpCiNANDEzICpFeHRyYSBvZmZzZXQgZm9yIGxpbmUg d2hpY2ggY29udGFpbnMgb25seSB0aGUgc3RhcnQgb2YgYSBjb21tZW50LgpDYW4gY29udGFpbiBh biBpbnRlZ2VyIG9yIGEgY29ucyBjZWxsIG9mIHRoZSBmb3JtOgoKIChOT04tQU5DSE9SRUQtT0ZG U0VUIC4gQU5DSE9SRUQtT0ZGU0VUKQoKV2hlcmUgTk9OLUFOQ0hPUkVELU9GRlNFVCBpcyB0aGUg YW1vdW50IG9mIG9mZnNldCBnaXZlbiB0bwpub24tY29sdW1uLXplcm8gYW5jaG9yZWQgY29tbWVu dC1vbmx5IGxpbmVzLCBhbmQgQU5DSE9SRUQtT0ZGU0VUIGlzCnRoZSBhbW91bnQgb2Ygb2Zmc2V0 IHRvIGdpdmUgY29sdW1uLXplcm8gYW5jaG9yZWQgY29tbWVudC1vbmx5IGxpbmVzLgpKdXN0IGFu IGludGVnZXIgYXMgdmFsdWUgaXMgZXF1aXZhbGVudCB0byAoPHZhbD4gLiAwKR8KKGRlZnZhciB2 aGRsLWNvbW1lbnQtb25seS1saW5lLW9mZnNldCAwICgjJCAuIC00NTUyMCkpCiNAMTE3ICpIb29r IGZvciB1c2VyIGRlZmluZWQgc3BlY2lhbCBpbmRlbnRhdGlvbiBhZGp1c3RtZW50cy4KVGhpcyBo b29rIGdldHMgY2FsbGVkIGFmdGVyIGEgbGluZSBpcyBpbmRlbnRlZCBieSB0aGUgbW9kZS4fCihk ZWZ2YXIgdmhkbC1zcGVjaWFsLWluZGVudC1ob29rIG5pbCAoIyQgLiAtNDU5OTQpKQojQDY4MyBT dHlsZXMgb2YgSW5kZW50YXRpb24uCkVsZW1lbnRzIG9mIHRoaXMgYWxpc3QgYXJlIG9mIHRoZSBm b3JtOgoKICAoU1RZTEUtU1RSSU5HIChWQVJJQUJMRSAuIFZBTFVFKSBbKFZBUklBQkxFIC4gVkFM VUUpIC4uLl0pCgp3aGVyZSBTVFlMRS1TVFJJTkcgaXMgYSBzaG9ydCBkZXNjcmlwdGl2ZSBzdHJp bmcgdXNlZCB0byBzZWxlY3QgYQpzdHlsZSwgVkFSSUFCTEUgaXMgYW55IGB2aGRsLW1vZGUnIHZh cmlhYmxlLCBhbmQgVkFMVUUgaXMgdGhlIGludGVuZGVkCnZhbHVlIGZvciB0aGF0IHZhcmlhYmxl IHdoZW4gdXNpbmcgdGhlIHNlbGVjdGVkIHN0eWxlLgoKVGhlcmUgaXMgb25lIHNwZWNpYWwgY2Fz ZSB3aGVuIFZBUklBQkxFIGlzIGB2aGRsLW9mZnNldHMtYWxpc3QnLiAgSW4gdGhpcwpjYXNlLCB0 aGUgVkFMVUUgaXMgYSBsaXN0IGNvbnRhaW5pbmcgZWxlbWVudHMgb2YgdGhlIGZvcm06CgogIChT WU5UQUNUSUMtU1lNQk9MIC4gVkFMVUUpCgphcyBkZXNjcmliZWQgaW4gYHZoZGwtb2Zmc2V0cy1h bGlzdCcuICBUaGVzZSBhcmUgcGFzc2VkIGRpcmVjdGx5IHRvCmB2aGRsLXNldC1vZmZzZXQnIHNv IHRoZXJlIGlzIG5vIG5lZWQgdG8gc2V0IGV2ZXJ5IHN5bnRhY3RpYyBzeW1ib2wgaW4KeW91ciBz dHlsZSwgb25seSB0aG9zZSB0aGF0IGFyZSBkaWZmZXJlbnQgZnJvbSB0aGUgZGVmYXVsdC4fCihk ZWZ2YXIgdmhkbC1zdHlsZS1hbGlzdCAnKCgiSUVFRSIgKHZoZGwtYmFzaWMtb2Zmc2V0IC4gNCkg KHZoZGwtb2Zmc2V0cy1hbGlzdCkpKSAoIyQgLiA0NjE2OSkpCihieXRlLWNvZGUgIlwzMDNcMzA0 CFwiXDIwNBUAXDMwNRlcMzA0XDMwNlwzMDcJXCJCXDIxMRoIQhAqXDMwM1wyMDciIFt2aGRsLXN0 eWxlLWFsaXN0IHZhcmxpc3QgZGVmYXVsdCBhc3NvYyAiRGVmYXVsdCIgKHZoZGwtaW5oaWJpdC1z dGFydHVwLXdhcm5pbmdzLXAgdmhkbC1zdHJpY3Qtc3ludGF4LXAgdmhkbC1lY2hvLXN5bnRhY3Rp Yy1pbmZvcm1hdGlvbi1wIHZoZGwtYmFzaWMtb2Zmc2V0IHZoZGwtb2Zmc2V0cy1hbGlzdCB2aGRs LWNvbW1lbnQtb25seS1saW5lLW9mZnNldCkgbWFwY2FyICNbKHZhcikgIghcMjExSkJcMjA3IiBb dmFyXSAyXV0gNSkKI0AzMCAqSG9vayBjYWxsZWQgYnkgYHZoZGwtbW9kZScuHwooZGVmdmFyIHZo ZGwtbW9kZS1ob29rIG5pbCAoIyQgLiAtNDcyNzApKQojQDQ0IFdhcm5pbmdzIHRvIHRlbGwgdGhl IHVzZXIgZHVyaW5nIHN0YXJ0IHVwLh8KKGRlZnZhciB2aGRsLXN0YXJ0dXAtd2FybmluZ3Mgbmls ICgjJCAuIDQ3MzQ3KSkKI0A1NyBQcmludCBvdXQgbWVzc2FnZXMgaW4gdmFyaWFibGUgYHZoZGwt c3RhcnR1cC13YXJuaW5ncycuHwooZGVmYWxpYXMgJ3ZoZGwtcHJpbnQtd2FybmluZ3MgI1tuaWwg IghcMjExGVwyMDMUAFwzMDJcMzAzCUBQIVwyMTAJQVwyMTERXDIwNAYAKQhHXDMwNFZcMjA1HwBc MzAyXDMwNSFcMjA3IiBbdmhkbC1zdGFydHVwLXdhcm5pbmdzIHdhcm5pbmdzIG1lc3NhZ2UgIldB Uk5JTkc6ICAiIDEgIldBUk5JTkc6ICBTZWUgd2FybmluZyBtZXNzYWdlcyBpbiAqTWVzc2FnZXMq IGJ1ZmZlci4iXSA0ICgjJCAuIDQ3NDQ0KV0pCiNANTMgQWRkIFNUUklORyB0byB3YXJuaW5nIGxp c3QgYHZoZGwtc3RhcnR1cC13YXJuaW5ncycuHwooZGVmYWxpYXMgJ3ZoZGwtYWRkLXdhcm5pbmcg I1soc3RyaW5nKSAiCAlCXDIxMRFcMjA3IiBbc3RyaW5nIHZoZGwtc3RhcnR1cC13YXJuaW5nc10g MiAoIyQgLiA0Nzc0MildKQooYnl0ZS1jb2RlICIIO1wyMDQLAFwzMDYQXDMwN1wzMTAhXDIxMAk8 XDIwNBYAXDMxMRFcMzA3XDMxMiFcMjEwXG5AR1wzMTNVXDIwMzkAXG5cMzE0G1wyMTEcXDIwMzUA XDMxNVxmQFwzMTZcIgtCE1xmQVwyMTEUXDIwNCYAC1wyMzcSKg1AR1wzMTNVXDIwM1xcAA1cMzE0 G1wyMTEcXDIwM1gAXDMxNVxmQFwzMTdcIgtCE1xmQVwyMTEUXDIwNEkAC1wyMzcVKlwzMTRcMjA3 IiBbdmhkbC1jb21waWxlciB2aGRsLXN0YW5kYXJkIHZoZGwtbW9kZWwtYWxpc3QgbmV3LWFsaXN0 IG9sZC1hbGlzdCB2aGRsLXByb2plY3QtYWxpc3QgIk1vZGVsU2ltIiB2aGRsLWFkZC13YXJuaW5n ICJWYXJpYWJsZSBgdmhkbC1jb21waWxlcicgaGFzIGNoYW5nZWQgZm9ybWF0OyBjdXN0b21pemUg YWdhaW4iICg4NyBuaWwpICJWYXJpYWJsZSBgdmhkbC1zdGFuZGFyZCcgaGFzIGNoYW5nZWQgZm9y bWF0OyBjdXN0b21pemUgYWdhaW4iIDMgbmlsIGFwcGVuZCAoIiIpICgiIildIDQpCiNANTAgQ2hl Y2sgaWYgU1RBTkRBUkQgaXMgc3BlY2lmaWVkIGFzIHVzZWQgc3RhbmRhcmQuHwooZGVmYWxpYXMg J3ZoZGwtc3RhbmRhcmQtcCAjWyhzdGFuZGFyZCkgIggJQD1cMjA2DwAICVwyMTEaQUApPlwyMDci IFtzdGFuZGFyZCB2aGRsLXN0YW5kYXJkIHhdIDMgKCMkIC4gNDgzOTApXSkKKGJ5dGUtY29kZSAi XDMwMFwzMDFcMzAyXDMwMyNcMjEwXDMwNFwzMDUhXDIwNyIgW3B1dCB2aGRsLXN0YW5kYXJkLXAg Ynl0ZS1vcHRpbWl6ZXIgYnl0ZS1jb21waWxlLWlubGluZS1leHBhbmQgcmVxdWlyZSBhc3NvY10g NCkKI0AxMDggRG8gd2hhdGV2ZXIgaXMgbmVjZXNzYXJ5IHRvIGtlZXAgdGhlIHJlZ2lvbiBhY3Rp dmUgaW4gWEVtYWNzLgpJZ25vcmUgYnl0ZS1jb21waWxlciB3YXJuaW5ncyB5b3UgbWlnaHQgc2Vl Lh8KKGRlZmFsaWFzICd2aGRsLWtlZXAtcmVnaW9uLWFjdGl2ZSAjW25pbCAiXDMwMVwzMDAhXDIw NQkAXDMwMlwyMTEQXDIwNyIgW3ptYWNzLXJlZ2lvbi1zdGF5cyBib3VuZHAgdF0gMiAoIyQgLiA0 ODY4NyldKQooYnl0ZS1jb2RlICJcMzAwXDMwMSFcMjA0XG4AXDMwMVwzMDJNXDIxMFwzMDBcMjA3 IiBbZmJvdW5kcCB3aWxkY2FyZC10by1yZWdleHAgI1sod2lsZGNhcmQpICJcMzA1XDMwNghcIhkI XDMwNwlPGghHGwlcMjAzPAAJC1dcMjAzPAAICUgcXG5cZlwzMTA9XDIwMyYAXDMxMVwyMDIzAFxm XDMxMj1cMjAzMABcMzEzXDIwMjMAXDMxNFxmIVASCVQRKVwyMDIRAFwzMTVcblwzMTZRK1wyMDci IFt3aWxkY2FyZCBpIHJlc3VsdCBsZW4gY2ggc3RyaW5nLW1hdGNoICJbKj9dIiAwIDQyICJbXgBd KiIgNjMgIlteAF0iIGNoYXItdG8tc3RyaW5nICJcXGAiICJcXCciXSAzICJTaW1wbGlmaWVkIHZl cnNpb24gb2YgYHdpbGRjYXJkLXRvLXJlZ2V4cCcgZnJvbSBFbWFjcycgYGZpbGVzLmVsJy4iXV0g MikKI0AyOCBLZXltYXAgZm9yIFZIREwgdGVtcGxhdGVzLh8KKGRlZnZhciB2aGRsLXRlbXBsYXRl LW1hcCBuaWwgKCMkIC4gNDkzMTMpKQojQDMzIEluaXRpYWxpemUgYHZoZGwtdGVtcGxhdGUtbWFw Jy4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1tYXAtaW5pdCAjW25pbCAiXDMwNCAQXDMwNQhc MzA2XDMwNyNcMjEwXDMwNQhcMzEwXDMxMSNcMjEwXDMwNQhcMzEyXDMxMyNcMjEwXDMwNQhcMzE0 XDMxNSNcMjEwXDMwNQhcMzE2XDMxNyNcMjEwXDMwNQhcMzIwXDMyMSNcMjEwXDMwNQhcMzIyXDMy MyNcMjEwXDMwNQhcMzI0XDMyNSNcMjEwXDMwNQhcMzI2XDMyNyNcMjEwXDMwNQhcMzMwXDMzMSNc MjEwXDMwNQhcMzMyXDMzMyNcMjEwXDMwNQhcMzM0XDMzNSNcMjEwXDMwNQhcMzM2XDMzNyNcMjEw XDMwNQhcMzQwXDM0MSNcMjEwXDMwNQhcMzQyXDM0MyNcMjEwXDMwNQhcMzQ0XDM0NSNcMjEwXDMw NQhcMzQ2XDM0NyNcMjEwXDMwNQhcMzUwXDM1MSNcMjEwXDMwNQhcMzUyXDM1MyNcMjEwXDMwNQhc MzU0XDM1NSNcMjEwXDMwNQhcMzU2XDM1NyNcMjEwXDMwNQhcMzYwXDM2MSNcMjEwXDMwNQhcMzYy XDM2MyNcMjEwXDMwNQhcMzY0XDM2NSNcMjEwXDMwNQhcMzY2XDM2NyNcMjEwXDMwNQhcMzcwXDM3 MSNcMjEwXDMwNQhcMzcyXDM3MyNcMjEwXDMwNQhcMzc0XDM3NSNcMjEwXDMwNQhcMzc2XDM3NyNc MjEwXDMwNQhcMjAxQABcMjAxQQAjXDIxMFwzMDUIXDIwMUIAXDIwMUMAI1wyMTBcMzA1CFwyMDFE AFwyMDFFACNcMjEwXDMwNQhcMjAxRgBcMjAxRwAjXDIxMFwzMDUIXDIwMUgAXDIwMUkAI1wyMTBc MzA1CFwyMDFKAFwyMDFLACNcMjEwXDMwNQhcMjAxTABcMjAxTQAjXDIxMFwzMDUIXDIwMU4AXDMw MCNcMjEwXDMwNQhcMjAxTwBcMjAxUAAjXDIxMFwzMDUIXDIwMVEAXDIwMVIAI1wyMTBcMzA1CFwy MDFTAFwyMDFUACNcMjEwXDMwNQhcMjAxVQBcMjAxVgAjXDIxMFwzMDUIXDIwMVcAXDIwMVgAI1wy MTBcMzA1CFwyMDFZAFwyMDFaACNcMjEwXDMwNQhcMjAxWwBcMjAxXFwAI1wyMTBcMzA1CFwyMDFd AFwyMDFeACNcMjEwXDMwNQhcMjAxXwBcMjAxYAAjXDIxMFwzMDUIXDIwMWEAXDIwMWIAI1wyMTBc MzA1CFwyMDFjAFwyMDFkACNcMjEwXDMwNQhcMjAxZQBcMjAxZgAjXDIxMFwzMDUIXDIwMWcAXDIw MWgAI1wyMTBcMzA1CFwyMDFpAFwyMDFqACNcMjEwXDMwNQhcMjAxawBcMjAxbAAjXDIxMFwzMDUI XDIwMW0AXDIwMW4AI1wyMTBcMzA1CFwyMDFvAFwyMDFwACNcMjEwXDMwNQhcMjAxcQBcMjAxcgAj XDIxMFwzMDUIXDIwMXMAXDIwMXQAI1wyMTBcMzA1CFwyMDF1AFwyMDF2ACNcMjEwXDMwNQhcMjAx dwBcMjAxeAAjXDIxMFwzMDUIXDIwMXkAXDIwMXoAI1wyMTBcMzA1CFwyMDF7AFwyMDF8ACNcMjEw XDMwNQhcMjAxfQBcMjAxfgAjXDIxMFwzMDUIXDIwMX8AXDIwMVwyMDAAI1wyMTBcMzA1CFwyMDFc MjAxAFwyMDFcMjAyACNcMjEwXDMwNQhcMjAxXDIwMwBcMjAxXDIwNAAjXDIxMFwzMDUIXDIwMVwy MDUAXDIwMVwyMDYAI1wyMTBcMzA1CFwyMDFcMjA3AFwyMDFcMjEwACNcMjEwXDMwNQhcMjAxXDIx MQBcMjAxXDIxMgAjXDIxMFwzMDUIXDIwMVwyMTMAXDIwMVwyMTQAI1wyMTBcMzA1CFwyMDFcMjE1 AFwyMDFcMjE2ACNcMjEwXDMwNQhcMjAxXDIxNwBcMjAxXDIyMAAjXDIxMFwzMDUIXDIwMVwyMjEA XDIwMVwyMjIAI1wyMTBcMzA1CFwyMDFcMjIzAFwyMDFcMjI0ACNcMjEwXDMwNQhcMjAxXDIyNQBc MjAxXDIyNgAjXDIxMFwyMDFcMjI3ABlcMjAxXDIyNwBcbkA9XDIwNnwCCVxuXDIxMRtBQCk+KVwy MDNcMzU2AlwzMDUIXDIwMVwyMzAAXDIwMVwyMzEAI1wyMTBcMzA1CFwyMDFcMjMyAFwyMDFcMjMz ACNcMjEwXDMwNQhcMjAxXDIzNABcMjAxXDIzNQAjXDIxMFwzMDUIXDIwMVwyMzYAXDIwMVwyMzcA I1wyMTBcMzA1CFwyMDFcMjQwAFwyMDFcMjQxACNcMjEwXDMwNQhcMjAxXDI0MgBcMjAxXDI0MwAj XDIxMFwzMDUIXDIwMVwyNDQAXDIwMVwyNDUAI1wyMTBcMzA1CFwyMDFcMjQ2AFwyMDFcMjQ3ACNc MjEwXDMwNQhcMjAxXDI1MABcMjAxXDI1MQAjXDIxMFwzMDUIXDIwMVwyNTIAXDIwMVwyNTMAI1wy MTBcMzA1CFwyMDFcMjU0AFwyMDFcMjU1ACNcMjEwXDIwMVwyNTYAGVwyMDFcMjU2AFxuQD1cMjA2 AwMJXG5cMjExG0FAKT4pXDIwNRoDXDMwNQhcMjAxXDI1NwBcMjAxXDI2MAAjXDIxMFwzMDUIXDIw MVwyNjEAXDIwMVwyNjIAI1wyMDciIFt2aGRsLXRlbXBsYXRlLW1hcCBzdGFuZGFyZCB2aGRsLXN0 YW5kYXJkIHggbWFrZS1zcGFyc2Uta2V5bWFwIGRlZmluZS1rZXkgImFsIiB2aGRsLXRlbXBsYXRl LWFsaWFzICJhciIgdmhkbC10ZW1wbGF0ZS1hcmNoaXRlY3R1cmUgImF0IiB2aGRsLXRlbXBsYXRl LWFzc2VydCAiYWQiIHZoZGwtdGVtcGxhdGUtYXR0cmlidXRlLWRlY2wgImFzIiB2aGRsLXRlbXBs YXRlLWF0dHJpYnV0ZS1zcGVjICJibCIgdmhkbC10ZW1wbGF0ZS1ibG9jayAiY2EiIHZoZGwtdGVt cGxhdGUtY2FzZS1pcyAiY2QiIHZoZGwtdGVtcGxhdGUtY29tcG9uZW50LWRlY2wgImNpIiB2aGRs LXRlbXBsYXRlLWNvbXBvbmVudC1pbnN0ICJjcyIgdmhkbC10ZW1wbGF0ZS1jb25kaXRpb25hbC1z aWduYWwtYXNzdCAiQ2IiIHZoZGwtdGVtcGxhdGUtYmxvY2stY29uZmlndXJhdGlvbiAiQ2MiIHZo ZGwtdGVtcGxhdGUtY29tcG9uZW50LWNvbmYgIkNkIiB2aGRsLXRlbXBsYXRlLWNvbmZpZ3VyYXRp b24tZGVjbCAiQ3MiIHZoZGwtdGVtcGxhdGUtY29uZmlndXJhdGlvbi1zcGVjICJjbyIgdmhkbC10 ZW1wbGF0ZS1jb25zdGFudCAiZGkiIHZoZGwtdGVtcGxhdGUtZGlzY29ubmVjdCAiZWwiIHZoZGwt dGVtcGxhdGUtZWxzZSAiZWkiIHZoZGwtdGVtcGxhdGUtZWxzaWYgImVuIiB2aGRsLXRlbXBsYXRl LWVudGl0eSAiZXgiIHZoZGwtdGVtcGxhdGUtZXhpdCAiZmkiIHZoZGwtdGVtcGxhdGUtZmlsZSAi ZmciIHZoZGwtdGVtcGxhdGUtZm9yLWdlbmVyYXRlICJmbCIgdmhkbC10ZW1wbGF0ZS1mb3ItbG9v cCAiBiIgdmhkbC10ZW1wbGF0ZS1mb290ZXIgImZiIiB2aGRsLXRlbXBsYXRlLWZ1bmN0aW9uLWJv ZHkgImZkIiB2aGRsLXRlbXBsYXRlLWZ1bmN0aW9uLWRlY2wgImdlIiB2aGRsLXRlbXBsYXRlLWdl bmVyaWMgImdkIiB2aGRsLXRlbXBsYXRlLWdyb3VwLWRlY2wgImd0IiB2aGRsLXRlbXBsYXRlLWdy b3VwLXRlbXBsYXRlICIIIiB2aGRsLXRlbXBsYXRlLWhlYWRlciAiaWciIHZoZGwtdGVtcGxhdGUt aWYtZ2VuZXJhdGUgIml0IiB2aGRsLXRlbXBsYXRlLWlmLXRoZW4gImxpIiB2aGRsLXRlbXBsYXRl LWxpYnJhcnkgImxvIiB2aGRsLXRlbXBsYXRlLWJhcmUtbG9vcCAiDSIgdmhkbC10ZW1wbGF0ZS1t b2RpZnkgIhQiIHZoZGwtdGVtcGxhdGUtaW5zZXJ0LWRhdGUgIm1hIiAibmUiIHZoZGwtdGVtcGxh dGUtbmV4dCAib3QiIHZoZGwtdGVtcGxhdGUtb3RoZXJzICJQZCIgdmhkbC10ZW1wbGF0ZS1wYWNr YWdlLWRlY2wgIlBiIiB2aGRsLXRlbXBsYXRlLXBhY2thZ2UtYm9keSAiKCIgdmhkbC10ZW1wbGF0 ZS1wYWlyZWQtcGFyZW5zICJwbyIgdmhkbC10ZW1wbGF0ZS1wb3J0ICJwYiIgdmhkbC10ZW1wbGF0 ZS1wcm9jZWR1cmUtYm9keSAicGQiIHZoZGwtdGVtcGxhdGUtcHJvY2VkdXJlLWRlY2wgInBjIiB2 aGRsLXRlbXBsYXRlLXByb2Nlc3MtY29tYiAicHMiIHZoZGwtdGVtcGxhdGUtcHJvY2Vzcy1zZXEg InJwIiB2aGRsLXRlbXBsYXRlLXJlcG9ydCAicnQiIHZoZGwtdGVtcGxhdGUtcmV0dXJuICJzcyIg dmhkbC10ZW1wbGF0ZS1zZWxlY3RlZC1zaWduYWwtYXNzdCAic2kiIHZoZGwtdGVtcGxhdGUtc2ln bmFsICJzdSIgdmhkbC10ZW1wbGF0ZS1zdWJ0eXBlICJ0eSIgdmhkbC10ZW1wbGF0ZS10eXBlICJ1 cyIgdmhkbC10ZW1wbGF0ZS11c2UgInZhIiB2aGRsLXRlbXBsYXRlLXZhcmlhYmxlICJ3YSIgdmhk bC10ZW1wbGF0ZS13YWl0ICJ3bCIgdmhkbC10ZW1wbGF0ZS13aGlsZS1sb29wICJ3aSIgdmhkbC10 ZW1wbGF0ZS13aXRoICJ3YyIgdmhkbC10ZW1wbGF0ZS1jbG9ja2VkLXdhaXQgIhBiIiB2aGRsLXRl bXBsYXRlLXBhY2thZ2UtbnVtZXJpYy1iaXQgIhBuIiB2aGRsLXRlbXBsYXRlLXBhY2thZ2UtbnVt ZXJpYy1zdGQgIhBzIiB2aGRsLXRlbXBsYXRlLXBhY2thZ2Utc3RkLWxvZ2ljLTExNjQgIhBBIiB2 aGRsLXRlbXBsYXRlLXBhY2thZ2Utc3RkLWxvZ2ljLWFyaXRoICIQTSIgdmhkbC10ZW1wbGF0ZS1w YWNrYWdlLXN0ZC1sb2dpYy1taXNjICIQUyIgdmhkbC10ZW1wbGF0ZS1wYWNrYWdlLXN0ZC1sb2dp Yy1zaWduZWQgIhBUIiB2aGRsLXRlbXBsYXRlLXBhY2thZ2Utc3RkLWxvZ2ljLXRleHRpbyAiEFUi IHZoZGwtdGVtcGxhdGUtcGFja2FnZS1zdGQtbG9naWMtdW5zaWduZWQgIhB0IiB2aGRsLXRlbXBs YXRlLXBhY2thZ2UtdGV4dGlvICIEbiIgdmhkbC10ZW1wbGF0ZS1kaXJlY3RpdmUtdHJhbnNsYXRl LW9uICIEZiIgdmhkbC10ZW1wbGF0ZS1kaXJlY3RpdmUtdHJhbnNsYXRlLW9mZiAiBE4iIHZoZGwt dGVtcGxhdGUtZGlyZWN0aXZlLXN5bnRoZXNpcy1vbiAiBEYiIHZoZGwtdGVtcGxhdGUtZGlyZWN0 aXZlLXN5bnRoZXNpcy1vZmYgIhEiIHZoZGwtdGVtcGxhdGUtc2VhcmNoLXByb21wdCBhbXMgImJy IiB2aGRsLXRlbXBsYXRlLWJyZWFrICJjdSIgdmhkbC10ZW1wbGF0ZS1jYXNlLXVzZSAiaXUiIHZo ZGwtdGVtcGxhdGUtaWYtdXNlICJsbSIgdmhkbC10ZW1wbGF0ZS1saW1pdCAibmEiIHZoZGwtdGVt cGxhdGUtbmF0dXJlICJwYSIgdmhkbC10ZW1wbGF0ZS1wcm9jZWR1cmFsICJxZiIgdmhkbC10ZW1w bGF0ZS1xdWFudGl0eS1mcmVlICJxYiIgdmhkbC10ZW1wbGF0ZS1xdWFudGl0eS1icmFuY2ggInFz IiB2aGRsLXRlbXBsYXRlLXF1YW50aXR5LXNvdXJjZSAic24iIHZoZGwtdGVtcGxhdGUtc3VibmF0 dXJlICJ0ZSIgdmhkbC10ZW1wbGF0ZS10ZXJtaW5hbCBtYXRoICIQYyIgdmhkbC10ZW1wbGF0ZS1w YWNrYWdlLW1hdGgtY29tcGxleCAiEHIiIHZoZGwtdGVtcGxhdGUtcGFja2FnZS1tYXRoLXJlYWxd IDQgKCMkIC4gNDkzOTApXSkKKHZoZGwtdGVtcGxhdGUtbWFwLWluaXQpCiNAMTc3IEdlbmVyYXRl IGEgTGlzcCBmdW5jdGlvbiBuYW1lLgpQUkVGSVgsIFNUUklORyBhbmQgb3B0aW9uYWwgUE9TVEZJ WCBhcmUgY29uY2F0ZW5hdGVkIGJ5ICctJyBhbmQgc3BhY2VzIGluClNUUklORyBhcmUgcmVwbGFj ZWQgYnkgYC0nIGFuZCBzdWJzdHJpbmdzIGFyZSBjb252ZXJ0ZWQgdG8gbG93ZXIgY2FzZS4fCihk ZWZhbGlhcyAndmhkbC1mdW5jdGlvbi1uYW1lICNbKHByZWZpeCBzdHJpbmcgJm9wdGlvbmFsIHBv c3RmaXgpICIIGVwzMDRcMzA1XG5cIlwyMDMcAAlcMzA2XG5cMzA3XDMxMFwyMjVPXDIyN1ERXG5c MzExXDIyNFwzMTJPElwyMDICAAtcMjAzJQAJXDMwNgtREVwzMTMJISlcMjA3IiBbcHJlZml4IG5h bWUgc3RyaW5nIHBvc3RmaXggc3RyaW5nLW1hdGNoICJcXChcXHcrXFwpXFxzLSpcXCguKlxcKSIg Ii0iIDAgMSAyIG5pbCBpbnRlcm5dIDUgKCMkIC4gNTQzMTMpXSkKI0AyNSBLZXltYXAgZm9yIFZI REwgbW9kZWxzLh8KKGRlZnZhciB2aGRsLW1vZGVsLW1hcCBuaWwgKCMkIC4gNTQ3NjQpKQojQDMw IEluaXRpYWxpemUgYHZoZGwtbW9kZWwtbWFwJy4fCihkZWZhbGlhcyAndmhkbC1tb2RlbC1tYXAt aW5pdCAjW25pbCAiXDMwNCAQCVwzMDUaXDIxMRtcMjA1XCIAC0ASXDMwNghcMzA3XG44XDMxMFwz MTFcbkBcIiNcMjEwC0FcMjExE1wyMDQLAFwzMDUqXDIwNyIgW3ZoZGwtbW9kZWwtbWFwIHZoZGwt bW9kZWwtYWxpc3QgbW9kZWwgbW9kZWwtYWxpc3QgbWFrZS1zcGFyc2Uta2V5bWFwIG5pbCBkZWZp bmUta2V5IDIgdmhkbC1mdW5jdGlvbi1uYW1lICJ2aGRsLW1vZGVsIl0gNyAoIyQgLiA1NDgzNSld KQoodmhkbC1tb2RlbC1tYXAtaW5pdCkKI0AyMyBLZXltYXAgZm9yIFZIREwgTW9kZS4fCihkZWZ2 YXIgdmhkbC1tb2RlLW1hcCBuaWwgKCMkIC4gNTUxNDgpKQojQDI5IEluaXRpYWxpemUgYHZoZGwt bW9kZS1tYXAnLh8KKGRlZmFsaWFzICd2aGRsLW1vZGUtbWFwLWluaXQgI1tuaWwgIlwzMDYgEFwz MDcIXDMxMAkjXDIxMFwzMDcIXDMxMVxuI1wyMTBcMzA3CFwzMTJcMzEzI1wyMTBcMzA3CFwzMTRc MzE1I1wyMTBcMzA3CFwzMTZcMzE3I1wyMTBcMzA3CFwzMjBcMzIxI1wyMTBcMzA3CFwzMjJcMzIz I1wyMTBcMzA3CFwzMjRcMzI1I1wyMTBcMzA3CFwzMjZcMzI3I1wyMTBcMzA3CFwzMzBcMzMxI1wy MTBcMzA3CFwzMzJcMzMzI1wyMTBcMzA3CFwzMzRcMzM1I1wyMTBcMzA3CFwzMzZcMzM3I1wyMTBc MzQwXDM0MQtcIlwyMDReAFwzMDcIXDM0MlwzNDMjXDIxMFwzMDcIXDM0NFwzNDUjXDIxMFwzMDcI XDM0NlwzNDcjXDIxMFwzMDcIXDM1MFwzNTEjXDIxMFwzMDcIXDM1MlwzNTMjXDIxMFwzMDcIXDM1 NFwzNTUjXDIxMFwzMDcIXDM1NlwzNTUjXDIxMFwzMDcIXDM1N1wzNjAjXDIxMFwzMDcIXDM2MVwz NjIjXDIxMFwzMDcIXDM2M1wzNjQjXDIxMFwzMDcIXDM2NVwzNjYjXDIxMFwzMDcIXDM2N1wzNzAj XDIxMFwzNDBcMzQxC1wiXDIwM1wyNjAAXDMwNwhcMzcxXDM3MiNcMjEwXDIwMlwyNjYAXDMwNwhc MzczXDM3MiNcMjEwXDMwNwhcMzc0XDM3NSNcMjEwXDMwNwhcMzc2XDM3NyNcMjEwXDMwNwhcMjAx QgBcMjAxQwAjXDIxMFwzMDcIXDIwMUQAXDIwMUUAI1wyMTBcMzA3CFwyMDFGAFwyMDFHACNcMjEw XDMwNwhcMjAxSABcMjAxSQAjXDIxMFwzMDcIXDIwMUoAXDIwMUsAI1wyMTBcMzA3CFwyMDFMAFwy MDFNACNcMjEwXDMwNwhcMjAxTgBcMjAxTwAjXDIxMFwzMDcIXDIwMVAAXDIwMVEAI1wyMTBcMzA3 CFwyMDFSAFwyMDFTACNcMjEwXDMwNwhcMjAxVABcMjAxVQAjXDIxMFwzMDcIXDIwMVYAXDIwMVcA I1wyMTBcMzA3CFwyMDFYAFwyMDFZACNcMjEwXDMwNwhcMjAxWgBcMjAxWwAjXDIxMFwzMDcIXDIw MVxcAFwyMDFdACNcMjEwXDMwNwhcMjAxXgBcMjAxXwAjXDIxMFwzMDcIXDIwMWAAXDIwMWEAI1wy MTBcMzA3CFwyMDFiAFwyMDFjACNcMjEwXDMwNwhcMjAxZABcMjAxZQAjXDIxMFwzMDcIXDIwMWYA XDIwMWcAI1wyMTBcMzA3CFwyMDFoAFwyMDFpACNcMjEwXDMwNwhcMjAxagBcMjAxawAjXDIxMFwz MDcIXDIwMWwAXDIwMW0AI1wyMTBcMzA3CFwyMDFuAFwyMDFvACNcMjEwXDMwNwhcMjAxcABcMjAx cQAjXDIxMFwzMDcIXDIwMXIAXDIwMXMAI1wyMTBcMzA3CFwyMDF0AFwyMDF1ACNcMjEwXDMwNwhc MjAxdgBcMjAxdwAjXDIxMFwzMDcIXDIwMXgAXDIwMXkAI1wyMTBcMzA3CFwyMDF6AFwyMDF7ACNc MjEwXDMwNwhcMjAxfABcMjAxfQAjXDIxMFwzMDcIXDIwMX4AXDIwMX8AI1wyMTBcMzA3CFwyMDFc MjAwAFwyMDFcMjAxACNcMjEwXDMwNwhcMjAxXDIwMgBcMjAxXDIwMwAjXDIxMFxmXDIwMx0CXDMw NwhcMjAxXDIwNABcMjAxXDIwNQAjXDIxMFwyMDInAlwzMDcIXDIwMVwyMDQAXDIwMUkAI1wyMTBc MzA3CFwyMDFcMjA2AFwyMDFcMjA3ACNcMjEwXDMwNwhcMjAxXDIxMABcMjAxXDIxMQAjXDIxMFwz MDcIXDIwMVwyMTIAXDIwMVwyMTMAI1wyMTBcMzA3CFwyMDFcMjE0AFwyMDFcMjE1ACNcMjEwXDMw NwhcMjAxXDIxNgBcMjAxXDIxNwAjXDIxMFwzMDcIXDIwMVwyMjAAXDIwMVwyMjEAI1wyMTBcMzA3 CFwyMDFcMjIyAFwyMDFcMjIzACNcMjEwXDMwNwhcMjAxXDIyNABcMjAxXDIyNQAjXDIxMFwyMDFc MjI2AB1cMjAxXDIyNgAOQEA9XDIwNlwyMTcCDQ5AXDIxMR5BQUApPilcMjA1XDIzNAJcMzA3CFwy MDFcMjI3AFwyMDFcMjMwACNcMjA3IiBbdmhkbC1tb2RlLW1hcCB2aGRsLXRlbXBsYXRlLW1hcCB2 aGRsLW1vZGVsLW1hcCBlbWFjcy12ZXJzaW9uIHZoZGwtaW50ZWxsaWdlbnQtdGFiIHN0YW5kYXJk IG1ha2Utc3BhcnNlLWtleW1hcCBkZWZpbmUta2V5ICIDFCIgIgMNIiAiXDM0MSIgdmhkbC1iZWdp bm5pbmctb2Ytc3RhdGVtZW50ICJcMzQ1IiB2aGRsLWVuZC1vZi1zdGF0ZW1lbnQgIlwyMDYiIHZo ZGwtZm9yd2FyZC1zZXhwICJcMjAyIiB2aGRsLWJhY2t3YXJkLXNleHAgIlwyMjUiIHZoZGwtYmFj a3dhcmQtdXAtbGlzdCAiXDIwMSIgdmhkbC1iZWdpbm5pbmctb2YtZGVmdW4gIlwyMDUiIHZoZGwt ZW5kLW9mLWRlZnVuICJcMjEwIiB2aGRsLW1hcmstZGVmdW4gIlwyMjEiIHZoZGwtaW5kZW50LXNl eHAgW2JhY2tzcGFjZV0gYmFja3dhcmQtZGVsZXRlLWNoYXItdW50YWJpZnkgW2RlbGV0ZV0gZGVs ZXRlLWNoYXIgc3RyaW5nLW1hdGNoICJYRW1hY3MiIFtNLWRlbGV0ZV0ga2lsbC13b3JkICIDBSIg dmhkbC1lbGVjdHJpYy1tb2RlICIDEyIgdmhkbC1zdHV0dGVyLW1vZGUgIgMLIiB2aGRsLWNvbXBp bGUgIgNcMjEzIiB2aGRsLW1ha2UgIgMQFyIgdmhkbC1wb3J0LWNvcHkgIgMQXDM2NyIgIgMQBSIg dmhkbC1wb3J0LXBhc3RlLWVudGl0eSAiAxADIiB2aGRsLXBvcnQtcGFzdGUtY29tcG9uZW50ICID EAkiIHZoZGwtcG9ydC1wYXN0ZS1pbnN0YW5jZSAiAxATIiB2aGRsLXBvcnQtcGFzdGUtc2lnbmFs cyAiAxBcMzQzIiB2aGRsLXBvcnQtcGFzdGUtY29uc3RhbnRzICIDEFwzNDciIHZoZGwtcG9ydC1w YXN0ZS1nZW5lcmljLW1hcCAiAxAHIiAiAxAUIiB2aGRsLXBvcnQtcGFzdGUtdGVzdGJlbmNoICID EAYiIHZoZGwtcG9ydC1mbGF0dGVuIHZoZGwtc3RhbmRhcmQgeCAiAwMiIHZoZGwtY29tbWVudC11 bmNvbW1lbnQtcmVnaW9uICIDLSIgdmhkbC1jb21tZW50LWFwcGVuZC1pbmxpbmUgIgNcMjU1IiB2 aGRsLWNvbW1lbnQtZGlzcGxheS1saW5lICIDXDIxMSIgdmhkbC1pbmRlbnQtbGluZSAiXDIzNCIg dmhkbC1pbmRlbnQtcmVnaW9uICIDASIgdmhkbC1hbGlnbi1ncm91cCAiAxIBIiB2aGRsLWFsaWdu LW5vaW5kZW50LXJlZ2lvbiAiA1wyMDEiIHZoZGwtYWxpZ24taW5saW5lLWNvbW1lbnQtZ3JvdXAg IgMSXDIwMSIgdmhkbC1hbGlnbi1pbmxpbmUtY29tbWVudC1yZWdpb24gIgMXIiB2aGRsLWZpeHVw LXdoaXRlc3BhY2UtcmVnaW9uICIDXGYXIiB2aGRsLWxpbmUta2lsbCAiA1xmXDM2NyIgdmhkbC1s aW5lLWNvcHkgIgNcZhkiIHZoZGwtbGluZS15YW5rICIDXGYJIiB2aGRsLWxpbmUtZXhwYW5kICID XGYOIiB2aGRsLWxpbmUtdHJhbnNwb3NlLW5leHQgIgNcZhAiIHZoZGwtbGluZS10cmFuc3Bvc2Ut cHJldmlvdXMgIgNcZg8iIHZoZGwtbGluZS1vcGVuICIDXGYHIiBnb3RvLWxpbmUgIgNcZgMiIHZo ZGwtY29tbWVudC11bmNvbW1lbnQtbGluZSAiAxIVIiB2aGRsLWZpeC1jYXNlLXJlZ2lvbiAiAxUi IHZoZGwtZml4LWNhc2UtYnVmZmVyICIDBiIgdmhkbC1mb250aWZ5LWJ1ZmZlciAiAxgiIHZoZGwt c2hvdy1zeW50YWN0aWMtaW5mb3JtYXRpb24gIgMIIiB2aGRsLWRvYy1tb2RlICIDFiIgdmhkbC12 ZXJzaW9uICIDEgIiIHZoZGwtYmVhdXRpZnktcmVnaW9uICIDAiIgdmhkbC1iZWF1dGlmeS1idWZm ZXIgIlwyMTEiIHRhYi10by10YWItc3RvcCAiAwkDIiB2aGRsLXRlbXBsYXRlLWluc2VydC1jb25z dHJ1Y3QgIgMJECIgdmhkbC10ZW1wbGF0ZS1pbnNlcnQtcGFja2FnZSAiAwkEIiB2aGRsLXRlbXBs YXRlLWluc2VydC1kaXJlY3RpdmUgIgMJDSIgdmhkbC1tb2RlbC1pbnNlcnQgIiAiIHZoZGwtZWxl Y3RyaWMtc3BhY2UgIgkiIHZoZGwtZWxlY3RyaWMtdGFiICINIiB2aGRsLWVsZWN0cmljLXJldHVy biAiLSIgdmhkbC1lbGVjdHJpYy1kYXNoICJbIiB2aGRsLWVsZWN0cmljLW9wZW4tYnJhY2tldCAi XSIgdmhkbC1lbGVjdHJpYy1jbG9zZS1icmFja2V0ICInIiB2aGRsLWVsZWN0cmljLXF1b3RlICI7 IiB2aGRsLWVsZWN0cmljLXNlbWljb2xvbiAiLCIgdmhkbC1lbGVjdHJpYy1jb21tYSAiLiIgdmhk bC1lbGVjdHJpYy1wZXJpb2QgYW1zICI9IiB2aGRsLWVsZWN0cmljLWVxdWFsXSA0ICgjJCAuIDU1 MjE2KV0pCih2aGRsLW1vZGUtbWFwLWluaXQpCiNANDIgS2V5bWFwIGZvciBtaW5pYnVmZmVyIHVz ZWQgaW4gVkhETCBNb2RlLh8KKGRlZnZhciB2aGRsLW1pbmlidWZmZXItbG9jYWwtbWFwIChjb3B5 LWtleW1hcCBtaW5pYnVmZmVyLWxvY2FsLW1hcCkgKCMkIC4gNTkwODUpKQooYnl0ZS1jb2RlICII XDIwM1xuAFwzMDIJXDMwM1wzMDQjXDIxMFwzMDVcMzA2XDMwN1wiXDIwNyIgW3ZoZGwtd29yZC1j b21wbGV0aW9uLWluLW1pbmlidWZmZXIgdmhkbC1taW5pYnVmZmVyLWxvY2FsLW1hcCBkZWZpbmUt a2V5ICIJIiB2aGRsLW1pbmlidWZmZXItdGFiIG1hcGNhciAjWyhzeW0pICJcMzAxCFwzMDJcMzAz I1wyMTBcMzAxCFwzMDRcMzAzI1wyMDciIFtzeW0gcHV0IGRlbGV0ZS1zZWxlY3Rpb24gdCBwZW5k aW5nLWRlbGV0ZV0gNF0gKHZoZGwtZWxlY3RyaWMtc3BhY2UgdmhkbC1lbGVjdHJpYy10YWIgdmhk bC1lbGVjdHJpYy1yZXR1cm4gdmhkbC1lbGVjdHJpYy1kYXNoIHZoZGwtZWxlY3RyaWMtb3Blbi1i cmFja2V0IHZoZGwtZWxlY3RyaWMtY2xvc2UtYnJhY2tldCB2aGRsLWVsZWN0cmljLXF1b3RlIHZo ZGwtZWxlY3RyaWMtc2VtaWNvbG9uIHZoZGwtZWxlY3RyaWMtY29tbWEgdmhkbC1lbGVjdHJpYy1w ZXJpb2QgdmhkbC1lbGVjdHJpYy1lcXVhbCldIDQpCiNANDMgU3ludGF4IHRhYmxlIHVzZWQgaW4g YHZoZGwtbW9kZScgYnVmZmVycy4fCihkZWZ2YXIgdmhkbC1tb2RlLXN5bnRheC10YWJsZSBuaWwg KCMkIC4gNTk3MTUpKQojQDM4IEluaXRpYWxpemUgYHZoZGwtbW9kZS1zeW50YXgtdGFibGUnLh8K KGRlZmFsaWFzICd2aGRsLW1vZGUtc3ludGF4LXRhYmxlLWluaXQgI1tuaWwgIlwzMDIgEFwzMDNc MzA0XDMwNQgjXDIxMFwzMDNcMzA2XDMwNQgjXDIxMFwzMDNcMzA3XDMwNQgjXDIxMFwzMDNcMzEw XDMwNQgjXDIxMFwzMDNcMzExXDMwNQgjXDIxMFwzMDNcMzEyXDMwNQgjXDIxMFwzMDNcMzEzXDMw NQgjXDIxMFwzMDNcMzE0XDMwNQgjXDIxMFwzMDNcMzE1XDMwNQgjXDIxMFwzMDNcMzE2XDMwNQgj XDIxMFwzMDNcMzE3XDMwNQgjXDIxMFwzMDNcMzIwXDMwNQgjXDIxMFwzMDNcMzIxXDMwNQgjXDIx MFwzMDNcMzIyXDMwNQgjXDIxMFwzMDNcMzIzXDMwNQgjXDIxMFwzMDNcMzI0XDMwNQgjXDIxMFwz MDNcMzI1XDMyNggjXDIxMAlcMjAzcwBcMzAzXDMyN1wzMzAII1wyMTBcMzAzXDMzMVwzMzIII1wy MTBcMzAzXDMzM1wzMzQII1wyMTBcMzAzXDMzNVwzMzQII1wyMTBcMzAzXDMzNlwzMzcII1wyMTBc MzAzXDM0MFwzNDEII1wyMTBcMzAzXDM0MlwzNDMII1wyMTBcMzAzXDM0NFwzNDUII1wyMTBcMzAz XDM0NlwzNDcII1wyMTBcMzAzXDM1MFwzNTEII1wyMDciIFt2aGRsLW1vZGUtc3ludGF4LXRhYmxl IHZoZGwtdW5kZXJzY29yZS1pcy1wYXJ0LW9mLXdvcmQgbWFrZS1zeW50YXgtdGFibGUgbW9kaWZ5 LXN5bnRheC1lbnRyeSAzNSAiLiIgMzYgMzcgMzggMzkgNDIgNDMgNDYgNDcgNTggNTkgNjAgNjEg NjIgOTIgMTI0IDM0ICJcIiIgOTUgInciIDQ1ICIuIDEyIiAxMCAiPiIgMTMgNDAgIigpIiA0MSAi KSgiIDkxICIoXSIgOTMgIilbIiAxMjMgIih9IiAxMjUgIil7Il0gNCAoIyQgLiA1OTgxMildKQoo dmhkbC1tb2RlLXN5bnRheC10YWJsZS1pbml0KQojQDY1IEV4ZWN1dGUgQk9EWSB3aXRoIHN5bnRh eCB0YWJsZSB0aGF0IGluY2x1ZGVzIGBfJyBpbiB3b3JkIGNsYXNzLh8KKGRlZmFsaWFzICd2aGRs LWV4dC1zeW50YXgtdGFibGUgJyhtYWNybyAuICNbKCZyZXN0IGJvZHkpICJcMzAxXDMwMlwzMDNc MzA0XDMwNVwzMDYIQkVcMzA3QkJCQlwyMDciIFtib2R5IGxldCAocmVzdWx0KSAobW9kaWZ5LXN5 bnRheC1lbnRyeSA5NSAidyIgdmhkbC1tb2RlLXN5bnRheC10YWJsZSkgc2V0cSByZXN1bHQgcHJv Z24gKCh3aGVuIChub3QgdmhkbC11bmRlcnNjb3JlLWlzLXBhcnQtb2Ytd29yZCkgKG1vZGlmeS1z eW50YXgtZW50cnkgOTUgIl8iIHZoZGwtbW9kZS1zeW50YXgtdGFibGUpKSByZXN1bHQpXSA3ICgj JCAuIDYwNjgyKV0pKQojQDU5IEJ1ZmZlciBsb2NhbCB2YXJpYWJsZSBjb250YWluaW5nIHN5bnRh Y3RpYyBhbmFseXNpcyBsaXN0Lh8KKGRlZnZhciB2aGRsLXN5bnRhY3RpYy1jb250ZXh0IG5pbCAo IyQgLiA2MTA2NikpCihtYWtlLXZhcmlhYmxlLWJ1ZmZlci1sb2NhbCAndmhkbC1zeW50YWN0aWMt Y29udGV4dCkKI0A0NSBBYmJyZXYgdGFibGUgdG8gdXNlIGluIGB2aGRsLW1vZGUnIGJ1ZmZlcnMu HwooZGVmdmFyIHZoZGwtbW9kZS1hYmJyZXYtdGFibGUgbmlsICgjJCAuIDYxMjMyKSkKI0AzOCBJ bml0aWFsaXplIGB2aGRsLW1vZGUtYWJicmV2LXRhYmxlJy4fCihkZWZhbGlhcyAndmhkbC1tb2Rl LWFiYnJldi10YWJsZS1pbml0ICNbbmlsICIIXDIwMwgAXDMwNgghXDIxMFwzMDdcMzAwXDMxMFwz MTEJPlwyMDUSAFwzMTJcMzExCT5cMjA1LgBcMzEzGlwzMTMLQD1cMjA2KQBcbgtcMjExHEFAKT4p XDIwNS4AXDMxNFwzMTUJPlwyMDVsAA1cMzE2XDIxMR4VHhZcMjExHhdcMjAzaQBcMzE3DhdAOFwy MTEWFVwzMjBcMjMyXDIwNGAADhVcMzIwXDMyMVwzMjIOF0BAXDMyMyNcMzI0Rg4WQhYWDhdBXDIx MRYXXDIwNEEADhYrI1wiXDIwNyIgW3ZoZGwtbW9kZS1hYmJyZXYtdGFibGUgdmhkbC1lbGVjdHJp Yy1rZXl3b3JkcyBzdGFuZGFyZCB2aGRsLXN0YW5kYXJkIHggdmhkbC1tb2RlbC1hbGlzdCBjbGVh ci1hYmJyZXYtdGFibGUgZGVmaW5lLWFiYnJldi10YWJsZSBhcHBlbmQgdmhkbCAoKCItLSIgIiIg dmhkbC10ZW1wbGF0ZS1kaXNwbGF5LWNvbW1lbnQtaG9vayAwKSAoImFicyIgIiIgdmhkbC10ZW1w bGF0ZS1kZWZhdWx0LWhvb2sgMCkgKCJhY2Nlc3MiICIiIHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1o b29rIDApICgiYWZ0ZXIiICIiIHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1ob29rIDApICgiYWxpYXMi ICIiIHZoZGwtdGVtcGxhdGUtYWxpYXMtaG9vayAwKSAoImFsbCIgIiIgdmhkbC10ZW1wbGF0ZS1k ZWZhdWx0LWhvb2sgMCkgKCJhbmQiICIiIHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1ob29rIDApICgi YXJjaCIgIiIgdmhkbC10ZW1wbGF0ZS1hcmNoaXRlY3R1cmUtaG9vayAwKSAoImFyY2hpdGVjdHVy ZSIgIiIgdmhkbC10ZW1wbGF0ZS1hcmNoaXRlY3R1cmUtaG9vayAwKSAoImFycmF5IiAiIiB2aGRs LXRlbXBsYXRlLWRlZmF1bHQtaG9vayAwKSAoImFzc2VydCIgIiIgdmhkbC10ZW1wbGF0ZS1hc3Nl cnQtaG9vayAwKSAoImF0dHIiICIiIHZoZGwtdGVtcGxhdGUtYXR0cmlidXRlLWhvb2sgMCkgKCJh dHRyaWJ1dGUiICIiIHZoZGwtdGVtcGxhdGUtYXR0cmlidXRlLWhvb2sgMCkgKCJiZWdpbiIgIiIg dmhkbC10ZW1wbGF0ZS1kZWZhdWx0LWluZGVudC1ob29rIDApICgiYmxvY2siICIiIHZoZGwtdGVt cGxhdGUtYmxvY2staG9vayAwKSAoImJvZHkiICIiIHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1ob29r IDApICgiYnVmZmVyIiAiIiB2aGRsLXRlbXBsYXRlLWRlZmF1bHQtaG9vayAwKSAoImJ1cyIgIiIg dmhkbC10ZW1wbGF0ZS1kZWZhdWx0LWhvb2sgMCkgKCJjYXNlIiAiIiB2aGRsLXRlbXBsYXRlLWNh c2UtaG9vayAwKSAoImNvbXAiICIiIHZoZGwtdGVtcGxhdGUtY29tcG9uZW50LWhvb2sgMCkgKCJj b21wb25lbnQiICIiIHZoZGwtdGVtcGxhdGUtY29tcG9uZW50LWhvb2sgMCkgKCJjb25kIiAiIiB2 aGRsLXRlbXBsYXRlLWNvbmRpdGlvbmFsLXNpZ25hbC1hc3N0LWhvb2sgMCkgKCJjb25kaXRpb25h bCIgIiIgdmhkbC10ZW1wbGF0ZS1jb25kaXRpb25hbC1zaWduYWwtYXNzdC1ob29rIDApICgiY29u ZiIgIiIgdmhkbC10ZW1wbGF0ZS1jb25maWd1cmF0aW9uLWhvb2sgMCkgKCJjb25maWd1cmF0aW9u IiAiIiB2aGRsLXRlbXBsYXRlLWNvbmZpZ3VyYXRpb24taG9vayAwKSAoImNvbnMiICIiIHZoZGwt dGVtcGxhdGUtY29uc3RhbnQtaG9vayAwKSAoImNvbnN0YW50IiAiIiB2aGRsLXRlbXBsYXRlLWNv bnN0YW50LWhvb2sgMCkgKCJkaXNjb25uZWN0IiAiIiB2aGRsLXRlbXBsYXRlLWRpc2Nvbm5lY3Qt aG9vayAwKSAoImRvd250byIgIiIgdmhkbC10ZW1wbGF0ZS1kZWZhdWx0LWhvb2sgMCkgKCJlbHNl IiAiIiB2aGRsLXRlbXBsYXRlLWVsc2UtaG9vayAwKSAoImVsc2VpZiIgIiIgdmhkbC10ZW1wbGF0 ZS1lbHNpZi1ob29rIDApICgiZWxzaWYiICIiIHZoZGwtdGVtcGxhdGUtZWxzaWYtaG9vayAwKSAo ImVuZCIgIiIgdmhkbC10ZW1wbGF0ZS1kZWZhdWx0LWluZGVudC1ob29rIDApICgiZW50aXR5IiAi IiB2aGRsLXRlbXBsYXRlLWVudGl0eS1ob29rIDApICgiZXhpdCIgIiIgdmhkbC10ZW1wbGF0ZS1l eGl0LWhvb2sgMCkgKCJmaWxlIiAiIiB2aGRsLXRlbXBsYXRlLWZpbGUtaG9vayAwKSAoImZvciIg IiIgdmhkbC10ZW1wbGF0ZS1mb3ItaG9vayAwKSAoImZ1bmMiICIiIHZoZGwtdGVtcGxhdGUtZnVu Y3Rpb24taG9vayAwKSAoImZ1bmN0aW9uIiAiIiB2aGRsLXRlbXBsYXRlLWZ1bmN0aW9uLWhvb2sg MCkgKCJnZW5lcmljIiAiIiB2aGRsLXRlbXBsYXRlLWdlbmVyaWMtaG9vayAwKSAoImdyb3VwIiAi IiB2aGRsLXRlbXBsYXRlLWdyb3VwLWhvb2sgMCkgKCJndWFyZGVkIiAiIiB2aGRsLXRlbXBsYXRl LWRlZmF1bHQtaG9vayAwKSAoImlmIiAiIiB2aGRsLXRlbXBsYXRlLWlmLWhvb2sgMCkgKCJpbXB1 cmUiICIiIHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1ob29rIDApICgiaW4iICIiIHZoZGwtdGVtcGxh dGUtZGVmYXVsdC1ob29rIDApICgiaW5lcnRpYWwiICIiIHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1o b29rIDApICgiaW5vdXQiICIiIHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1ob29rIDApICgiaW5zdCIg IiIgdmhkbC10ZW1wbGF0ZS1pbnN0YW5jZS1ob29rIDApICgiaW5zdGFuY2UiICIiIHZoZGwtdGVt cGxhdGUtaW5zdGFuY2UtaG9vayAwKSAoImlzIiAiIiB2aGRsLXRlbXBsYXRlLWRlZmF1bHQtaG9v ayAwKSAoImxhYmVsIiAiIiB2aGRsLXRlbXBsYXRlLWRlZmF1bHQtaG9vayAwKSAoImxpYnJhcnki ICIiIHZoZGwtdGVtcGxhdGUtbGlicmFyeS1ob29rIDApICgibGlua2FnZSIgIiIgdmhkbC10ZW1w bGF0ZS1kZWZhdWx0LWhvb2sgMCkgKCJsaXRlcmFsIiAiIiB2aGRsLXRlbXBsYXRlLWRlZmF1bHQt aG9vayAwKSAoImxvb3AiICIiIHZoZGwtdGVtcGxhdGUtYmFyZS1sb29wLWhvb2sgMCkgKCJtYXAi ICIiIHZoZGwtdGVtcGxhdGUtbWFwLWhvb2sgMCkgKCJtb2QiICIiIHZoZGwtdGVtcGxhdGUtZGVm YXVsdC1ob29rIDApICgibmFuZCIgIiIgdmhkbC10ZW1wbGF0ZS1kZWZhdWx0LWhvb2sgMCkgKCJu ZXciICIiIHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1ob29rIDApICgibmV4dCIgIiIgdmhkbC10ZW1w bGF0ZS1uZXh0LWhvb2sgMCkgKCJub3IiICIiIHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1ob29rIDAp ICgibm90IiAiIiB2aGRsLXRlbXBsYXRlLWRlZmF1bHQtaG9vayAwKSAoIm51bGwiICIiIHZoZGwt dGVtcGxhdGUtZGVmYXVsdC1ob29rIDApICgib2YiICIiIHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1o b29rIDApICgib24iICIiIHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1ob29rIDApICgib3BlbiIgIiIg dmhkbC10ZW1wbGF0ZS1kZWZhdWx0LWhvb2sgMCkgKCJvciIgIiIgdmhkbC10ZW1wbGF0ZS1kZWZh dWx0LWhvb2sgMCkgKCJvdGhlcnMiICIiIHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1ob29rIDApICgi b3V0IiAiIiB2aGRsLXRlbXBsYXRlLWRlZmF1bHQtaG9vayAwKSAoInBhY2siICIiIHZoZGwtdGVt cGxhdGUtcGFja2FnZS1ob29rIDApICgicGFja2FnZSIgIiIgdmhkbC10ZW1wbGF0ZS1wYWNrYWdl LWhvb2sgMCkgKCJwb3J0IiAiIiB2aGRsLXRlbXBsYXRlLXBvcnQtaG9vayAwKSAoInBvc3Rwb25l ZCIgIiIgdmhkbC10ZW1wbGF0ZS1kZWZhdWx0LWhvb2sgMCkgKCJwcm9jZWR1cmUiICIiIHZoZGwt dGVtcGxhdGUtcHJvY2VkdXJlLWhvb2sgMCkgKCJwcm9jZXNzIiAiIiB2aGRsLXRlbXBsYXRlLXBy b2Nlc3MtaG9vayAwKSAoInB1cmUiICIiIHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1ob29rIDApICgi cmFuZ2UiICIiIHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1ob29rIDApICgicmVjb3JkIiAiIiB2aGRs LXRlbXBsYXRlLWRlZmF1bHQtaG9vayAwKSAoInJlZ2lzdGVyIiAiIiB2aGRsLXRlbXBsYXRlLWRl ZmF1bHQtaG9vayAwKSAoInJlamVjdCIgIiIgdmhkbC10ZW1wbGF0ZS1kZWZhdWx0LWhvb2sgMCkg KCJyZW0iICIiIHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1ob29rIDApICgicmVwb3J0IiAiIiB2aGRs LXRlbXBsYXRlLXJlcG9ydC1ob29rIDApICgicmV0dXJuIiAiIiB2aGRsLXRlbXBsYXRlLXJldHVy bi1ob29rIDApICgicm9sIiAiIiB2aGRsLXRlbXBsYXRlLWRlZmF1bHQtaG9vayAwKSAoInJvciIg IiIgdmhkbC10ZW1wbGF0ZS1kZWZhdWx0LWhvb2sgMCkgKCJzZWxlY3QiICIiIHZoZGwtdGVtcGxh dGUtc2VsZWN0ZWQtc2lnbmFsLWFzc3QtaG9vayAwKSAoInNldmVyaXR5IiAiIiB2aGRsLXRlbXBs YXRlLWRlZmF1bHQtaG9vayAwKSAoInNoYXJlZCIgIiIgdmhkbC10ZW1wbGF0ZS1kZWZhdWx0LWhv b2sgMCkgKCJzaWciICIiIHZoZGwtdGVtcGxhdGUtc2lnbmFsLWhvb2sgMCkgKCJzaWduYWwiICIi IHZoZGwtdGVtcGxhdGUtc2lnbmFsLWhvb2sgMCkgKCJzbGEiICIiIHZoZGwtdGVtcGxhdGUtZGVm YXVsdC1ob29rIDApICgic2xsIiAiIiB2aGRsLXRlbXBsYXRlLWRlZmF1bHQtaG9vayAwKSAoInNy YSIgIiIgdmhkbC10ZW1wbGF0ZS1kZWZhdWx0LWhvb2sgMCkgKCJzcmwiICIiIHZoZGwtdGVtcGxh dGUtZGVmYXVsdC1ob29rIDApICgic3VidHlwZSIgIiIgdmhkbC10ZW1wbGF0ZS1zdWJ0eXBlLWhv b2sgMCkgKCJ0aGVuIiAiIiB2aGRsLXRlbXBsYXRlLWRlZmF1bHQtaG9vayAwKSAoInRvIiAiIiB2 aGRsLXRlbXBsYXRlLWRlZmF1bHQtaG9vayAwKSAoInRyYW5zcG9ydCIgIiIgdmhkbC10ZW1wbGF0 ZS1kZWZhdWx0LWhvb2sgMCkgKCJ0eXBlIiAiIiB2aGRsLXRlbXBsYXRlLXR5cGUtaG9vayAwKSAo InVuYWZmZWN0ZWQiICIiIHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1ob29rIDApICgidW5pdHMiICIi IHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1ob29rIDApICgidW50aWwiICIiIHZoZGwtdGVtcGxhdGUt ZGVmYXVsdC1ob29rIDApICgidXNlIiAiIiB2aGRsLXRlbXBsYXRlLXVzZS1ob29rIDApICgidmFy IiAiIiB2aGRsLXRlbXBsYXRlLXZhcmlhYmxlLWhvb2sgMCkgKCJ2YXJpYWJsZSIgIiIgdmhkbC10 ZW1wbGF0ZS12YXJpYWJsZS1ob29rIDApICgid2FpdCIgIiIgdmhkbC10ZW1wbGF0ZS13YWl0LWhv b2sgMCkgKCJ3aGVuIiAiIiB2aGRsLXRlbXBsYXRlLXdoZW4taG9vayAwKSAoIndoaWxlIiAiIiB2 aGRsLXRlbXBsYXRlLXdoaWxlLWxvb3AtaG9vayAwKSAoIndpdGgiICIiIHZoZGwtdGVtcGxhdGUt d2l0aC1ob29rIDApICgieG5vciIgIiIgdmhkbC10ZW1wbGF0ZS1kZWZhdWx0LWhvb2sgMCkgKCJ4 b3IiICIiIHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1ob29rIDApKSBhbXMgKCgiYWNyb3NzIiAiIiB2 aGRsLXRlbXBsYXRlLWRlZmF1bHQtaG9vayAwKSAoImJyZWFrIiAiIiB2aGRsLXRlbXBsYXRlLWJy ZWFrLWhvb2sgMCkgKCJsaW1pdCIgIiIgdmhkbC10ZW1wbGF0ZS1saW1pdC1ob29rIDApICgibmF0 dXJlIiAiIiB2aGRsLXRlbXBsYXRlLW5hdHVyZS1ob29rIDApICgibm9pc2UiICIiIHZoZGwtdGVt cGxhdGUtZGVmYXVsdC1ob29rIDApICgicHJvY2VkdXJhbCIgIiIgdmhkbC10ZW1wbGF0ZS1wcm9j ZWR1cmFsLWhvb2sgMCkgKCJxdWFudGl0eSIgIiIgdmhkbC10ZW1wbGF0ZS1xdWFudGl0eS1ob29r IDApICgicmVmZXJlbmNlIiAiIiB2aGRsLXRlbXBsYXRlLWRlZmF1bHQtaG9vayAwKSAoInNwZWN0 cnVtIiAiIiB2aGRsLXRlbXBsYXRlLWRlZmF1bHQtaG9vayAwKSAoInN1Ym5hdHVyZSIgIiIgdmhk bC10ZW1wbGF0ZS1zdWJuYXR1cmUtaG9vayAwKSAoInRlcm1pbmFsIiAiIiB2aGRsLXRlbXBsYXRl LXRlcm1pbmFsLWhvb2sgMCkgKCJ0aHJvdWdoIiAiIiB2aGRsLXRlbXBsYXRlLWRlZmF1bHQtaG9v ayAwKSAoInRvbGVyYW5jZSIgIiIgdmhkbC10ZW1wbGF0ZS1kZWZhdWx0LWhvb2sgMCkpIHVzZXIg bmlsIDMgIiIgdmhkbC1mdW5jdGlvbi1uYW1lICJ2aGRsLW1vZGVsIiAiaG9vayIgMCBrZXl3b3Jk IGFiYnJldi1saXN0IGFsaXN0XSAxMiAoIyQgLiA2MTMzMSldKQoodmhkbC1tb2RlLWFiYnJldi10 YWJsZS1pbml0KQojQDM5IExpc3Qgb2YgYnVpbHQtaW4gY29uc3RydWN0IHRlbXBsYXRlcy4fCihk ZWZ2YXIgdmhkbC10ZW1wbGF0ZS1jb25zdHJ1Y3QtYWxpc3QgbmlsICgjJCAuIDY3MjE5KSkKI0A0 NSBJbml0aWFsaXplIGB2aGRsLXRlbXBsYXRlLWNvbnN0cnVjdC1hbGlzdCcuHwooZGVmYWxpYXMg J3ZoZGwtdGVtcGxhdGUtY29uc3RydWN0LWFsaXN0LWluaXQgI1tuaWwgIlwzMDRcMzA1XDMwNhhc MzA2CUA9XDIwNhMACAlcMjExGkFAKT4pXDIwNRgAXDMwN1wiXDIxMRNcMjA3IiBbc3RhbmRhcmQg dmhkbC1zdGFuZGFyZCB4IHZoZGwtdGVtcGxhdGUtY29uc3RydWN0LWFsaXN0IGFwcGVuZCAoKCJh bGlhcyBkZWNsYXJhdGlvbiIgdmhkbC10ZW1wbGF0ZS1hbGlhcykgKCJhcmNoaXRlY3R1cmUgYm9k eSIgdmhkbC10ZW1wbGF0ZS1hcmNoaXRlY3R1cmUpICgiYXNzZXJ0aW9uIiB2aGRsLXRlbXBsYXRl LWFzc2VydCkgKCJhdHRyaWJ1dGUgZGVjbGFyYXRpb24iIHZoZGwtdGVtcGxhdGUtYXR0cmlidXRl LWRlY2wpICgiYXR0cmlidXRlIHNwZWNpZmljYXRpb24iIHZoZGwtdGVtcGxhdGUtYXR0cmlidXRl LXNwZWMpICgiYmxvY2sgY29uZmlndXJhdGlvbiIgdmhkbC10ZW1wbGF0ZS1ibG9jay1jb25maWd1 cmF0aW9uKSAoImJsb2NrIHN0YXRlbWVudCIgdmhkbC10ZW1wbGF0ZS1ibG9jaykgKCJjYXNlIHN0 YXRlbWVudCIgdmhkbC10ZW1wbGF0ZS1jYXNlLWlzKSAoImNvbXBvbmVudCBjb25maWd1cmF0aW9u IiB2aGRsLXRlbXBsYXRlLWNvbXBvbmVudC1jb25mKSAoImNvbXBvbmVudCBkZWNsYXJhdGlvbiIg dmhkbC10ZW1wbGF0ZS1jb21wb25lbnQtZGVjbCkgKCJjb21wb25lbnQgaW5zdGFudGlhdGlvbiBz dGF0ZW1lbnQiIHZoZGwtdGVtcGxhdGUtY29tcG9uZW50LWluc3QpICgiY29uZGl0aW9uYWwgc2ln bmFsIGFzc2lnbm1lbnQiIHZoZGwtdGVtcGxhdGUtY29uZGl0aW9uYWwtc2lnbmFsLWFzc3QpICgi Y29uZmlndXJhdGlvbiBkZWNsYXJhdGlvbiIgdmhkbC10ZW1wbGF0ZS1jb25maWd1cmF0aW9uLWRl Y2wpICgiY29uZmlndXJhdGlvbiBzcGVjaWZpY2F0aW9uIiB2aGRsLXRlbXBsYXRlLWNvbmZpZ3Vy YXRpb24tc3BlYykgKCJjb25zdGFudCBkZWNsYXJhdGlvbiIgdmhkbC10ZW1wbGF0ZS1jb25zdGFu dCkgKCJkaXNjb25uZWN0aW9uIHNwZWNpZmljYXRpb24iIHZoZGwtdGVtcGxhdGUtZGlzY29ubmVj dCkgKCJlbnRpdHkgZGVjbGFyYXRpb24iIHZoZGwtdGVtcGxhdGUtZW50aXR5KSAoImV4aXQgc3Rh dGVtZW50IiB2aGRsLXRlbXBsYXRlLWV4aXQpICgiZmlsZSBkZWNsYXJhdGlvbiIgdmhkbC10ZW1w bGF0ZS1maWxlKSAoImdlbmVyYXRlIHN0YXRlbWVudCIgdmhkbC10ZW1wbGF0ZS1nZW5lcmF0ZSkg KCJnZW5lcmljIGNsYXVzZSIgdmhkbC10ZW1wbGF0ZS1nZW5lcmljKSAoImdyb3VwIGRlY2xhcmF0 aW9uIiB2aGRsLXRlbXBsYXRlLWdyb3VwLWRlY2wpICgiZ3JvdXAgdGVtcGxhdGUgZGVjbGFyYXRp b24iIHZoZGwtdGVtcGxhdGUtZ3JvdXAtdGVtcGxhdGUpICgiaWYgc3RhdGVtZW50IiB2aGRsLXRl bXBsYXRlLWlmLXRoZW4pICgibGlicmFyeSBjbGF1c2UiIHZoZGwtdGVtcGxhdGUtbGlicmFyeSkg KCJsb29wIHN0YXRlbWVudCIgdmhkbC10ZW1wbGF0ZS1sb29wKSAoIm5leHQgc3RhdGVtZW50IiB2 aGRsLXRlbXBsYXRlLW5leHQpICgicGFja2FnZSBkZWNsYXJhdGlvbiIgdmhkbC10ZW1wbGF0ZS1w YWNrYWdlLWRlY2wpICgicGFja2FnZSBib2R5IiB2aGRsLXRlbXBsYXRlLXBhY2thZ2UtYm9keSkg KCJwb3J0IGNsYXVzZSIgdmhkbC10ZW1wbGF0ZS1wb3J0KSAoInByb2Nlc3Mgc3RhdGVtZW50IiB2 aGRsLXRlbXBsYXRlLXByb2Nlc3MpICgicmVwb3J0IHN0YXRlbWVudCIgdmhkbC10ZW1wbGF0ZS1y ZXBvcnQpICgicmV0dXJuIHN0YXRlbWVudCIgdmhkbC10ZW1wbGF0ZS1yZXR1cm4pICgic2VsZWN0 ZWQgc2lnbmFsIGFzc2lnbm1lbnQiIHZoZGwtdGVtcGxhdGUtc2VsZWN0ZWQtc2lnbmFsLWFzc3Qp ICgic2lnbmFsIGRlY2xhcmF0aW9uIiB2aGRsLXRlbXBsYXRlLXNpZ25hbCkgKCJzdWJwcm9ncmFt IGRlY2xhcmF0aW9uIiB2aGRsLXRlbXBsYXRlLXN1YnByb2dyYW0tZGVjbCkgKCJzdWJwcm9ncmFt IGJvZHkiIHZoZGwtdGVtcGxhdGUtc3VicHJvZ3JhbS1ib2R5KSAoInN1YnR5cGUgZGVjbGFyYXRp b24iIHZoZGwtdGVtcGxhdGUtc3VidHlwZSkgKCJ0eXBlIGRlY2xhcmF0aW9uIiB2aGRsLXRlbXBs YXRlLXR5cGUpICgidXNlIGNsYXVzZSIgdmhkbC10ZW1wbGF0ZS11c2UpICgidmFyaWFibGUgZGVj bGFyYXRpb24iIHZoZGwtdGVtcGxhdGUtdmFyaWFibGUpICgid2FpdCBzdGF0ZW1lbnQiIHZoZGwt dGVtcGxhdGUtd2FpdCkpIGFtcyAoKCJicmVhayBzdGF0ZW1lbnQiIHZoZGwtdGVtcGxhdGUtYnJl YWspICgibmF0dXJlIGRlY2xhcmF0aW9uIiB2aGRsLXRlbXBsYXRlLW5hdHVyZSkgKCJxdWFudGl0 eSBkZWNsYXJhdGlvbiIgdmhkbC10ZW1wbGF0ZS1xdWFudGl0eSkgKCJzaW11bHRhbmVvdXMgY2Fz ZSBzdGF0ZW1lbnQiIHZoZGwtdGVtcGxhdGUtY2FzZS11c2UpICgic2ltdWx0YW5lb3VzIGlmIHN0 YXRlbWVudCIgdmhkbC10ZW1wbGF0ZS1pZi11c2UpICgic2ltdWx0YW5lb3VzIHByb2NlZHVyYWwg c3RhdGVtZW50IiB2aGRsLXRlbXBsYXRlLXByb2NlZHVyYWwpICgic3RlcCBsaW1pdCBzcGVjaWZp Y2F0aW9uIiB2aGRsLXRlbXBsYXRlLWxpbWl0KSAoInN1Ym5hdHVyZSBkZWNsYXJhdGlvbiIgdmhk bC10ZW1wbGF0ZS1zdWJuYXR1cmUpICgidGVybWluYWwgZGVjbGFyYXRpb24iIHZoZGwtdGVtcGxh dGUtdGVybWluYWwpKV0gNSAoIyQgLiA2NzMxOSldKQoodmhkbC10ZW1wbGF0ZS1jb25zdHJ1Y3Qt YWxpc3QtaW5pdCkKI0AzNyBMaXN0IG9mIGJ1aWx0LWluIHBhY2thZ2UgdGVtcGxhdGVzLh8KKGRl ZnZhciB2aGRsLXRlbXBsYXRlLXBhY2thZ2UtYWxpc3QgbmlsICgjJCAuIDcwMDcwKSkKI0A0MyBJ bml0aWFsaXplIGB2aGRsLXRlbXBsYXRlLXBhY2thZ2UtYWxpc3QnLh8KKGRlZmFsaWFzICd2aGRs LXRlbXBsYXRlLXBhY2thZ2UtYWxpc3QtaW5pdCAjW25pbCAiXDMwNFwzMDVcMzA2GFwzMDYJQD1c MjA2EwAICVwyMTEaQUApPilcMjA1GABcMzA3XCJcMjExE1wyMDciIFtzdGFuZGFyZCB2aGRsLXN0 YW5kYXJkIHggdmhkbC10ZW1wbGF0ZS1wYWNrYWdlLWFsaXN0IGFwcGVuZCAoKCJudW1lcmljX2Jp dCIgdmhkbC10ZW1wbGF0ZS1wYWNrYWdlLW51bWVyaWMtYml0KSAoIm51bWVyaWNfc3RkIiB2aGRs LXRlbXBsYXRlLXBhY2thZ2UtbnVtZXJpYy1zdGQpICgic3RkX2xvZ2ljXzExNjQiIHZoZGwtdGVt cGxhdGUtcGFja2FnZS1zdGQtbG9naWMtMTE2NCkgKCJzdGRfbG9naWNfYXJpdGgiIHZoZGwtdGVt cGxhdGUtcGFja2FnZS1zdGQtbG9naWMtYXJpdGgpICgic3RkX2xvZ2ljX21pc2MiIHZoZGwtdGVt cGxhdGUtcGFja2FnZS1zdGQtbG9naWMtbWlzYykgKCJzdGRfbG9naWNfc2lnbmVkIiB2aGRsLXRl bXBsYXRlLXBhY2thZ2Utc3RkLWxvZ2ljLXNpZ25lZCkgKCJzdGRfbG9naWNfdGV4dGlvIiB2aGRs LXRlbXBsYXRlLXBhY2thZ2Utc3RkLWxvZ2ljLXRleHRpbykgKCJzdGRfbG9naWNfdW5zaWduZWQi IHZoZGwtdGVtcGxhdGUtcGFja2FnZS1zdGQtbG9naWMtdW5zaWduZWQpICgidGV4dGlvIiB2aGRs LXRlbXBsYXRlLXBhY2thZ2UtdGV4dGlvKSkgbWF0aCAoKCJtYXRoX2NvbXBsZXgiIHZoZGwtdGVt cGxhdGUtcGFja2FnZS1tYXRoLWNvbXBsZXgpICgibWF0aF9yZWFsIiB2aGRsLXRlbXBsYXRlLXBh Y2thZ2UtbWF0aC1yZWFsKSldIDUgKCMkIC4gNzAxNjYpXSkKKHZoZGwtdGVtcGxhdGUtcGFja2Fn ZS1hbGlzdC1pbml0KQojQDM5IExpc3Qgb2YgYnVpbHQtaW4gZGlyZWN0aXZlIHRlbXBsYXRlcy4f CihkZWZ2YXIgdmhkbC10ZW1wbGF0ZS1kaXJlY3RpdmUtYWxpc3QgKGFwcGVuZCAnKCgidHJhbnNs YXRlX29uIiB2aGRsLXRlbXBsYXRlLWRpcmVjdGl2ZS10cmFuc2xhdGUtb24pICgidHJhbnNsYXRl X29mZiIgdmhkbC10ZW1wbGF0ZS1kaXJlY3RpdmUtdHJhbnNsYXRlLW9mZikgKCJzeW50aGVzaXNf b24iIHZoZGwtdGVtcGxhdGUtZGlyZWN0aXZlLXN5bnRoZXNpcy1vbikgKCJzeW50aGVzaXNfb2Zm IiB2aGRsLXRlbXBsYXRlLWRpcmVjdGl2ZS1zeW50aGVzaXMtb2ZmKSkpICgjJCAuIDcxMDQxKSkK I0A1NCBDYWxsIHRoZSBjdXN0b21pemUgZnVuY3Rpb24gd2l0aCBgdmhkbCcgYXMgYXJndW1lbnQu HwooZGVmYWxpYXMgJ3ZoZGwtY3VzdG9taXplICNbbmlsICJcMzAwXDMwMSFcMjA3IiBbY3VzdG9t aXplLWJyb3dzZSB2aGRsXSAyICgjJCAuIDcxMzY5KSBuaWxdKQojQDY5IENyZWF0ZSBhIGZ1bGwg Y3VzdG9taXphdGlvbiBtZW51IGZvciBWSERMLCBpbnNlcnQgaXQgaW50byB0aGUgbWVudS4fCihk ZWZhbGlhcyAndmhkbC1jcmVhdGUtY3VzdG9taXplLW1lbnUgI1tuaWwgIlwzMDBcMzAxIVwyMDMS AFwzMDJcMzAzXDMwNFwzMDVcMzAxXDMwNiFcMzA3QkIjXDIwN1wzMTBcMzExIVwyMDciIFtmYm91 bmRwIGN1c3RvbWl6ZS1tZW51LWNyZWF0ZSBlYXN5LW1lbnUtY2hhbmdlICgiVkhETCIpICJDdXN0 b21pemUiIFsiQnJvd3NlIFZIREwgR3JvdXAuLi4iIHZoZGwtY3VzdG9taXplIHRdIHZoZGwgKCIt LSIgWyJBY3RpdmF0ZSBOZXcgQ3VzdG9taXphdGlvbnMiIHZoZGwtYWN0aXZhdGUtY3VzdG9taXph dGlvbnMgdF0pIGVycm9yICJDYW5ub3QgZXhwYW5kIG1lbnUgKG91dGRhdGVkIHZlcnNpb24gb2Yg Y3VzLWVkaXQuZWwpIl0gNiAoIyQgLiA3MTUyMSkgbmlsXSkKI0AyNCBDcmVhdGUgVkhETCBNb2Rl IG1lbnUuHwooZGVmYWxpYXMgJ3ZoZGwtY3JlYXRlLW1vZGUtbWVudSAjW25pbCAiXDMwNlwzMDdc MzEwXDMxMVwzMTIIXDMxM1wyMTEZGlwyMTEbXDIwMysAC0BAEVwzMTQJXDMxNQlEXGZcMzE2DVwz MTdcMzIwCUUmBlxuQhILQVwyMTETXDIwNA8AXDMyMVwzMTBcbkJCXDIxMRJcMjM3K1wiXDMxMFwz MjJcMzIzXDMyNFwzMTBcMzI1XDMyNlwzMTBcMzI3XDMzMFwzMzFcMzEwXDMxMVwzMzIOPVwzMTNc MjExGRpcMjExHj5cMjAzbwAOPkBAEVwzMTQJXDMzM1wzMzQJRVxmXDMxNg1cMzE3XDMzNAlFJgZc bkISDj5BXDIxMRY+XDIwNE8AXDMzNVwzMTBcbkJCXDIxMRJcMjM3K1wiXDI1N1xmXDMxMFwzMTFc MzM2XDMzNx4/XDMzNw5AQD1cMjA2XDIyNAAOPw5AXDIxMR5BQUApPilcMjA1XDIzMQBcMzQwXDM0 MVwzMTFcMzQyXDM0Mx4/XDM0Mw5AQD1cMjA2XDI2MgAOPw5AXDIxMR5BQUApPilcMjA1XDI2NwBc MzQ0XDM0NSNDXDM0NiVcMzExXDM0Nw5CXDMxM1wyMTEeQxpcMjExHkRcMjAzXDM2MQAOREAWQ1wz MTQOQ0BcMzUwXDM1MQ5DQFwiDkVcMzUyXDM1M1wzNTQOQzghUCRcbkISDkRBXDIxMRZEXDIwNFwz MTMAXDMxMVxuXDIzN1wzNTVcIlwyMTESK1wiXDM1NlwzMTBcMzU3XDM2MFwzNjFcMzEwXDM2Mlwz NjNcMzY0XDM2NVwzMTBcMzY2XDM2N1wzMTBcMzcwXDM3MVwzNzJcMzEwXDM3M1wzMTBcMzc0XDI1 Nx5cMjA3IiBbdmhkbC1wcm9qZWN0LWFsaXN0IG5hbWUgbWVudS1hbGlzdCBwcm9qZWN0LWFsaXN0 IDpzdHlsZSA6c2VsZWN0ZWQgIlZIREwiICgiTW9kZSIgWyJFbGVjdHJpYyIgdmhkbC1lbGVjdHJp Yy1tb2RlIDpzdHlsZSB0b2dnbGUgOnNlbGVjdGVkIHZoZGwtZWxlY3RyaWMtbW9kZV0gWyJTdHV0 dGVyIiB2aGRsLXN0dXR0ZXItbW9kZSA6c3R5bGUgdG9nZ2xlIDpzZWxlY3RlZCB2aGRsLXN0dXR0 ZXItbW9kZV0pICItLSIgYXBwZW5kICgiUHJvamVjdCIgWyJOb25lIiAodmhkbC1wcm9qZWN0LXN3 aXRjaCAiIikgOnN0eWxlIHJhZGlvIDpzZWxlY3RlZCAoZXF1YWwgdmhkbC1wcm9qZWN0ICIiKV0g Ii0tIikgbmlsIHZlY3RvciB2aGRsLXByb2plY3Qtc3dpdGNoIHJhZGlvIGVxdWFsIHZoZGwtcHJv amVjdCBbIkFkZCBQcm9qZWN0Li4uIiAoY3VzdG9taXplLXZhcmlhYmxlICd2aGRsLXByb2plY3Qt YWxpc3QpIHRdICJDb21waWxlIiBbIkNvbXBpbGUgQnVmZmVyIiB2aGRsLWNvbXBpbGUgdF0gWyJT dG9wIENvbXBpbGF0aW9uIiBraWxsLWNvbXBpbGF0aW9uIHRdIFsiTWFrZSIgdmhkbC1tYWtlIHRd IFsiR2VuZXJhdGUgTWFrZWZpbGUiIHZoZGwtZ2VuZXJhdGUtbWFrZWZpbGUgdF0gWyJOZXh0IEVy cm9yIiBuZXh0LWVycm9yIHRdIFsiUHJldmlvdXMgRXJyb3IiIHByZXZpb3VzLWVycm9yIHRdIFsi Rmlyc3QgRXJyb3IiIGZpcnN0LWVycm9yIHRdICgiQ29tcGlsZXIiKSBzZXRxIHZoZGwtY29tcGls ZXIgWyJBZGQgQ29tcGlsZXIuLi4iIChjdXN0b21pemUtdmFyaWFibGUgJ3ZoZGwtY29tcGlsZXIt YWxpc3QpIHRdICgiVGVtcGxhdGUiICgiVkhETCBDb25zdHJ1Y3QgMSIgWyJBbGlhcyIgdmhkbC10 ZW1wbGF0ZS1hbGlhcyB0XSBbIkFyY2hpdGVjdHVyZSIgdmhkbC10ZW1wbGF0ZS1hcmNoaXRlY3R1 cmUgdF0gWyJBc3NlcnQiIHZoZGwtdGVtcGxhdGUtYXNzZXJ0IHRdIFsiQXR0cmlidXRlIChEZWNs KSIgdmhkbC10ZW1wbGF0ZS1hdHRyaWJ1dGUtZGVjbCB0XSBbIkF0dHJpYnV0ZSAoU3BlYykiIHZo ZGwtdGVtcGxhdGUtYXR0cmlidXRlLXNwZWMgdF0gWyJCbG9jayIgdmhkbC10ZW1wbGF0ZS1ibG9j ayB0XSBbIkNhc2UiIHZoZGwtdGVtcGxhdGUtY2FzZS1pcyB0XSBbIkNvbXBvbmVudCAoRGVjbCki IHZoZGwtdGVtcGxhdGUtY29tcG9uZW50LWRlY2wgdF0gWyIoQ29tcG9uZW50KSBJbnN0YW5jZSIg dmhkbC10ZW1wbGF0ZS1jb21wb25lbnQtaW5zdCB0XSBbIkNvbmRpdGlvbmFsIChTaWduYWwgQXNz dCkiIHZoZGwtdGVtcGxhdGUtY29uZGl0aW9uYWwtc2lnbmFsLWFzc3QgdF0gWyJDb25maWd1cmF0 aW9uIChCbG9jaykiIHZoZGwtdGVtcGxhdGUtYmxvY2stY29uZmlndXJhdGlvbiB0XSBbIkNvbmZp Z3VyYXRpb24gKENvbXApIiB2aGRsLXRlbXBsYXRlLWNvbXBvbmVudC1jb25mIHRdIFsiQ29uZmln dXJhdGlvbiAoRGVjbCkiIHZoZGwtdGVtcGxhdGUtY29uZmlndXJhdGlvbi1kZWNsIHRdIFsiQ29u ZmlndXJhdGlvbiAoU3BlYykiIHZoZGwtdGVtcGxhdGUtY29uZmlndXJhdGlvbi1zcGVjIHRdIFsi Q29uc3RhbnQiIHZoZGwtdGVtcGxhdGUtY29uc3RhbnQgdF0gWyJEaXNjb25uZWN0IiB2aGRsLXRl bXBsYXRlLWRpc2Nvbm5lY3QgdF0gWyJFbHNlIiB2aGRsLXRlbXBsYXRlLWVsc2UgdF0gWyJFbHNp ZiIgdmhkbC10ZW1wbGF0ZS1lbHNpZiB0XSBbIkVudGl0eSIgdmhkbC10ZW1wbGF0ZS1lbnRpdHkg dF0gWyJFeGl0IiB2aGRsLXRlbXBsYXRlLWV4aXQgdF0gWyJGaWxlIiB2aGRsLXRlbXBsYXRlLWZp bGUgdF0gWyJGb3IgKEdlbmVyYXRlKSIgdmhkbC10ZW1wbGF0ZS1mb3ItZ2VuZXJhdGUgdF0gWyJG b3IgKExvb3ApIiB2aGRsLXRlbXBsYXRlLWZvci1sb29wIHRdIFsiRnVuY3Rpb24gKEJvZHkpIiB2 aGRsLXRlbXBsYXRlLWZ1bmN0aW9uLWJvZHkgdF0gWyJGdW5jdGlvbiAoRGVjbCkiIHZoZGwtdGVt cGxhdGUtZnVuY3Rpb24tZGVjbCB0XSBbIkdlbmVyaWMiIHZoZGwtdGVtcGxhdGUtZ2VuZXJpYyB0 XSBbIkdyb3VwIChEZWNsKSIgdmhkbC10ZW1wbGF0ZS1ncm91cC1kZWNsIHRdIFsiR3JvdXAgKFRl bXBsYXRlKSIgdmhkbC10ZW1wbGF0ZS1ncm91cC10ZW1wbGF0ZSB0XSkgKCJWSERMIENvbnN0cnVj dCAyIiBbIklmIChHZW5lcmF0ZSkiIHZoZGwtdGVtcGxhdGUtaWYtZ2VuZXJhdGUgdF0gWyJJZiAo VGhlbikiIHZoZGwtdGVtcGxhdGUtaWYtdGhlbiB0XSBbIkxpYnJhcnkiIHZoZGwtdGVtcGxhdGUt bGlicmFyeSB0XSBbIkxvb3AiIHZoZGwtdGVtcGxhdGUtYmFyZS1sb29wIHRdIFsiTWFwIiB2aGRs LXRlbXBsYXRlLW1hcCB0XSBbIk5leHQiIHZoZGwtdGVtcGxhdGUtbmV4dCB0XSBbIihPdGhlcnMp IiB2aGRsLXRlbXBsYXRlLW90aGVycyB0XSBbIlBhY2thZ2UgKERlY2wpIiB2aGRsLXRlbXBsYXRl LXBhY2thZ2UtZGVjbCB0XSBbIlBhY2thZ2UgKEJvZHkpIiB2aGRsLXRlbXBsYXRlLXBhY2thZ2Ut Ym9keSB0XSBbIlBvcnQiIHZoZGwtdGVtcGxhdGUtcG9ydCB0XSBbIlByb2NlZHVyZSAoQm9keSki IHZoZGwtdGVtcGxhdGUtcHJvY2VkdXJlLWJvZHkgdF0gWyJQcm9jZWR1cmUgKERlY2wpIiB2aGRs LXRlbXBsYXRlLXByb2NlZHVyZS1kZWNsIHRdIFsiUHJvY2VzcyAoQ29tYikiIHZoZGwtdGVtcGxh dGUtcHJvY2Vzcy1jb21iIHRdIFsiUHJvY2VzcyAoU2VxKSIgdmhkbC10ZW1wbGF0ZS1wcm9jZXNz LXNlcSB0XSBbIlJlcG9ydCIgdmhkbC10ZW1wbGF0ZS1yZXBvcnQgdF0gWyJSZXR1cm4iIHZoZGwt dGVtcGxhdGUtcmV0dXJuIHRdIFsiU2VsZWN0IiB2aGRsLXRlbXBsYXRlLXNlbGVjdGVkLXNpZ25h bC1hc3N0IHRdIFsiU2lnbmFsIiB2aGRsLXRlbXBsYXRlLXNpZ25hbCB0XSBbIlN1YnR5cGUiIHZo ZGwtdGVtcGxhdGUtc3VidHlwZSB0XSBbIlR5cGUiIHZoZGwtdGVtcGxhdGUtdHlwZSB0XSBbIlVz ZSIgdmhkbC10ZW1wbGF0ZS11c2UgdF0gWyJWYXJpYWJsZSIgdmhkbC10ZW1wbGF0ZS12YXJpYWJs ZSB0XSBbIldhaXQiIHZoZGwtdGVtcGxhdGUtd2FpdCB0XSBbIihDbG9ja2VkIFdhaXQpIiB2aGRs LXRlbXBsYXRlLWNsb2NrZWQtd2FpdCB0XSBbIldoZW4iIHZoZGwtdGVtcGxhdGUtd2hlbiB0XSBb IldoaWxlIChMb29wKSIgdmhkbC10ZW1wbGF0ZS13aGlsZS1sb29wIHRdIFsiV2l0aCIgdmhkbC10 ZW1wbGF0ZS13aXRoIHRdKSkgYW1zICgoIlZIREwtQU1TIENvbnN0cnVjdCIgWyJCcmVhayIgdmhk bC10ZW1wbGF0ZS1icmVhayB0XSBbIkNhc2UgKFVzZSkiIHZoZGwtdGVtcGxhdGUtY2FzZS11c2Ug dF0gWyJJZiAoVXNlKSIgdmhkbC10ZW1wbGF0ZS1pZi11c2UgdF0gWyJMaW1pdCIgdmhkbC10ZW1w bGF0ZS1saW1pdCB0XSBbIk5hdHVyZSIgdmhkbC10ZW1wbGF0ZS1uYXR1cmUgdF0gWyJQcm9jZWR1 cmFsIiB2aGRsLXRlbXBsYXRlLXByb2NlZHVyYWwgdF0gWyJRdWFudGl0eSAoRnJlZSkiIHZoZGwt dGVtcGxhdGUtcXVhbnRpdHktZnJlZSB0XSBbIlF1YW50aXR5IChCcmFuY2gpIiB2aGRsLXRlbXBs YXRlLXF1YW50aXR5LWJyYW5jaCB0XSBbIlF1YW50aXR5IChTb3VyY2UpIiB2aGRsLXRlbXBsYXRl LXF1YW50aXR5LXNvdXJjZSB0XSBbIlN1Ym5hdHVyZSIgdmhkbC10ZW1wbGF0ZS1zdWJuYXR1cmUg dF0gWyJUZXJtaW5hbCIgdmhkbC10ZW1wbGF0ZS10ZXJtaW5hbCB0XSkpIChbIkluc2VydCBDb25z dHJ1Y3QiIHZoZGwtdGVtcGxhdGUtaW5zZXJ0LWNvbnN0cnVjdCA6a2V5cyAiQy1jIEMtaSBDLWMi XSAiLS0iKSAoIlBhY2thZ2UiKSBtYXRoIChbIm1hdGhfY29tcGxleCIgdmhkbC10ZW1wbGF0ZS1w YWNrYWdlLW1hdGgtY29tcGxleCB0XSBbIm1hdGhfcmVhbCIgdmhkbC10ZW1wbGF0ZS1wYWNrYWdl LW1hdGgtcmVhbCB0XSkgKFsibnVtZXJpY19iaXQiIHZoZGwtdGVtcGxhdGUtcGFja2FnZS1udW1l cmljLWJpdCB0XSBbIm51bWVyaWNfc3RkIiB2aGRsLXRlbXBsYXRlLXBhY2thZ2UtbnVtZXJpYy1z dGQgdF0gWyJzdGRfbG9naWNfMTE2NCIgdmhkbC10ZW1wbGF0ZS1wYWNrYWdlLXN0ZC1sb2dpYy0x MTY0IHRdIFsidGV4dGlvIiB2aGRsLXRlbXBsYXRlLXBhY2thZ2UtdGV4dGlvIHRdICItLSIgWyJz dGRfbG9naWNfYXJpdGgiIHZoZGwtdGVtcGxhdGUtcGFja2FnZS1zdGQtbG9naWMtYXJpdGggdF0g WyJzdGRfbG9naWNfc2lnbmVkIiB2aGRsLXRlbXBsYXRlLXBhY2thZ2Utc3RkLWxvZ2ljLXNpZ25l ZCB0XSBbInN0ZF9sb2dpY191bnNpZ25lZCIgdmhkbC10ZW1wbGF0ZS1wYWNrYWdlLXN0ZC1sb2dp Yy11bnNpZ25lZCB0XSBbInN0ZF9sb2dpY19taXNjIiB2aGRsLXRlbXBsYXRlLXBhY2thZ2Utc3Rk LWxvZ2ljLW1pc2MgdF0gWyJzdGRfbG9naWNfdGV4dGlvIiB2aGRsLXRlbXBsYXRlLXBhY2thZ2Ut c3RkLWxvZ2ljLXRleHRpbyB0XSAiLS0iIFsiSW5zZXJ0IFBhY2thZ2UiIHZoZGwtdGVtcGxhdGUt aW5zZXJ0LXBhY2thZ2UgOmtleXMgIkMtYyBDLWkgQy1wIl0pICgoIkRpcmVjdGl2ZSIgWyJ0cmFu c2xhdGVfb24iIHZoZGwtdGVtcGxhdGUtZGlyZWN0aXZlLXRyYW5zbGF0ZS1vbiB0XSBbInRyYW5z bGF0ZV9vZmYiIHZoZGwtdGVtcGxhdGUtZGlyZWN0aXZlLXRyYW5zbGF0ZS1vZmYgdF0gWyJzeW50 aGVzaXNfb24iIHZoZGwtdGVtcGxhdGUtZGlyZWN0aXZlLXN5bnRoZXNpcy1vbiB0XSBbInN5bnRo ZXNpc19vZmYiIHZoZGwtdGVtcGxhdGUtZGlyZWN0aXZlLXN5bnRoZXNpcy1vZmYgdF0gIi0tIiBb Ikluc2VydCBEaXJlY3RpdmUiIHZoZGwtdGVtcGxhdGUtaW5zZXJ0LWRpcmVjdGl2ZSA6a2V5cyAi Qy1jIEMtaSBDLWQiXSkgIi0tIiBbIkluc2VydCBIZWFkZXIiIHZoZGwtdGVtcGxhdGUtaGVhZGVy IDprZXlzICJDLWMgQy10IEMtaCJdIFsiSW5zZXJ0IEZvb3RlciIgdmhkbC10ZW1wbGF0ZS1mb290 ZXIgdF0gWyJJbnNlcnQgRGF0ZSIgdmhkbC10ZW1wbGF0ZS1pbnNlcnQtZGF0ZSB0XSBbIk1vZGlm eSBEYXRlIiB2aGRsLXRlbXBsYXRlLW1vZGlmeSA6a2V5cyAiQy1jIEMtdCBDLW0iXSAiLS0iIFsi UXVlcnkgTmV4dCBQcm9tcHQiIHZoZGwtdGVtcGxhdGUtc2VhcmNoLXByb21wdCB0XSkgKCJNb2Rl bCIpIHZoZGwtZnVuY3Rpb24tbmFtZSAidmhkbC1tb2RlbCIgIkMtYyBDLW0gIiBrZXktZGVzY3Jp cHRpb24gMiAoIi0tIiBbIkluc2VydCBNb2RlbCIgdmhkbC1tb2RlbC1pbnNlcnQgOmtleXMgIkMt YyBDLWkgQy1tIl0gWyJBZGQgTW9kZWwuLi4iIChjdXN0b21pemUtdmFyaWFibGUgJ3ZoZGwtbW9k ZWwtYWxpc3QpIHRdKSAoIlBvcnQiIFsiQ29weSIgdmhkbC1wb3J0LWNvcHkgdF0gIi0tIiBbIlBh c3RlIEFzIEVudGl0eSIgdmhkbC1wb3J0LXBhc3RlLWVudGl0eSB2aGRsLXBvcnQtbGlzdF0gWyJQ YXN0ZSBBcyBDb21wb25lbnQiIHZoZGwtcG9ydC1wYXN0ZS1jb21wb25lbnQgdmhkbC1wb3J0LWxp c3RdIFsiUGFzdGUgQXMgSW5zdGFuY2UiIHZoZGwtcG9ydC1wYXN0ZS1pbnN0YW5jZSA6a2V5cyAi Qy1jIEMtcCBDLWkiIDphY3RpdmUgdmhkbC1wb3J0LWxpc3RdIFsiUGFzdGUgQXMgU2lnbmFscyIg dmhkbC1wb3J0LXBhc3RlLXNpZ25hbHMgdmhkbC1wb3J0LWxpc3RdIFsiUGFzdGUgQXMgQ29uc3Rh bnRzIiB2aGRsLXBvcnQtcGFzdGUtY29uc3RhbnRzIHZoZGwtcG9ydC1saXN0XSBbIlBhc3RlIEFz IEdlbmVyaWMgTWFwIiB2aGRsLXBvcnQtcGFzdGUtZ2VuZXJpYy1tYXAgdmhkbC1wb3J0LWxpc3Rd IFsiUGFzdGUgQXMgVGVzdCBCZW5jaCIgdmhkbC1wb3J0LXBhc3RlLXRlc3RiZW5jaCB2aGRsLXBv cnQtbGlzdF0gIi0tIiBbIkZsYXR0ZW4iIHZoZGwtcG9ydC1mbGF0dGVuIHZoZGwtcG9ydC1saXN0 XSkgKCJDb21tZW50IiBbIihVbilDb21tZW50IE91dCBSZWdpb24iIHZoZGwtY29tbWVudC11bmNv bW1lbnQtcmVnaW9uIChtYXJrKV0gIi0tIiBbIkluc2VydCBJbmxpbmUgQ29tbWVudCIgdmhkbC1j b21tZW50LWFwcGVuZC1pbmxpbmUgdF0gWyJJbnNlcnQgSG9yaXpvbnRhbCBMaW5lIiB2aGRsLWNv bW1lbnQtZGlzcGxheS1saW5lIHRdIFsiSW5zZXJ0IERpc3BsYXkgQ29tbWVudCIgdmhkbC1jb21t ZW50LWRpc3BsYXkgdF0gIi0tIiBbIkZpbGwgQ29tbWVudCIgZmlsbC1wYXJhZ3JhcGggdF0gWyJG aWxsIENvbW1lbnQgUmVnaW9uIiBmaWxsLXJlZ2lvbiAobWFyayldIFsiS2lsbCBDb21tZW50IFJl Z2lvbiIgdmhkbC1jb21tZW50LWtpbGwtcmVnaW9uIChtYXJrKV0gWyJLaWxsIElubGluZSBDb21t ZW50IFJlZ2lvbiIgdmhkbC1jb21tZW50LWtpbGwtaW5saW5lLXJlZ2lvbiAobWFyayldKSAoIkxp bmUiIFsiS2lsbCIgdmhkbC1saW5lLWtpbGwgdF0gWyJDb3B5IiB2aGRsLWxpbmUtY29weSB0XSBb IllhbmsiIHZoZGwtbGluZS15YW5rIHRdIFsiRXhwYW5kIiB2aGRsLWxpbmUtZXhwYW5kIHRdICIt LSIgWyJUcmFuc3Bvc2UgTmV4dCIgdmhkbC1saW5lLXRyYW5zcG9zZS1uZXh0IHRdIFsiVHJhbnNw b3NlIFByZXYiIHZoZGwtbGluZS10cmFuc3Bvc2UtcHJldmlvdXMgdF0gWyJPcGVuIiB2aGRsLWxp bmUtb3BlbiB0XSBbIkpvaW4iIGRlbGV0ZS1pbmRlbnRhdGlvbiB0XSAiLS0iIFsiR290byIgZ290 by1saW5lIHRdIFsiKFVuKUNvbW1lbnQgT3V0IiB2aGRsLWNvbW1lbnQtdW5jb21tZW50LWxpbmUg dF0pICgiTW92ZSIgWyJGb3J3YXJkIFN0YXRlbWVudCIgdmhkbC1lbmQtb2Ytc3RhdGVtZW50IHRd IFsiQmFja3dhcmQgU3RhdGVtZW50IiB2aGRsLWJlZ2lubmluZy1vZi1zdGF0ZW1lbnQgdF0gWyJG b3J3YXJkIEV4cHJlc3Npb24iIHZoZGwtZm9yd2FyZC1zZXhwIHRdIFsiQmFja3dhcmQgRXhwcmVz c2lvbiIgdmhkbC1iYWNrd2FyZC1zZXhwIHRdIFsiRm9yd2FyZCBGdW5jdGlvbiIgdmhkbC1lbmQt b2YtZGVmdW4gdF0gWyJCYWNrd2FyZCBGdW5jdGlvbiIgdmhkbC1iZWdpbm5pbmctb2YtZGVmdW4g dF0gWyJNYXJrIEZ1bmN0aW9uIiB2aGRsLW1hcmstZGVmdW4gdF0pICgiSW5kZW50IiBbIkxpbmUi IHZoZGwtaW5kZW50LWxpbmUgdF0gWyJSZWdpb24iIHZoZGwtaW5kZW50LXJlZ2lvbiAobWFyayld IFsiQnVmZmVyIiB2aGRsLWluZGVudC1idWZmZXIgdF0pICgiQWxpZ24iIFsiR3JvdXAiIHZoZGwt YWxpZ24tZ3JvdXAgdF0gWyJSZWdpb24iIHZoZGwtYWxpZ24tbm9pbmRlbnQtcmVnaW9uIChtYXJr KV0gWyJCdWZmZXIiIHZoZGwtYWxpZ24tbm9pbmRlbnQtYnVmZmVyIHRdICItLSIgWyJJbmxpbmUg Q29tbWVudCBHcm91cCIgdmhkbC1hbGlnbi1pbmxpbmUtY29tbWVudC1ncm91cCB0XSBbIklubGlu ZSBDb21tZW50IFJlZ2lvbiIgdmhkbC1hbGlnbi1pbmxpbmUtY29tbWVudC1yZWdpb24gKG1hcmsp XSBbIklubGluZSBDb21tZW50IEJ1ZmZlciIgdmhkbC1hbGlnbi1pbmxpbmUtY29tbWVudC1idWZm ZXIgdF0gIi0tIiBbIkZpeHVwIFdoaXRlc3BhY2UgUmVnaW9uIiB2aGRsLWZpeHVwLXdoaXRlc3Bh Y2UtcmVnaW9uIChtYXJrKV0gWyJGaXh1cCBXaGl0ZXNwYWNlIEJ1ZmZlciIgdmhkbC1maXh1cC13 aGl0ZXNwYWNlLWJ1ZmZlciB0XSkgKCJGaXggQ2FzZSIgWyJSZWdpb24iIHZoZGwtZml4LWNhc2Ut cmVnaW9uIChtYXJrKV0gWyJCdWZmZXIiIHZoZGwtZml4LWNhc2UtYnVmZmVyIHRdKSAoIkJlYXV0 aWZ5IiBbIkJlYXV0aWZ5IFJlZ2lvbiIgdmhkbC1iZWF1dGlmeS1yZWdpb24gKG1hcmspXSBbIkJl YXV0aWZ5IEJ1ZmZlciIgdmhkbC1iZWF1dGlmeS1idWZmZXIgdF0pIFsiRm9udGlmeSBCdWZmZXIi IHZoZGwtZm9udGlmeS1idWZmZXIgdF0gWyJTeW50YWN0aWMgSW5mbyIgdmhkbC1zaG93LXN5bnRh Y3RpYy1pbmZvcm1hdGlvbiB0XSAoIkRvY3VtZW50YXRpb24iIFsiVkhETCBNb2RlIiB2aGRsLWRv Yy1tb2RlIDprZXlzICJDLWMgQy1oIl0gWyJSZXNlcnZlZCBXb3JkcyIgKHZoZGwtZG9jLXZhcmlh YmxlICd2aGRsLWRvYy1rZXl3b3JkcykgdF0gWyJDb2RpbmcgU3R5bGUiICh2aGRsLWRvYy12YXJp YWJsZSAndmhkbC1kb2MtY29kaW5nLXN0eWxlKSB0XSkgWyJWZXJzaW9uIiB2aGRsLXZlcnNpb24g dF0gWyJCdWcgUmVwb3J0Li4uIiB2aGRsLXN1Ym1pdC1idWctcmVwb3J0IHRdICgiU3BlZWRiYXIi IFsiT3Blbi9DbG9zZSIgdmhkbC1zcGVlZGJhciB0XSAiLS0iIFsiU2hvdyBIaWVyYXJjaHkiIHZo ZGwtc3BlZWRiYXItdG9nZ2xlLWhpZXJhcmNoeSA6c3R5bGUgdG9nZ2xlIDpzZWxlY3RlZCAoYW5k IChib3VuZHAgJ3NwZWVkYmFyLWluaXRpYWwtZXhwYW5zaW9uLWxpc3QtbmFtZSkgKGVxdWFsIHNw ZWVkYmFyLWluaXRpYWwtZXhwYW5zaW9uLWxpc3QtbmFtZSAidmhkbCBoaWVyYXJjaHkiKSkgOmFj dGl2ZSAoYW5kIChib3VuZHAgJ3NwZWVkYmFyLWZyYW1lKSBzcGVlZGJhci1mcmFtZSldKSAoIkN1 c3RvbWl6ZSIgWyJCcm93c2UgVkhETCBHcm91cC4uLiIgdmhkbC1jdXN0b21pemUgdF0gWyJCdWls ZCBDdXN0b21pemUgTWVudSIgdmhkbC1jcmVhdGUtY3VzdG9taXplLW1lbnUgKGZib3VuZHAgJ2N1 c3RvbWl6ZS1tZW51LWNyZWF0ZSldICItLSIgWyJBY3RpdmF0ZSBOZXcgQ3VzdG9taXphdGlvbnMi IHZoZGwtYWN0aXZhdGUtY3VzdG9taXphdGlvbnMgdF0pIHZoZGwtY29tcGlsZXItYWxpc3QgY29t cC1hbGlzdCBzdGFuZGFyZCB2aGRsLXN0YW5kYXJkIHggdmhkbC1tb2RlbC1hbGlzdCBtb2RlbCBt b2RlbC1hbGlzdCA6a2V5c10gMzEgKCMkIC4gNzE5NzUpXSkKI0AxNyBWSERMIE1vZGUgbWVudS4f CihkZWZ2YXIgdmhkbC1tb2RlLW1lbnUtbGlzdCAodmhkbC1jcmVhdGUtbW9kZS1tZW51KSAoIyQg LiA4MTI2NikpCiNAMjQgVXBkYXRlIFZIREwgbW9kZSBtZW51Lh8KKGRlZmFsaWFzICd2aGRsLXVw ZGF0ZS1tb2RlLW1lbnUgI1tuaWwgIlwzMDQIIVwyMTBcMzA1IBBcMzA2CCFcMjEwXDMwN1wzMDEh XDIwNBMAXDMxMBFcMzAxXG5CElwzMTFcMzAxXDMxMlwzMTMjXDIxMFwzMTRcMzAxC1wzMTMIJFwy MDciIFt2aGRsLW1vZGUtbWVudS1saXN0IHZoZGwtbW9kZS1tZW51IGN1cnJlbnQtbG9hZC1saXN0 IHZoZGwtbW9kZS1tYXAgZWFzeS1tZW51LXJlbW92ZSB2aGRsLWNyZWF0ZS1tb2RlLW1lbnUgZWFz eS1tZW51LWFkZCBib3VuZHAgbmlsIHB1dCB2YXJpYWJsZS1kb2N1bWVudGF0aW9uICJNZW51IGtl eW1hcCBmb3IgVkhETCBNb2RlLiIgZWFzeS1tZW51LWRvLWRlZmluZV0gNSAoIyQgLiA4MTM1NCkg bmlsXSkKKHJlcXVpcmUgJ2Vhc3ltZW51KQojQDc0IEltZW51IGdlbmVyaWMgZXhwcmVzc2lvbiBm b3IgVkhETCBNb2RlLiAgU2VlIGBpbWVudS1nZW5lcmljLWV4cHJlc3Npb24nLh8KKGRlZnZhciB2 aGRsLWltZW51LWdlbmVyaWMtZXhwcmVzc2lvbiAnKCgiU3VicHJvZ3JhbSIgIl5cXHMtKlxcKFxc KFxcKGltcHVyZVxcfHB1cmVcXClcXHMtK1xcfFxcKWZ1bmN0aW9uXFx8cHJvY2VkdXJlXFwpXFxz LStcXChcIj9cXChcXHdcXHxcXHNfXFwpK1wiP1xcKSIgNCkgKCJJbnN0YW5jZSIgIl5cXHMtKlxc KFxcKFxcd1xcfFxcc19cXCkrXFxzLSo6XFwoXFxzLVxcfFxuXFwpKlxcKFxcd1xcfFxcc19cXCkr XFwpXFwoXFxzLVxcfFxuXFwpK1xcKGdlbmVyaWNcXHxwb3J0XFwpXFxzLSttYXBcXD4iIDEpICgi Q29tcG9uZW50IiAiXlxccy0qXFwoY29tcG9uZW50XFwpXFxzLStcXChcXChcXHdcXHxcXHNfXFwp K1xcKSIgMikgKCJQcm9jZWR1cmFsIiAiXlxccy0qXFwoXFwoXFx3XFx8XFxzX1xcKStcXClcXHMt KjpcXChcXHMtXFx8XG5cXCkqXFwocHJvY2VkdXJhbFxcKSIgMSkgKCJQcm9jZXNzIiAiXlxccy0q XFwoXFwoXFx3XFx8XFxzX1xcKStcXClcXHMtKjpcXChcXHMtXFx8XG5cXCkqXFwoXFwocG9zdHBv bmVkXFxzLStcXHxcXClwcm9jZXNzXFwpIiAxKSAoIkJsb2NrIiAiXlxccy0qXFwoXFwoXFx3XFx8 XFxzX1xcKStcXClcXHMtKjpcXChcXHMtXFx8XG5cXCkqXFwoYmxvY2tcXCkiIDEpICgiUGFja2Fn ZSIgIl5cXHMtKlxcKHBhY2thZ2VcXCggYm9keVxcfFxcKVxcKVxccy0rXFwoXFwoXFx3XFx8XFxz X1xcKStcXCkiIDMpICgiQ29uZmlndXJhdGlvbiIgIl5cXHMtKlxcKGNvbmZpZ3VyYXRpb25cXClc XHMtK1xcKFxcKFxcd1xcfFxcc19cXCkrXFxzLStvZlxccy0rXFwoXFx3XFx8XFxzX1xcKStcXCki IDIpICgiQXJjaGl0ZWN0dXJlIiAiXlxccy0qXFwoYXJjaGl0ZWN0dXJlXFwpXFxzLStcXChcXChc XHdcXHxcXHNfXFwpK1xccy0rb2ZcXHMtK1xcKFxcd1xcfFxcc19cXCkrXFwpIiAyKSAoIkVudGl0 eSIgIl5cXHMtKlxcKGVudGl0eVxcKVxccy0rXFwoXFwoXFx3XFx8XFxzX1xcKStcXCkiIDIpKSAo IyQgLiA4MTc2OSkpCiNAMjQgSW5pdGlhbGl6ZSBpbmRleCBtZW51Lh8KKGRlZmFsaWFzICd2aGRs LWluZGV4LW1lbnUtaW5pdCAjW25pbCAiXDMwNFwzMDUhXDMwNkxcMjEwXDMwNFwzMDchCExcMjEw CVwyMDUsAFwzMTBcMzExXG5cIj9cMjA1LABcMzEyXDMwMyFcMjAzJQALXDMxMyBWXDIwMykAXDMx NFwzMTUhXDIwN1wzMTZcMzE3IVwyMDciIFt2aGRsLWltZW51LWdlbmVyaWMtZXhwcmVzc2lvbiB2 aGRsLWluZGV4LW1lbnUgZW1hY3MtdmVyc2lvbiBmb250LWxvY2stbWF4aW11bS1zaXplIG1ha2Ut bG9jYWwtdmFyaWFibGUgaW1lbnUtY2FzZS1mb2xkLXNlYXJjaCB0IGltZW51LWdlbmVyaWMtZXhw cmVzc2lvbiBzdHJpbmctbWF0Y2ggIlhFbWFjcyIgYm91bmRwIGJ1ZmZlci1zaXplIGltZW51LWFk ZC10by1tZW51YmFyICJJbmRleCIgbWVzc2FnZSAiU2Nhbm5pbmcgYnVmZmVyIGZvciBpbmRleC4u LmJ1ZmZlciB0b28gYmlnIl0gMyAoIyQgLiA4MjgzOSldKQooYnl0ZS1jb2RlICJcMzAyXDMwMCFc MjA0CABcMzAzEFwzMDAJQhFcMzAzXDIwNyIgW3ZoZGwtc291cmNlcy1tZW51IGN1cnJlbnQtbG9h ZC1saXN0IGJvdW5kcCBuaWxdIDIpCiNANzkgQ2FsbCBgZGlyZWN0b3J5LWZpbGVzJyBpZiBESVJF Q1RPUlkgZXhpc3RzLCBvdGhlcndpc2UgZ2VuZXJhdGUgZXJyb3IKbWVzc2FnZS4fCihkZWZhbGlh cyAndmhkbC1kaXJlY3RvcnktZmlsZXMgI1soZGlyZWN0b3J5ICZvcHRpb25hbCBmdWxsIG1hdGNo KSAiXDMwMwghXDIwM1xmAFwzMDQICVxuI1wyMDdcMzA1XDMwNghcIlwyMTBcMzA3XDIwNyIgW2Rp cmVjdG9yeSBmdWxsIG1hdGNoIGZpbGUtZGlyZWN0b3J5LXAgZGlyZWN0b3J5LWZpbGVzIG1lc3Nh Z2UgIk5vIHN1Y2ggZGlyZWN0b3J5OiBcIiVzXCIiIG5pbF0gNCAoIyQgLiA4MzQxOCldKQojQDY2 IEdldCBsaXN0IG9mIFZIREwgc291cmNlIGZpbGVzIGluIERJUkVDVE9SWSBvciBjdXJyZW50IGRp cmVjdG9yeS4fCihkZWZhbGlhcyAndmhkbC1nZXQtc291cmNlLWZpbGVzICNbKCZvcHRpb25hbCBm dWxsIGRpcmVjdG9yeSkgIghcMzA2GRpcMzA3EVxuXDIwMyAAXG5AQVwzMTA9XDIwMxkACVxuQEBc MzExURFcbkFcMjExElwyMDRcbgAJXDMxMlwzMTNcMzE0CVwiT1wzMTVQEVwzMTYLXDIwNjAAXGYN CSNcMjM3KlwyMDciIFthdXRvLW1vZGUtYWxpc3QgZmlsZW5hbWUtcmVnZXhwIG1vZGUtYWxpc3Qg ZGlyZWN0b3J5IGRlZmF1bHQtZGlyZWN0b3J5IGZ1bGwgbmlsICIuKlxcKCIgdmhkbC1tb2RlICJc XHwiIDAgc3RyaW5nLW1hdGNoICJcXFxcfCQiICJcXCkiIHZoZGwtZGlyZWN0b3J5LWZpbGVzXSA2 ICgjJCAuIDgzNzM0KV0pCiNAMTE0IFNjYW4gZGlyZWN0b3J5IGZvciBhbGwgVkhETCBzb3VyY2Ug ZmlsZXMgYW5kIGdlbmVyYXRlIG1lbnUuClRoZSBkaXJlY3Rvcnkgb2YgdGhlIGN1cnJlbnQgc291 cmNlIGZpbGUgaXMgc2Nhbm5lZC4fCihkZWZhbGlhcyAndmhkbC1hZGQtc291cmNlLWZpbGVzLW1l bnUgI1tuaWwgIlwzMDZcMzA3IVwyMTBcMzEwIAhcMzExIFwzMTJcMjExGRobHB1cMzEyEQtcMjAz KwBcMzEzEVwzMTQLQFwzMTULQERcMzEzI1xuQhILQVwyMTETXDIwNBYAXDMxNlxuXDMxN1wiEglc MjAzOABcMzIwXG5CElwzMjFcbkISXDMyMlxuQhJcMzIzXG4hXDIxMFwzMjRcMzI1IVwyMDRNAFwz MTIWFVwzMjUOG0IWG1wzMjZcMzI1XDMyN1wzMzAjXDIxMFwzMzFcMzI1DVwzMzBcbiRcMjEwLVwz MDZcMzMyIVwyMDciIFthdXRvLW1vZGUtYWxpc3QgZm91bmQgbWVudS1saXN0IGZpbGUtbGlzdCBt b2RlLWFsaXN0IG5ld21hcCBtZXNzYWdlICJTY2FubmluZyBkaXJlY3RvcnkgZm9yIHNvdXJjZSBm aWxlcyAuLi4iIGN1cnJlbnQtbG9jYWwtbWFwIHZoZGwtZ2V0LXNvdXJjZS1maWxlcyBuaWwgdCB2 ZWN0b3IgZmluZC1maWxlIHZoZGwtbWVudS1zcGxpdCAyNSAiLS0iIFsiKlJlc2NhbioiIHZoZGwt YWRkLXNvdXJjZS1maWxlcy1tZW51IHRdICJTb3VyY2VzIiBlYXN5LW1lbnUtYWRkIGJvdW5kcCB2 aGRsLXNvdXJjZXMtbWVudSBwdXQgdmFyaWFibGUtZG9jdW1lbnRhdGlvbiAiVkhETCBzb3VyY2Ug ZmlsZXMgbWVudSIgZWFzeS1tZW51LWRvLWRlZmluZSAiIiBjdXJyZW50LWxvYWQtbGlzdF0gNiAo IyQgLiA4NDE1NCkgbmlsXSkKI0A2OCBTcGxpdCBtZW51IExJU1QgaW50byBzZXZlcmFsIHN1Ym1l bnVlcywgaWYgbnVtYmVyIG9mIGVsZW1lbnRzID4gTi4fCihkZWZhbGlhcyAndmhkbC1tZW51LXNw bGl0ICNbKGxpc3QgbikgIghHCVZcMjAzUQAIXDMwNlwyMTFcMzA3XDMxMBobHB0eCw4LXDIwMz8A DgtAXGZCFA4LQRYLXG5UXDIxMRIJVVwyMDMSAFwzMTFcMzEyC1wiXGZcMjM3Qg1CFVwzMTASC1QT XDMwNhRcMjAyEgBcZlwyMDNNAFwzMTFcMzEyC1wiXGZcMjM3Qg1CFQ1cMjM3LVwyMDcIXDIwNyIg W2xpc3QgbiBpIG1lbnVubyBzdWJsaXN0IHJlc3VsdCBuaWwgMSAwIGZvcm1hdCAiU291cmNlcyAl cyIgcmVtYWluXSA2ICgjJCAuIDg0OTUzKV0pCiNAMTUwMDMgTWFqb3IgbW9kZSBmb3IgZWRpdGlu ZyBWSERMIGNvZGUuCgpVc2FnZToKLS0tLS0tCgotIFRFTVBMQVRFIElOU0VSVElPTiAoZWxlY3Ry aWZpY2F0aW9uKTogIEFmdGVyIHR5cGluZyBhIFZIREwga2V5d29yZCBhbmQKICBlbnRlcmluZyBg XFt2aGRsLWVsZWN0cmljLXNwYWNlXScsIHlvdSBhcmUgcHJvbXB0ZWQgZm9yIGFyZ3VtZW50cyB3 aGlsZSBhIHRlbXBsYXRlIGlzIGdlbmVyYXRlZAogIGZvciB0aGF0IFZIREwgY29uc3RydWN0LiAg VHlwaW5nIGBcW3ZoZGwtZWxlY3RyaWMtcmV0dXJuXScgb3IgYFxba2V5Ym9hcmQtcXVpdF0nIGF0 IHRoZSBmaXJzdCAobWFuZGF0b3J5KQogIHByb21wdCBhYm9ydHMgdGhlIGN1cnJlbnQgdGVtcGxh dGUgZ2VuZXJhdGlvbi4gIE9wdGlvbmFsIGFyZ3VtZW50cyBhcmUKICBpbmRpY2F0ZWQgYnkgc3F1 YXJlIGJyYWNrZXRzIGFuZCByZW1vdmVkIGlmIHRoZSBxdWVyaWVkIHN0cmluZyBpcyBsZWZ0IGVt cHR5LgogIFByb21wdHMgZm9yIG1hbmRhdG9yeSBhcmd1bWVudHMgcmVtYWluIGluIHRoZSBjb2Rl IGlmIHRoZSBxdWVyaWVkIHN0cmluZyBpcwogIGxlZnQgZW1wdHkuICBUaGV5IGNhbiBiZSBxdWVy aWVkIGFnYWluIGJ5IGBcW3ZoZGwtdGVtcGxhdGUtc2VhcmNoLXByb21wdF0nLgogIFR5cGluZyBg XFtqdXN0LW9uZS1zcGFjZV0nIGFmdGVyIGEga2V5d29yZCBpbnNlcnRzIGEgc3BhY2Ugd2l0aG91 dCBjYWxsaW5nIHRoZSB0ZW1wbGF0ZQogIGdlbmVyYXRvci4gIEF1dG9tYXRpYyB0ZW1wbGF0ZSBn ZW5lcmF0aW9uIChpLmUuIGVsZWN0cmlmaWNhdGlvbikgY2FuIGJlCiAgZGlzYWJsZWQgKGVuYWJs ZWQpIGJ5IHR5cGluZyBgXFt2aGRsLWVsZWN0cmljLW1vZGVdJyBvciBieSBzZXR0aW5nIGN1c3Rv bSB2YXJpYWJsZQogIGB2aGRsLWVsZWN0cmljLW1vZGUnIChzZWUgQ1VTVE9NSVpBVElPTikuCiAg RW5hYmxlZCBlbGVjdHJpZmljYXRpb24gaXMgaW5kaWNhdGVkIGJ5IGAvZScgaW4gdGhlIG1vZGVs aW5lLgogIFRlbXBsYXRlIGdlbmVyYXRvcnMgY2FuIGJlIGludm9rZWQgZnJvbSB0aGUgVkhETCBt ZW51LCBieSBrZXkgYmluZGluZ3MsIGJ5CiAgdHlwaW5nIGBDLWMgQy1pIEMtYycgYW5kIGNob29z aW5nIGEgY29uc3RydWN0LCBvciBieSB0eXBpbmcgdGhlIGtleXdvcmQgKGkuZS4KICBmaXJzdCB3 b3JkIG9mIG1lbnUgZW50cnkgbm90IGluIHBhcmVudGhlc2lzKSBhbmQgYFxbdmhkbC1lbGVjdHJp Yy1zcGFjZV0nLgogIFRoZSBmb2xsb3dpbmcgYWJicmV2aWF0aW9ucyBjYW4gYWxzbyBiZSB1c2Vk OgogIGFyY2gsIGF0dHIsIGNvbmQsIGNvbmYsIGNvbXAsIGNvbnMsIGZ1bmMsIGluc3QsIHBhY2ss IHNpZywgdmFyLgogIFRlbXBsYXRlIHN0eWxlcyBjYW4gYmUgY3VzdG9taXplZCBpbiBjdXN0b21p emF0aW9uIGdyb3VwIGB2aGRsLWVsZWN0cmljJwogIChzZWUgQ1VTVE9NSVpBVElPTikuCgotIEhF QURFUiBJTlNFUlRJT046ICBBIGZpbGUgaGVhZGVyIGNhbiBiZSBpbnNlcnRlZCBieSBgXFt2aGRs LXRlbXBsYXRlLWhlYWRlcl0nLiAgQQogIGZpbGUgZm9vdGVyICh0ZW1wbGF0ZSBhdCB0aGUgZW5k IG9mIHRoZSBmaWxlKSBjYW4gYmUgaW5zZXJ0ZWQgYnkKICBgXFt2aGRsLXRlbXBsYXRlLWZvb3Rl cl0nLiAgU2VlIGN1c3RvbWl6YXRpb24gZ3JvdXAgYHZoZGwtaGVhZGVyJy4KCi0gU1RVVFRFUklO RzogIERvdWJsZSBzdHJpa2luZyBvZiBzb21lIGtleXMgaW5zZXJ0cyBjdW1iZXJzb21lIFZIREwg c3ludGF4CiAgZWxlbWVudHMuICBTdHV0dGVyaW5nIGNhbiBiZSBkaXNhYmxlZCAoZW5hYmxlZCkg YnkgdHlwaW5nIGBcW3ZoZGwtc3R1dHRlci1tb2RlXScgb3IgYnkKICB2YXJpYWJsZSBgdmhkbC1z dHV0dGVyLW1vZGUnLiAgRW5hYmxlZCBzdHV0dGVyaW5nIGlzIGluZGljYXRlZCBieSBgL3MnIGlu CiAgdGhlIG1vZGVsaW5lLiAgVGhlIHN0dXR0ZXJpbmcga2V5cyBhbmQgdGhlaXIgZWZmZWN0cyBh cmU6CiAgICAgIDs7ICAgLS0+ICAiIDogIiAgICAgICAgIFsgICAtLT4gICggICAgICAgIC0tICAg IC0tPiAgY29tbWVudAogICAgICA7OzsgIC0tPiAgIiA6PSAiICAgICAgICBbWyAgLS0+ICBbICAg ICAgICAtLUNSICAtLT4gIGNvbW1lbnQtb3V0IGNvZGUKICAgICAgLi4gICAtLT4gICIgPT4gIiAg ICAgICAgXSAgIC0tPiAgKSAgICAgICAgLS0tICAgLS0+ICBob3Jpem9udGFsIGxpbmUKICAgICAg LCwgICAtLT4gICIgPD0gIiAgICAgICAgXV0gIC0tPiAgXSAgICAgICAgLS0tLSAgLS0+ICBkaXNw bGF5IGNvbW1lbnQKICAgICAgPT0gICAtLT4gICIgPT0gIiAgICAgICAgJycgIC0tPiAgXCIKCi0g V09SRCBDT01QTEVUSU9OOiAgVHlwaW5nIGBcW3ZoZGwtZWxlY3RyaWMtdGFiXScgYWZ0ZXIgYSAo bm90IGNvbXBsZXRlZCkgd29yZCBsb29rcyBmb3IgYSBWSERMCiAga2V5d29yZCBvciBhIHdvcmQg aW4gdGhlIGJ1ZmZlciB0aGF0IHN0YXJ0cyBhbGlrZSwgaW5zZXJ0cyBpdCBhbmQgYWRqdXN0cwog IGNhc2UuICBSZS10eXBpbmcgYFxbdmhkbC1lbGVjdHJpYy10YWJdJyB0b2dnbGVzIHRocm91Z2gg YWx0ZXJuYXRpdmUgd29yZCBjb21wbGV0aW9ucy4KICBUaGlzIGFsc28gd29ya3MgaW4gdGhlIG1p bmlidWZmZXIgKGkuZS4gaW4gdGVtcGxhdGUgZ2VuZXJhdG9yIHByb21wdHMpLgogIFR5cGluZyBg XFt2aGRsLWVsZWN0cmljLXRhYl0nIGFmdGVyIGAoJyBsb29rcyBmb3IgYW5kIGluc2VydHMgY29t cGxldGUgcGFyZW50aGVzaXplZAogIGV4cHJlc3Npb25zIChlLmcuIGZvciBhcnJheSBpbmRleCBy YW5nZXMpLiAgQWxsIGtleXdvcmRzIGFzIHdlbGwgYXMgc3RhbmRhcmQKICB0eXBlcyBhbmQgc3Vi cHJvZ3JhbXMgb2YgVkhETCBoYXZlIHByZWRlZmluZWQgYWJicmV2aWF0aW9ucyAoZS5nLiB0eXBl ICJzdGQiCiAgYW5kIGBcW3ZoZGwtZWxlY3RyaWMtdGFiXScgd2lsbCB0b2dnbGUgdGhyb3VnaCBh bGwgc3RhbmRhcmQgdHlwZXMgYmVnaW5uaW5nIHdpdGggInN0ZCIpLgoKICBUeXBpbmcgYFxbdmhk bC1lbGVjdHJpYy10YWJdJyBhZnRlciBhIG5vbi13b3JkIGNoYXJhY3RlciBpbmRlbnRzIHRoZSBs aW5lIGlmIGF0IHRoZSBiZWdpbm5pbmcKICBvZiBhIGxpbmUgKGkuZS4gbm8gcHJlY2VkaW5nIG5v bi1ibGFuayBjaGFyYWN0ZXJzKSxhbmQgaW5zZXJ0cyBhIHRhYnVsYXRvcgogIHN0b3Agb3RoZXJ3 aXNlLiAgYFxbdGFiLXRvLXRhYi1zdG9wXScgYWx3YXlzIGluc2VydHMgYSB0YWJ1bGF0b3Igc3Rv cC4KCi0gQ09NTUVOVFM6CiAgICAgIGAtLScgICAgICAgcHV0cyBhIHNpbmdsZSBjb21tZW50Lgog ICAgICBgLS0tJyAgICAgIGRyYXdzIGEgaG9yaXpvbnRhbCBsaW5lIGZvciBzZXBhcmF0aW5nIGNv ZGUgc2VnbWVudHMuCiAgICAgIGAtLS0tJyAgICAgaW5zZXJ0cyBhIGRpc3BsYXkgY29tbWVudCwg aS5lLiB0d28gaG9yaXpvbnRhbCBsaW5lcyB3aXRoIGEKICAgICAgICAgICAgICAgICBjb21tZW50 IGluIGJldHdlZW4uCiAgICAgIGAtLUNSJyAgICAgY29tbWVudHMgb3V0IGNvZGUgb24gdGhhdCBs aW5lLiAgUmUtaGl0dGluZyBDUiBjb21tZW50cyBvdXQKICAgICAgICAgICAgICAgICBmb2xsb3dp bmcgbGluZXMuCiAgICAgIGBcW3ZoZGwtY29tbWVudC11bmNvbW1lbnQtcmVnaW9uXScgIGNvbW1l bnRzIG91dCBhIHJlZ2lvbiBpZiBub3QgY29tbWVudGVkIG91dCwKICAgICAgICAgICAgICAgICB1 bmNvbW1lbnRzIGEgcmVnaW9uIGlmIGFscmVhZHkgY29tbWVudGVkIG91dC4KCiAgWW91IGFyZSBw cm9tcHRlZCBmb3IgY29tbWVudHMgYWZ0ZXIgb2JqZWN0IGRlZmluaXRpb25zIChpLmUuIHNpZ25h bHMsCiAgdmFyaWFibGVzLCBjb25zdGFudHMsIHBvcnRzKSBhbmQgYWZ0ZXIgc3VicHJvZ3JhbSBh bmQgcHJvY2VzcyBzcGVjaWZpY2F0aW9ucwogIGlmIHZhcmlhYmxlIGB2aGRsLXByb21wdC1mb3It Y29tbWVudHMnIGlzIG5vbi1uaWwuICBDb21tZW50cyBhcmUKICBhdXRvbWF0aWNhbGx5IGluc2Vy dGVkIGFzIGFkZGl0aW9uYWwgbGFiZWxzIChlLmcuIGFmdGVyIGJlZ2luIHN0YXRlbWVudHMpIGFu ZAogIGFzIGhlbHAgY29tbWVudHMgaWYgYHZoZGwtc2VsZi1pbnNlcnQtY29tbWVudHMnIGlzIG5v bi1uaWwuCiAgSW5saW5lIGNvbW1lbnRzIChpLmUuIGNvbW1lbnRzIGFmdGVyIGEgcGllY2Ugb2Yg Y29kZSBvbiB0aGUgc2FtZSBsaW5lKSBhcmUKICBpbmRlbnRlZCBhdCBsZWFzdCB0byBgdmhkbC1p bmxpbmUtY29tbWVudC1jb2x1bW4nLiAgQ29tbWVudHMgZ28gYXQgbWF4aW11bSB0bwogIGB2aGRs LWVuZC1jb21tZW50LWNvbHVtbicuICBgXFt2aGRsLWVsZWN0cmljLXJldHVybl0nIGFmdGVyIGEg c3BhY2UgaW4gYSBjb21tZW50IHdpbGwgb3BlbiBhCiAgbmV3IGNvbW1lbnQgbGluZS4gIFR5cGlu ZyBiZXlvbmQgYHZoZGwtZW5kLWNvbW1lbnQtY29sdW1uJyBpbiBhIGNvbW1lbnQKICBhdXRvbWF0 aWNhbGx5IG9wZW5zIGEgbmV3IGNvbW1lbnQgbGluZS4gIGBcW2ZpbGwtcGFyYWdyYXBoXScgcmUt ZmlsbHMKICBtdWx0aS1saW5lIGNvbW1lbnRzLgoKLSBJTkRFTlRBVElPTjogIGBcW3ZoZGwtZWxl Y3RyaWMtdGFiXScgaW5kZW50cyBhIGxpbmUgaWYgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgbGlu ZS4KICBUaGUgYW1vdW50IG9mIGluZGVudGF0aW9uIGlzIHNwZWNpZmllZCBieSB2YXJpYWJsZSBg dmhkbC1iYXNpYy1vZmZzZXQnLgogIGBcW3ZoZGwtaW5kZW50LWxpbmVdJyBhbHdheXMgaW5kZW50 cyB0aGUgY3VycmVudCBsaW5lIChpcyBib3VuZCB0byBgVEFCJyBpZiB2YXJpYWJsZQogIGB2aGRs LWludGVsbGlnZW50LXRhYicgaXMgbmlsKS4gIEluZGVudGF0aW9uIGNhbiBiZSBkb25lIGZvciBh biBlbnRpcmUgcmVnaW9uCiAgKGBcW3ZoZGwtaW5kZW50LXJlZ2lvbl0nKSBvciBidWZmZXIgKG1l bnUpLiAgQXJndW1lbnQgYW5kIHBvcnQgbGlzdHMgYXJlIGluZGVudGVkIG5vcm1hbGx5CiAgKG5p bCkgb3IgcmVsYXRpdmUgdG8gdGhlIG9wZW5pbmcgcGFyZW50aGVzaXMgKG5vbi1uaWwpIGFjY29y ZGluZyB0byB2YXJpYWJsZQogIGB2aGRsLWFyZ3VtZW50LWxpc3QtaW5kZW50Jy4gIElmIHZhcmlh YmxlIGB2aGRsLWluZGVudC10YWJzLW1vZGUnIGlzIG5pbCwKICBzcGFjZXMgYXJlIHVzZWQgaW5z dGVhZCBvZiB0YWJzLiAgYFxbdGFiaWZ5XScgYW5kIGBcW3VudGFiaWZ5XScgYWxsb3cKICB0byBj b252ZXJ0IHNwYWNlcyB0byB0YWJzIGFuZCB2aWNlIHZlcnNhLgoKLSBBTElHTk1FTlQ6ICBUaGUg YWxpZ25tZW50IGZ1bmN0aW9ucyBhbGlnbiBvcGVyYXRvcnMsIGtleXdvcmRzLCBhbmQgaW5saW5l CiAgY29tbWVudCB0byBiZWF1dGlmeSBhcmd1bWVudCBsaXN0cywgcG9ydCBtYXBzLCBldGMuICBg XFt2aGRsLWFsaWduLWdyb3VwXScgYWxpZ25zIGEgZ3JvdXAKICBvZiBjb25zZWN1dGl2ZSBsaW5l cyBzZXBhcmF0ZWQgYnkgYmxhbmsgbGluZXMuICBgXFt2aGRsLWFsaWduLW5vaW5kZW50LXJlZ2lv bl0nIGFsaWducyBhbgogIGVudGlyZSByZWdpb24uICBJZiB2YXJpYWJsZSBgdmhkbC1hbGlnbi1n cm91cHMnIGlzIG5vbi1uaWwsIGdyb3VwcyBvZiBjb2RlCiAgbGluZXMgc2VwYXJhdGVkIGJ5IGVt cHR5IGxpbmVzIGFyZSBhbGlnbmVkIGluZGl2aWR1YWxseS4gIGBcW3ZoZGwtYWxpZ24taW5saW5l LWNvbW1lbnQtZ3JvdXBdJyBhbGlnbnMKICBpbmxpbmUgY29tbWVudHMgZm9yIGEgZ3JvdXAgb2Yg bGluZXMsIGFuZCBgXFt2aGRsLWFsaWduLWlubGluZS1jb21tZW50LXJlZ2lvbl0nIGZvciBhIHJl Z2lvbi4KICBTb21lIHRlbXBsYXRlcyBhcmUgYXV0b21hdGljYWxseSBhbGlnbmVkIGFmdGVyIGdl bmVyYXRpb24gaWYgY3VzdG9tIHZhcmlhYmxlCiAgYHZoZGwtYXV0by1hbGlnbicgaXMgbm9uLW5p bC4KICBgXFt2aGRsLWZpeHVwLXdoaXRlc3BhY2UtcmVnaW9uXScgZml4ZXMgdXAgd2hpdGVzcGFj ZSBpbiBhIHJlZ2lvbi4gIFRoYXQgaXMsIG9wZXJhdG9yIHN5bWJvbHMKICBhcmUgc3Vycm91bmRl ZCBieSBvbmUgc3BhY2UsIGFuZCBtdWx0aXBsZSBzcGFjZXMgYXJlIGVsaW1pbmF0ZWQuCgotIFBP UlQgVFJBTlNMQVRJT046ICBHZW5lcmljIGFuZCBwb3J0IGNsYXVzZXMgZnJvbSBlbnRpdHkgb3Ig Y29tcG9uZW50CiAgZGVjbGFyYXRpb25zIGNhbiBiZSBjb3BpZWQgKGBcW3ZoZGwtcG9ydC1jb3B5 XScpIGFuZCBwYXN0ZWQgYXMgZW50aXR5IGFuZAogIGNvbXBvbmVudCBkZWNsYXJhdGlvbnMsIGFz IGNvbXBvbmVudCBpbnN0YW50aWF0aW9ucyBhbmQgY29ycmVzcG9uZGluZwogIGludGVybmFsIGNv bnN0YW50cyBhbmQgc2lnbmFscywgYXMgYSBnZW5lcmljIG1hcCB3aXRoIGNvbnN0YW50cyBhcyBh Y3R1YWwKICBwYXJhbWV0ZXJzLCBhbmQgYXMgYSB0ZXN0IGJlbmNoIChtZW51KS4KICBBIGNsYXVz ZSB3aXRoIHNldmVyYWwgZ2VuZXJpYy9wb3J0IG5hbWVzIG9uIHRoZSBzYW1lIGxpbmUgY2FuIGJl IGZsYXR0ZW5lZAogIChgXFt2aGRsLXBvcnQtZmxhdHRlbl0nKSBzbyB0aGF0IG9ubHkgb25lIG5h bWUgcGVyIGxpbmUgZXhpc3RzLiAgTmFtZXMgZm9yIGFjdHVhbAogIHBvcnRzLCBpbnN0YW5jZXMs IHRlc3QgYmVuY2hlcywgYW5kIGRlc2lnbi11bmRlci10ZXN0IGluc3RhbmNlcyBjYW4gYmUKICBk ZXJpdmVkIGZyb20gZXhpc3RpbmcgbmFtZXMgYWNjb3JkaW5nIHRvIHZhcmlhYmxlcyBgdmhkbC0u Li4tbmFtZScuCiAgVmFyaWFibGVzIGB2aGRsLXRlc3RiZW5jaC0uLi4nIGFsbG93IHRoZSBpbnNl cnRpb24gb2YgYWRkaXRpb25hbCB0ZW1wbGF0ZXMKICBpbnRvIGEgdGVzdCBiZW5jaC4gIE5ldyBm aWxlcyBhcmUgY3JlYXRlZCBmb3IgdGhlIHRlc3QgYmVuY2ggZW50aXR5IGFuZAogIGFyY2hpdGVj dHVyZSBhY2NvcmRpbmcgdG8gdmFyaWFibGUgYHZoZGwtdGVzdGJlbmNoLWNyZWF0ZS1maWxlcycu CiAgU2VlIGN1c3RvbWl6YXRpb24gZ3JvdXAgYHZoZGwtcG9ydCcuCgotIFRFU1QgQkVOQ0ggR0VO RVJBVElPTjogIFNlZSBQT1JUIFRSQU5TTEFUSU9OLgoKLSBLRVkgQklORElOR1M6ICBLZXkgYmlu ZGluZ3MgKGBDLWMgLi4uJykgZXhpc3QgZm9yIG1vc3QgY29tbWFuZHMgKHNlZSBpbgogIG1lbnUp LgoKLSBWSERMIE1FTlU6ICBBbGwgY29tbWFuZHMgY2FuIGJlIGludm9rZWQgZnJvbSB0aGUgVkhE TCBtZW51LgoKLSBGSUxFIEJST1dTRVI6ICBUaGUgc3BlZWRiYXIgYWxsb3dzIGJyb3dzaW5nIG9m IGRpcmVjdG9yaWVzIGFuZCBmaWxlIGNvbnRlbnRzLgogIEl0IGNhbiBiZSBhY2Nlc3NlZCBmcm9t IHRoZSBWSERMIG1lbnUgYW5kIGlzIGF1dG9tYXRpY2FsbHkgb3BlbmVkIGlmCiAgdmFyaWFibGUg YHZoZGwtc3BlZWRiYXInIGlzIG5vbi1uaWwuCiAgSW4gc3BlZWRiYXIsIG9wZW4gZmlsZXMgYW5k IGRpcmVjdG9yaWVzIHdpdGggYG1vdXNlLTInIG9uIHRoZSBuYW1lIGFuZAogIGJyb3dzZS9yZXNj YW4gdGhlaXIgY29udGVudHMgd2l0aCBgbW91c2UtMicvYFMtbW91c2UtMicgb24gdGhlIGArJy4K Ci0gREVTSUdOIEhJRVJBUkNIWSBCUk9XU0VSOiAgVGhlIHNwZWVkYmFyIGNhbiBhbHNvIGJlIHVz ZWQgZm9yIGJyb3dzaW5nIHRoZQogIGhpZXJhcmNoeSBvZiBkZXNpZ24gdW5pdHMgY29udGFpbmVk IGluIHRoZSBzb3VyY2UgZmlsZXMgb2YgdGhlIGN1cnJlbnQKICBkaXJlY3Rvcnkgb3IgaW4gdGhl IHNvdXJjZSBmaWxlcy9kaXJlY3RvcmllcyBzcGVjaWZpZWQgZm9yIGEgcHJvamVjdCAoc2VlCiAg dmFyaWFibGUgYHZoZGwtcHJvamVjdC1hbGlzdCcpLgogIFRoZSBzcGVlZGJhciBjYW4gYmUgc3dp dGNoZWQgYmV0d2VlbiBmaWxlIGFuZCBoaWVyYXJjaHkgYnJvd3NpbmcgbW9kZSBpbiB0aGUKICBW SERMIG1lbnUgb3IgYnkgdHlwaW5nIGBmJyBhbmQgYGgnIGluIHNwZWVkYmFyLgogIEluIHNwZWVk YmFyLCBvcGVuIGRlc2lnbiB1bml0cyB3aXRoIGBtb3VzZS0yJyBvbiB0aGUgbmFtZSBhbmQgYnJv d3NlIHRoZWlyCiAgaGllcmFyY2h5IHdpdGggYG1vdXNlLTInIG9uIHRoZSBgKycuICBUaGUgaGll cmFyY2h5IGNhbiBiZSByZXNjYW5uZWQgYW5kCiAgcG9ydHMgZGlyZWN0bHkgYmUgY29waWVkIGZy b20gZW50aXRpZXMgYnkgdXNpbmcgdGhlIHNwZWVkYmFyIG1lbnUuCgotIFBST0pFQ1RTOiAgUHJv amVjdHMgY2FuIGJlIGRlZmluZWQgaW4gdmFyaWFibGUgYHZoZGwtcHJvamVjdC1hbGlzdCcgYW5k IGEKICBjdXJyZW50IHByb2plY3QgYmUgc2VsZWN0ZWQgdXNpbmcgdmFyaWFibGUgYHZoZGwtcHJv amVjdCcgKHBlcm1hbmVudGx5KSBvcgogIGZyb20gdGhlIG1lbnUgKHRlbXBvcmFyaWx5KS4gIEZv ciBlYWNoIHByb2plY3QsIGEgdGl0bGUgc3RyaW5nIChmb3IgdGhlIGZpbGUKICBoZWFkZXJzKSBh bmQgc291cmNlIGZpbGVzL2RpcmVjdG9yaWVzIChmb3IgdGhlIGhpZXJhcmNoeSBicm93c2VyKSBj YW4gYmUKICBzcGVjaWZpZWQuCgotIFNQRUNJQUwgTUVOVUVTOiAgQXMgYW4gYWx0ZXJuYXRpdmUg dG8gdGhlIHNwZWVkYmFyLCBhbiBpbmRleCBtZW51IGNhbgogIGJlIGFkZGVkIChzZXQgdmFyaWFi bGUgYHZoZGwtaW5kZXgtbWVudScgdG8gbm9uLW5pbCkgb3IgbWFkZSBhY2Nlc3NpYmxlCiAgYXMg YSBtb3VzZSBtZW51IChlLmcuIGFkZCAiKGdsb2JhbC1zZXQta2V5ICdbUy1kb3duLW1vdXNlLTNd ICdpbWVudSkiIHRvCiAgeW91ciBzdGFydC11cCBmaWxlKSBmb3IgYnJvd3NpbmcgdGhlIGZpbGUg Y29udGVudHMuICBBbHNvLCBhIHNvdXJjZSBmaWxlIG1lbnUKICBjYW4gYmUgYWRkZWQgKHNldCB2 YXJpYWJsZSBgdmhkbC1zb3VyY2UtZmlsZS1tZW51JyB0byBub24tbmlsKSBmb3IgYnJvd3NpbmcK ICB0aGUgY3VycmVudCBkaXJlY3RvcnkgZm9yIFZIREwgc291cmNlIGZpbGVzLgoKLSBTT1VSQ0Ug RklMRSBDT01QSUxBVElPTjogIFRoZSBzeW50YXggb2YgdGhlIGN1cnJlbnQgYnVmZmVyIGNhbiBi ZSBhbmFseXplZAogIGJ5IGNhbGxpbmcgYSBWSERMIGNvbXBpbGVyIChtZW51LCBgXFt2aGRsLWNv bXBpbGVdJykuICBUaGUgY29tcGlsZXIgdG8gYmUgdXNlZCBpcwogIHNwZWNpZmllZCBieSB2YXJp YWJsZSBgdmhkbC1jb21waWxlcicuICBUaGUgYXZhaWxhYmxlIGNvbXBpbGVycyBhcmUgbGlzdGVk CiAgaW4gdmFyaWFibGUgYHZoZGwtY29tcGlsZXItYWxpc3QnIGluY2x1ZGluZyBhbGwgcmVxdWly ZWQgY29tcGlsYXRpb24gY29tbWFuZCwKICBkZXN0aW5hdGlvbiBkaXJlY3RvcnksIGFuZCBlcnJv ciBtZXNzYWdlIHN5bnRheCBpbmZvcm1hdGlvbi4gIE5ldyBjb21waWxlcnMKICBjYW4gYmUgYWRk ZWQuICBBZGRpdGlvbmFsIGNvbXBpbGUgY29tbWFuZCBvcHRpb25zIGNhbiBiZSBzZXQgaW4gdmFy aWFibGUKICBgdmhkbC1jb21waWxlci1vcHRpb25zJy4KICBBbiBlbnRpcmUgaGllcmFyY2h5IG9m IHNvdXJjZSBmaWxlcyBjYW4gYmUgY29tcGlsZWQgYnkgdGhlIGBtYWtlJyBjb21tYW5kCiAgKG1l bnUsIGBcW3ZoZGwtbWFrZV0nKS4gIFRoaXMgb25seSB3b3JrcyBpZiBhbiBhcHByb3ByaWF0ZSBN YWtlZmlsZSBleGlzdHMuCiAgVGhlIG1ha2UgY29tbWFuZCBpdHNlbGYgYXMgd2VsbCBhcyBhIGNv bW1hbmQgdG8gZ2VuZXJhdGUgYSBNYWtlZmlsZSBjYW4gYWxzbwogIGJlIHNwZWNpZmllZCBpbiB2 YXJpYWJsZSBgdmhkbC1jb21waWxlci1hbGlzdCcuCgotIFZIREwgU1RBTkRBUkRTOiAgVGhlIFZI REwgc3RhbmRhcmRzIHRvIGJlIHVzZWQgYXJlIHNwZWNpZmllZCBpbiB2YXJpYWJsZQogIGB2aGRs LXN0YW5kYXJkJy4gIEF2YWlsYWJsZSBzdGFuZGFyZHMgYXJlOiBWSERMJzg3Lyc5MywgVkhETC1B TVMsCiAgTWF0aCBQYWNrYWdlcy4KCi0gS0VZV09SRCBDQVNFOiAgTG93ZXIgYW5kIHVwcGVyIGNh c2UgZm9yIGtleXdvcmRzIGFuZCBzdGFuZGFyZGl6ZWQgdHlwZXMsCiAgYXR0cmlidXRlcywgYW5k IGVudW1lcmF0aW9uIHZhbHVlcyBpcyBzdXBwb3J0ZWQuICBJZiB0aGUgdmFyaWFibGUKICBgdmhk bC11cHBlci1jYXNlLWtleXdvcmRzJyBpcyBzZXQgdG8gbm9uLW5pbCwga2V5d29yZHMgY2FuIGJl IHR5cGVkIGluIGxvd2VyCiAgY2FzZSBhbmQgYXJlIGNvbnZlcnRlZCBpbnRvIHVwcGVyIGNhc2Ug YXV0b21hdGljYWxseSAobm90IGZvciB0eXBlcywKICBhdHRyaWJ1dGVzLCBhbmQgZW51bWVyYXRp b24gdmFsdWVzKS4gIFRoZSBjYXNlIG9mIGtleXdvcmRzLCB0eXBlcywKICBhdHRyaWJ1dGVzLGFu ZCBlbnVtZXJhdGlvbiB2YWx1ZXMgY2FuIGJlIGZpeGVkIGZvciBhbiBlbnRpcmUgcmVnaW9uICht ZW51KQogIG9yIGJ1ZmZlciAoYFxbdmhkbC1maXgtY2FzZS1idWZmZXJdJykgYWNjb3JkaW5nIHRv IHRoZSB2YXJpYWJsZXMKICBgdmhkbC11cHBlci1jYXNlLXtrZXl3b3Jkcyx0eXBlcyxhdHRyaWJ1 dGVzLGVudW0tdmFsdWVzfScuCgotIEhJR0hMSUdIVElORyAoZm9udGlmaWNhdGlvbik6ICBLZXl3 b3JkcyBhbmQgc3RhbmRhcmRpemVkIHR5cGVzLCBhdHRyaWJ1dGVzLAogIGVudW1lcmF0aW9uIHZh bHVlcywgYW5kIGZ1bmN0aW9uIG5hbWVzIChjb250cm9sbGVkIGJ5IHZhcmlhYmxlCiAgYHZoZGwt aGlnaGxpZ2h0LWtleXdvcmRzJyksIGFzIHdlbGwgYXMgY29tbWVudHMsIHN0cmluZ3MsIGFuZCB0 ZW1wbGF0ZQogIHByb21wdHMgYXJlIGhpZ2hsaWdodGVkIHVzaW5nIGRpZmZlcmVudCBjb2xvcnMu ICBVbml0LCBzdWJwcm9ncmFtLCBzaWduYWwsCiAgdmFyaWFibGUsIGNvbnN0YW50LCBwYXJhbWV0 ZXIgYW5kIGdlbmVyaWMvcG9ydCBuYW1lcyBpbiBkZWNsYXJhdGlvbnMgYXMgd2VsbAogIGFzIGxh YmVscyBhcmUgaGlnaGxpZ2h0ZWQgaWYgdmFyaWFibGUgYHZoZGwtaGlnaGxpZ2h0LW5hbWVzJyBp cyBub24tbmlsLgoKICBBZGRpdGlvbmFsIHJlc2VydmVkIHdvcmRzIG9yIHdvcmRzIHdpdGggYSBm b3JiaWRkZW4gc3ludGF4IChlLmcuIHdvcmRzIHRoYXQKICBzaG91bGQgYmUgYXZvaWRlZCkgY2Fu IGJlIHNwZWNpZmllZCBpbiB2YXJpYWJsZSBgdmhkbC1mb3JiaWRkZW4td29yZHMnIG9yCiAgYHZo ZGwtZm9yYmlkZGVuLXN5bnRheCcgYW5kIGJlIGhpZ2hsaWdodGVkIGluIGEgd2FybmluZyBjb2xv ciAodmFyaWFibGUKICBgdmhkbC1oaWdobGlnaHQtZm9yYmlkZGVuLXdvcmRzJykuICBWZXJpbG9n IGtleXdvcmRzIGFyZSBoaWdobGlnaHRlZCBhcwogIGZvcmJpZGRlbiB3b3JkcyBpZiB2YXJpYWJs ZSBgdmhkbC1oaWdobGlnaHQtdmVyaWxvZy1rZXl3b3JkcycgaXMgbm9uLW5pbC4KCiAgV29yZHMg d2l0aCBzcGVjaWFsIHN5bnRheCBjYW4gYmUgaGlnaGxpZ2h0ZWQgYnkgc3BlY2lmeWluZyB0aGVp ciBzeW50YXggYW5kCiAgY29sb3IgaW4gdmFyaWFibGUgYHZoZGwtc3BlY2lhbC1zeW50YXgtYWxp c3QnIGFuZCBieSBzZXR0aW5nIHZhcmlhYmxlCiAgYHZoZGwtaGlnaGxpZ2h0LXNwZWNpYWwtd29y ZHMnIHRvIG5vbi1uaWwuICBUaGlzIGFsbG93cyB0byBlc3RhYmxpc2ggc29tZQogIG5hbWluZyBj b252ZW50aW9ucyAoZS5nLiB0byBkaXN0aW5ndWlzaCBkaWZmZXJlbnQga2luZHMgb2Ygc2lnbmFs cyBvciBvdGhlcgogIG9iamVjdHMgYnkgdXNpbmcgbmFtZSBzdWZmaWNlcykgYW5kIHRvIHN1cHBv cnQgdGhlbSB2aXN1YWxseS4KCiAgVmFyaWFibGUgYHZoZGwtaGlnaGxpZ2h0LWNhc2Utc2Vuc2l0 aXZlJyBjYW4gYmUgc2V0IHRvIG5vbi1uaWwgaW4gb3JkZXIgdG8KICBzdXBwb3J0IGNhc2Utc2Vu c2l0aXZlIGhpZ2hsaWdodGluZy4gIEhvd2V2ZXIsIGtleXdvcmRzIGFyZSB0aGVuIG9ubHkKICBo aWdobGlnaHRlZCBpZiB3cml0dGVuIGluIGxvd2VyIGNhc2UuCgogIENvZGUgYmV0d2VlbiAidHJh bnNsYXRlX29mZiIgYW5kICJ0cmFuc2xhdGVfb24iIHByYWdtYXMgaXMgaGlnaGxpZ2h0ZWQKICB1 c2luZyBhIGRpZmZlcmVudCBiYWNrZ3JvdW5kIGNvbG9yIGlmIHZhcmlhYmxlIGB2aGRsLWhpZ2hs aWdodC10cmFuc2xhdGUtb2ZmJwogIGlzIG5vbi1uaWwuCgogIEFsbCBjb2xvcnMgY2FuIGJlIGN1 c3RvbWl6ZWQgYnkgY29tbWFuZCBgXFtjdXN0b21pemUtZmFjZV0nLgogIEZvciBoaWdobGlnaHRp bmcgb2YgbWF0Y2hpbmcgcGFyZW50aGVzaXMsIHNlZSBjdXN0b21pemF0aW9uIGdyb3VwCiAgYHBh cmVuLXNob3dpbmcnIChgXFtjdXN0b21pemUtZ3JvdXBdJykuCgotIFVTRVIgTU9ERUxTOiAgVkhE TCBtb2RlbHMgKHRlbXBsYXRlcykgY2FuIGJlIHNwZWNpZmllZCBieSB0aGUgdXNlciBhbmQgbWFk ZQogIGFjY2Vzc2libGUgaW4gdGhlIG1lbnUsIHRocm91Z2gga2V5IGJpbmRpbmdzIChgQy1jIEMt bSAuLi4nKSwgb3IgYnkga2V5d29yZAogIGVsZWN0cmlmaWNhdGlvbi4gIFNlZSBjdXN0b20gdmFy aWFibGUgYHZoZGwtbW9kZWwtYWxpc3QnLgoKLSBISURFL1NIT1c6ICBUaGUgY29kZSBvZiBlbnRp cmUgVkhETCBkZXNpZ24gdW5pdHMgY2FuIGJlIGhpZGRlbiB1c2luZyB0aGUKICBgSGlkZS9TaG93 JyBtZW51IG9yIGJ5IHByZXNzaW5nIGBTLW1vdXNlLTInIHdpdGhpbiB0aGUgY29kZSAodmFyaWFi bGUKICBgdmhkbC1oaWRlc2hvdy1tZW51JykuCgotIFBSSU5USU5HOiAgUG9zdHNjcmlwdCBwcmlu dGluZyB3aXRoIGRpZmZlcmVudCBmYWNlcyAoYW4gb3B0aW1pemVkIHNldCBvZgogIGZhY2VzIGlz IHVzZWQgaWYgYHZoZGwtcHJpbnQtY3VzdG9taXplLWZhY2VzJyBpcyBub24tbmlsKSBvciBjb2xv cnMKICAoaWYgYHBzLXByaW50LWNvbG9yLXAnIGlzIG5vbi1uaWwpIGlzIHBvc3NpYmxlIHVzaW5n IHRoZSBzdGFuZGFyZCBFbWFjcwogIHBvc3RzY3JpcHQgcHJpbnRpbmcgY29tbWFuZHMuICBWYXJp YWJsZSBgdmhkbC1wcmludC10d28tY29sdW1uJyBkZWZpbmVzCiAgYXBwcm9wcmlhdGUgZGVmYXVs dCBzZXR0aW5ncyBmb3IgbmljZSBsYW5kc2NhcGUgdHdvLWNvbHVtbiBwcmludGluZy4gIFRoZQog IHBhcGVyIGZvcm1hdCBjYW4gYmUgc2V0IGJ5IHZhcmlhYmxlIGBwcy1wYXBlci10eXBlJy4gIERv IG5vdCBmb3JnZXQgdG8KICBzd2l0Y2ggYHBzLXByaW50LWNvbG9yLXAnIHRvIG5pbCBmb3IgcHJp bnRpbmcgb24gYmxhY2stYW5kLXdoaXRlIHByaW50ZXJzLgoKLSBDVVNUT01JWkFUSU9OOiAgQWxs IHZhcmlhYmxlcyBjYW4gZWFzaWx5IGJlIGN1c3RvbWl6ZWQgdXNpbmcgdGhlIGBDdXN0b21pemUn CiAgbWVudSBlbnRyeSBvciBgXFtjdXN0b21pemUtb3B0aW9uXScgKGBcW2N1c3RvbWl6ZS1ncm91 cF0nIGZvciBncm91cHMpLgogIFNvbWUgY3VzdG9taXphdGlvbnMgb25seSB0YWtlIGVmZmVjdCBh ZnRlciBzb21lIGFjdGlvbiAocmVhZCB0aGUgTk9URSBpbgogIHRoZSB2YXJpYWJsZSBkb2N1bWVu dGF0aW9uKS4gIEN1c3RvbWl6YXRpb24gY2FuIGFsc28gYmUgZG9uZSBnbG9iYWxseSAoaS5lLgog IHNpdGUtd2lkZSwgcmVhZCB0aGUgSU5TVEFMTCBmaWxlKS4KCi0gRklMRSBFWFRFTlNJT05TOiAg QXMgZGVmYXVsdCwgZmlsZXMgd2l0aCBleHRlbnNpb25zICIudmhkIiBhbmQgIi52aGRsIiBhcmUK ICBhdXRvbWF0aWNhbGx5IHJlY29nbml6ZWQgYXMgVkhETCBzb3VyY2UgZmlsZXMuICBUbyBhZGQg YW4gZXh0ZW5zaW9uICIueHh4IiwKICBhZGQgdGhlIGZvbGxvd2luZyBsaW5lIHRvIHlvdXIgRW1h Y3Mgc3RhcnQtdXAgZmlsZSAoYC5lbWFjcycpOgogICAgKHNldHEgYXV0by1tb2RlLWFsaXN0IChj b25zICcoIlxcLnh4eFxcJyIgLiB2aGRsLW1vZGUpIGF1dG8tbW9kZS1hbGlzdCkpCgotIEhJTlRT OgogIC0gVHlwZSBgXFtrZXlib2FyZC1xdWl0XSBcW2tleWJvYXJkLXF1aXRdJyB0byBpbnRlcnJ1 cHQgbG9uZyBvcGVyYXRpb25zIG9yIGlmIEVtYWNzIGhhbmdzLgoKCk1haW50ZW5hbmNlOgotLS0t LS0tLS0tLS0KClRvIHN1Ym1pdCBhIGJ1ZyByZXBvcnQsIGVudGVyIGBcW3ZoZGwtc3VibWl0LWJ1 Zy1yZXBvcnRdJyB3aXRoaW4gVkhETCBNb2RlLgpBZGQgYSBkZXNjcmlwdGlvbiBvZiB0aGUgcHJv YmxlbSBhbmQgaW5jbHVkZSBhIHJlcHJvZHVjaWJsZSB0ZXN0IGNhc2UuCgpRdWVzdGlvbnMgYW5k IGVuaGFuY2VtZW50IHJlcXVlc3RzIGNhbiBiZSBzZW50IHRvIDx2aGRsLW1vZGVAZ2VvY2l0aWVz LmNvbT4uCgpUaGUgYHZoZGwtbW9kZS1hbm5vdW5jZScgbWFpbGluZyBsaXN0IGluZm9ybXMgYWJv dXQgbmV3IFZIREwgTW9kZSByZWxlYXNlcy4KVGhlIGB2aGRsLW1vZGUtdmljdGltcycgbWFpbGlu ZyBsaXN0IGluZm9ybXMgYWJvdXQgbmV3IFZIREwgTW9kZSBiZXRhIHJlbGVhc2VzLgpZb3UgYXJl IGtpbmRseSBpbnZpdGVkIHRvIHBhcnRpY2lwYXRlIGluIGJldGEgdGVzdGluZy4gIFN1YnNjcmli ZSB0byBhYm92ZQptYWlsaW5nIGxpc3RzIGJ5IHNlbmRpbmcgYW4gZW1haWwgdG8gPHZoZGwtbW9k ZUBnZW9jaXRpZXMuY29tPi4KClZIREwgTW9kZSBpcyBvZmZpY2lhbGx5IGRpc3RyaWJ1dGVkIG9u IHRoZSBFbWFjcyBWSERMIE1vZGUgSG9tZSBQYWdlCjxodHRwOi8vd3d3Lmdlb2NpdGllcy5jb20v U2lsaWNvblZhbGxleS9QZWFrcy84Mjg3Piwgd2hlcmUgdGhlIGxhdGVzdAp2ZXJzaW9uIGFuZCBy ZWxlYXNlIG5vdGVzIGNhbiBiZSBmb3VuZC4KCgpCdWdzIGFuZCBMaW1pdGF0aW9uczoKLS0tLS0t LS0tLS0tLS0tLS0tLS0tCgotIFJlLWluZGVudGluZyBsYXJnZSByZWdpb25zIG9yIGV4cHJlc3Np b25zIGNhbiBiZSBzbG93LgotIEluZGVudGF0aW9uIGJ1ZyBpbiBzaW11bHRhbmVvdXMgaWYtIGFu ZCBjYXNlLXN0YXRlbWVudHMgKFZIREwtQU1TKS4KLSBIaWRlc2hvdyBkb2VzIG5vdCB3b3JrIHVu ZGVyIFhFbWFjcy4KLSBJbmRleCBtZW51IGFuZCBmaWxlIHRhZ2dpbmcgaW4gc3BlZWRiYXIgZG8g bm90IHdvcmsgdW5kZXIgWEVtYWNzLgotIFBhcnNpbmcgY29tcGlsYXRpb24gZXJyb3IgbWVzc2Fn ZXMgZm9yIElrb3MgYW5kIFZpZXdsb2dpYyBWSERMIGNvbXBpbGVycwogIGRvZXMgbm90IHdvcmsg dW5kZXIgWEVtYWNzLgoKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgVGhlIFZIREwgTW9kZSBNYWludGFpbmVycwogICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICBSZXRvIFppbW1lcm1hbm4gYW5kIFJvZCBXaGl0YnkK CktleSBiaW5kaW5nczoKLS0tLS0tLS0tLS0tLQoKXHt2aGRsLW1vZGUtbWFwfR8KKGRlZmFsaWFz ICd2aGRsLW1vZGUgI1tuaWwgIlwzMDYgXDIxMFwzMDcQXDMxMBFcMzExXG4hXDIxMFwzMTILIVwy MTBcZhVcMzEzXDMxNCFcMzE1TFwyMTBcMzEzXDMxNiEOXGZMXDIxMFwzMTNcMzE3IVwzMjBMXDIx MFwzMTNcMzIxIVwzMjBMXDIxMFwzMTNcMzIyIVwzMjBMXDIxMFwzMTNcMzIzIVwzMjRMXDIxMFwz MTNcMzI1IVwzMjZMXDIxMFwzMTNcMzI3IVwzMzBMXDIxMFwzMTNcMzMxIQ5ATFwyMTBcMzEzXDMz MiEOQUxcMjEwXDMxM1wzMzMhXDMzNExcMjEwXDMxM1wzMzUhXDMzNkxcMjEwXDMxM1wzMzchDkJM XDIxMFwzMTNcMzQwIVwzNDFMXDIxMFwzMTNcMzQyIVwzMzZMXDIxMFwzNDNcMzQ0IVwyMDN8AFwz MTNcMzQ0IVwyMTBcMzQ1FiRcMzQ2XDM0NyFcMjEwXDMxM1wzNTAhXDM1MVwzMzYOQz9cMzUyXDM1 M1wzNTRcMjU3BkxcMjEwXDMxM1wzNTUhXDM1NkxcMjEwXDMxM1wzNTchXDMzNkxcMjEwXDMxM1wz NjAhXDMyMExcMjEwXDMxM1wzNjEhXDMyMExcMjEwXDM2MiBcMjEwXDM0NlwzNjMhXDIxMFwzMTNc MzY0IVwzMzZMXDIxMFwzMTNcMzY1IVwzMzZMXDIxMFwzNjYgXDIxMA5EXDIwM1wzMDUAXDM2NyBc MjEwXDM3MA5FIVwyMTBcMzQzXDM3MSFcMjA0XDMyMwBcMzM2FjlcMzcxDkZCFkZcMzcyXDM3MVwz NzNcMzc0I1wyMTBcMzc1XDM3MVxuXDM3NA5FJFwyMTBcMzEzXDM3NiFcMjEwXDM3NyBcMjEwXDIw MUgAXDIwMUkAIVwyMTBcMjAxSgBcMjAxSwAhXDIwMwkBXDMzNlwyMDFMAFwyMDFNAFwyMTdcMjEw XDIwMU4AIFwyMTBcMjAxTwAgXDIxMFwyMDFQACBcMjEwXDIwMVEAXDIwMVIADkdcIlwyMTBcMjAx UwAgXDIxMFwyMDFIAFwyMDFUACFcMjA3IiBbbWFqb3ItbW9kZSBtb2RlLW5hbWUgdmhkbC1tb2Rl LW1hcCB2aGRsLW1vZGUtc3ludGF4LXRhYmxlIHZoZGwtbW9kZS1hYmJyZXYtdGFibGUgbG9jYWwt YWJicmV2LXRhYmxlIGtpbGwtYWxsLWxvY2FsLXZhcmlhYmxlcyB2aGRsLW1vZGUgIlZIREwiIHVz ZS1sb2NhbC1tYXAgc2V0LXN5bnRheC10YWJsZSBtYWtlLWxvY2FsLXZhcmlhYmxlIHBhcmFncmFw aC1zdGFydCAiXFxzLSpcXCgtLStcXHMtKiRcXHxbXiAtXVxcfCRcXCkiIHBhcmFncmFwaC1zZXBh cmF0ZSBwYXJhZ3JhcGgtaWdub3JlLWZpbGwtcHJlZml4IHQgcmVxdWlyZS1maW5hbC1uZXdsaW5l IHBhcnNlLXNleHAtaWdub3JlLWNvbW1lbnRzIGluZGVudC1saW5lLWZ1bmN0aW9uIHZoZGwtaW5k ZW50LWxpbmUgY29tbWVudC1zdGFydCAiLS0iIGNvbW1lbnQtZW5kICIiIGNvbW1lbnQtY29sdW1u IGVuZC1jb21tZW50LWNvbHVtbiBjb21tZW50LXN0YXJ0LXNraXAgIi0tK1xccy0qIiBjb21tZW50 LW11bHRpLWxpbmUgbmlsIGluZGVudC10YWJzLW1vZGUgaGlwcGllLWV4cGFuZC1vbmx5LWJ1ZmZl cnMgKHZoZGwtbW9kZSkgaGlwcGllLWV4cGFuZC12ZXJib3NlIGJvdW5kcCBjb21tZW50LWluZGVu dC1mdW5jdGlvbiB2aGRsLWNvbW1lbnQtaW5kZW50IHJlcXVpcmUgZm9udC1sb2NrIGZvbnQtbG9j ay1kZWZhdWx0cyB2aGRsLWZvbnQtbG9jay1rZXl3b3JkcyAoKDk1IC4gInciKSkgYmVnaW5uaW5n LW9mLWxpbmUgKGZvbnQtbG9jay1zeW50YWN0aWMta2V5d29yZHMgLiB2aGRsLWZvbnQtbG9jay1z eW50YWN0aWMta2V5d29yZHMpIGZvbnQtbG9jay1zdXBwb3J0LW1vZGUgbGF6eS1sb2NrLW1vZGUg bGF6eS1sb2NrLWRlZmVyLWNvbnRleHR1YWxseSBsYXp5LWxvY2stZGVmZXItb24tdGhlLWZseSBs YXp5LWxvY2stZGVmZXItb24tc2Nyb2xsaW5nIHR1cm4tb24tZm9udC1sb2NrIGNvbXBpbGUgY29t cGlsYXRpb24tZXJyb3ItcmVnZXhwLWFsaXN0IGNvbXBpbGF0aW9uLWZpbGUtcmVnZXhwLWFsaXN0 IHZoZGwtaW5kZXgtbWVudS1pbml0IHZoZGwtYWRkLXNvdXJjZS1maWxlcy1tZW51IGVhc3ktbWVu dS1hZGQgdmhkbC1tb2RlLW1lbnUgcHV0IHZhcmlhYmxlLWRvY3VtZW50YXRpb24gIk1lbnUga2V5 bWFwIGZvciBWSERMIE1vZGUuIiBlYXN5LW1lbnUtZG8tZGVmaW5lIGhzLW1pbm9yLW1vZGUtaG9v ayB2aGRsLWhpZGVzaG93LWluaXQgdmhkbC1pbmxpbmUtY29tbWVudC1jb2x1bW4gdmhkbC1lbmQt Y29tbWVudC1jb2x1bW4gdmhkbC1pbmRlbnQtdGFicy1tb2RlIHZoZGwtaGlnaGxpZ2h0LWNhc2Ut c2Vuc2l0aXZlIHZoZGwtc291cmNlLWZpbGUtbWVudSB2aGRsLW1vZGUtbWVudS1saXN0IGN1cnJl bnQtbG9hZC1saXN0IHZoZGwtdmVyc2lvbiBydW4taG9va3MgbWVudS1iYXItdXBkYXRlLWhvb2sg ZmJvdW5kcCBzcGVlZGJhciAoYnl0ZS1jb2RlICIIXDIwMxgAXDMwM1wzMDEhXDIwMxAAXDMwNAkh XDIwNBgAXDMwNVwzMDYhXDIxMFwzMDdcbiFcMjEwXDMwM1wyMDciIFt2aGRsLXNwZWVkYmFyIHNw ZWVkYmFyLWZyYW1lIHNwZWVkYmFyLWF0dGFjaGVkLWZyYW1lIGJvdW5kcCBmcmFtZS1saXZlLXAg c3BlZWRiYXItZnJhbWUtbW9kZSAxIHNlbGVjdC1mcmFtZV0gMikgKChlcnJvciAodmhkbC1hZGQt d2FybmluZyAiQmVmb3JlIHVzaW5nIFNwZWVkYmFyLCBpbnN0YWxsIGluY2x1ZGVkIGBzcGVlZGJh ci5lbCcgcGF0Y2giKSkpIHZoZGwtcHMtcHJpbnQtaW5pdCB2aGRsLW1vZGlmeS1kYXRlLWluaXQg dmhkbC1tb2RlLWxpbmUtdXBkYXRlIG1lc3NhZ2UgIlZIREwgTW9kZSAlcy4gIFR5cGUgQy1jIEMt aCBmb3IgZG9jdW1lbnRhdGlvbi4iIHZoZGwtcHJpbnQtd2FybmluZ3MgdmhkbC1tb2RlLWhvb2td IDcgKCMkIC4gODUzMDgpIG5pbF0pCiNANDkgQWN0aXZhdGUgYWxsIGN1c3RvbWl6YXRpb25zIG9u IGxvY2FsIHZhcmlhYmxlcy4fCihkZWZhbGlhcyAndmhkbC1hY3RpdmF0ZS1jdXN0b21pemF0aW9u cyAjW25pbCAiXDMwNiBcMjEwXDMwNwghXDIxMFwzMTAJIVwyMTBcbhNcZhVcMzExIFwyMTBcMzEy IFwyMTBcMzEzIFwyMTBcMzE0XDMxNSFcMjEwXDMxNiBcMjA3IiBbdmhkbC1tb2RlLW1hcCB2aGRs LW1vZGUtc3ludGF4LXRhYmxlIHZoZGwtaW5saW5lLWNvbW1lbnQtY29sdW1uIGNvbW1lbnQtY29s dW1uIHZoZGwtZW5kLWNvbW1lbnQtY29sdW1uIGVuZC1jb21tZW50LWNvbHVtbiB2aGRsLW1vZGUt bWFwLWluaXQgdXNlLWxvY2FsLW1hcCBzZXQtc3ludGF4LXRhYmxlIHZoZGwtbW9kaWZ5LWRhdGUt aW5pdCB2aGRsLXVwZGF0ZS1tb2RlLW1lbnUgdmhkbC1oaWRlc2hvdy1pbml0IHJ1bi1ob29rcyBt ZW51LWJhci11cGRhdGUtaG9vayB2aGRsLW1vZGUtbGluZS11cGRhdGVdIDIgKCMkIC4gMTAzMDI2 KSBuaWxdKQojQDU4IEFkZC9yZW1vdmUgaG9vayBmb3IgbW9kaWZ5aW5nIGRhdGUgd2hlbiBidWZm ZXIgaXMgc2F2ZWQuHwooZGVmYWxpYXMgJ3ZoZGwtbW9kaWZ5LWRhdGUtaW5pdCAjW25pbCAiCFwy MDMJAFwzMDFcMzAyXDMwM1wiXDIwN1wzMDRcMzAyXDMwM1wiXDIwNyIgW3ZoZGwtbW9kaWZ5LWRh dGUtb24tc2F2aW5nIGFkZC1ob29rIGxvY2FsLXdyaXRlLWZpbGUtaG9va3MgdmhkbC10ZW1wbGF0 ZS1tb2RpZnktbm9lcnJvciByZW1vdmUtaG9va10gMyAoIyQgLiAxMDM1MjUpXSkKI0AxMDA5IFJl c2VydmVkIHdvcmRzIGluIFZIREw6CgpWSERMJzkzIChJRUVFIFN0ZCAxMDc2LTE5OTMpOgogIGB2 aGRsLTkzLWtleXdvcmRzJyAgICAgIDoga2V5d29yZHMKICBgdmhkbC05My10eXBlcycgICAgICAg ICA6IHN0YW5kYXJkaXplZCB0eXBlcwogIGB2aGRsLTkzLWF0dHJpYnV0ZXMnICAgIDogc3RhbmRh cmRpemVkIGF0dHJpYnV0ZXMKICBgdmhkbC05My1lbnVtLXZhbHVlcycgICA6IHN0YW5kYXJkaXpl ZCBlbnVtZXJhdGlvbiB2YWx1ZXMKICBgdmhkbC05My1mdW5jdGlvbnMnICAgICA6IHN0YW5kYXJk aXplZCBmdW5jdGlvbnMKICBgdmhkbC05My1wYWNrYWdlcycgICAgICA6IHN0YW5kYXJkaXplZCBw YWNrYWdlcyBhbmQgbGlicmFyaWVzCgpWSERMLUFNUyAoSUVFRSBTdGQgMTA3Ni4xKToKICBgdmhk bC1hbXMta2V5d29yZHMnICAgICA6IGtleXdvcmRzCiAgYHZoZGwtYW1zLXR5cGVzJyAgICAgICAg OiBzdGFuZGFyZGl6ZWQgdHlwZXMKICBgdmhkbC1hbXMtYXR0cmlidXRlcycgICA6IHN0YW5kYXJk aXplZCBhdHRyaWJ1dGVzCiAgYHZoZGwtYW1zLWVudW0tdmFsdWVzJyAgOiBzdGFuZGFyZGl6ZWQg ZW51bWVyYXRpb24gdmFsdWVzCiAgYHZoZGwtYW1zLWZ1bmN0aW9ucycgICAgOiBzdGFuZGFyZGl6 ZWQgZnVuY3Rpb25zCgpNYXRoIFBhY2thZ2VzIChJRUVFIFN0ZCAxMDc2LjIpOgogIGB2aGRsLW1h dGgtdHlwZXMnICAgICAgIDogc3RhbmRhcmRpemVkIHR5cGVzCiAgYHZoZGwtbWF0aC1jb25zdGFu dHMnICAgOiBzdGFuZGFyZGl6ZWQgY29uc3RhbnRzCiAgYHZoZGwtbWF0aC1mdW5jdGlvbnMnICAg OiBzdGFuZGFyZGl6ZWQgZnVuY3Rpb25zCiAgYHZoZGwtbWF0aC1wYWNrYWdlcycgICAgOiBzdGFu ZGFyZGl6ZWQgcGFja2FnZXMKCkZvcmJpZGRlbiB3b3JkczoKICBgdmhkbC12ZXJpbG9nLWtleXdv cmRzJyA6IFZlcmlsb2cgcmVzZXJ2ZWQgd29yZHMKCk5PVEU6IGNsaWNrIGBtb3VzZS0yJyBvbiB2 YXJpYWJsZSBuYW1lcyBhYm92ZSAobm90IGluIFhFbWFjcykuHwooZGVmdmFyIHZoZGwtZG9jLWtl eXdvcmRzIG5pbCAoIyQgLiAxMDM3OTUpKQojQDYzMCBGb3IgVkhETCBjb2Rpbmcgc3R5bGUgYW5k IG5hbWluZyBjb252ZW50aW9uIGd1aWRlbGluZXMsIHNlZSB0aGUgZm9sbG93aW5nCnJlZmVyZW5j ZXM6CgpbMV0gQmVuIENvaGVuLgogICAgIlZIREwgQ29kaW5nIFN0eWxlcyBhbmQgTWV0aG9kb2xv Z2llcyIuCiAgICBLbHV3ZXIgQWNhZGVtaWMgUHVibGlzaGVycywgMTk5OS4KICAgIGh0dHA6Ly9t ZW1iZXJzLmFvbC5jb20vdmhkbGNvaGVuL3ZoZGwvCgpbMl0gTWljaGFlbCBLZWF0aW5nIGFuZCBQ aWVycmUgQnJpY2F1ZC4KICAgICJSZXVzZSBNZXRob2RvbG9neSBNYW51YWwiLgogICAgS2x1d2Vy IEFjYWRlbWljIFB1Ymxpc2hlcnMsIDE5OTguCiAgICBodHRwOi8vd3d3LnN5bm9wc3lzLmNvbS9w cm9kdWN0cy9yZXVzZS9ybW0uaHRtbAoKWzNdIEV1cm9wZWFuIFNwYWNlIEFnZW5jeS4KICAgICJW SERMIE1vZGVsbGluZyBHdWlkZWxpbmVzIi4KICAgIGZ0cDovL2Z0cC5lc3RlYy5lc2EubmwvcHVi L3ZoZGwvZG9jL01vZGVsR3VpZGUue3BkZixwc30KClVzZSB2YXJpYWJsZXMgYHZoZGwtaGlnaGxp Z2h0LXNwZWNpYWwtd29yZHMnIGFuZCBgdmhkbC1zcGVjaWFsLXN5bnRheC1hbGlzdCcKdG8gdmlz dWFsbHkgc3VwcG9ydCBuYW1pbmcgY29udmVudGlvbnMuHwooZGVmdmFyIHZoZGwtZG9jLWNvZGlu Zy1zdHlsZSBuaWwgKCMkIC4gMTA0ODU1KSkKI0A1MiBEaXNwbGF5IFZBUklBQkxFJ3MgZG9jdW1l bnRhdGlvbiBpbiAqSGVscCogYnVmZmVyLh8KKGRlZmFsaWFzICd2aGRsLWRvYy12YXJpYWJsZSAj Wyh2YXJpYWJsZSkgIlwzMDNcMjIwXDMwNFwzMDUIXDMwNlwiIVwyMTBcMzA3XDMxMAlcIlwyMDQX AFwzMTFcMzEyCER0XCJcMjEwXDIxMlxucVwyMTBcMzEzIFwyMTApXDMxNCBcMjIxXDIwNyIgW3Zh cmlhYmxlIGVtYWNzLXZlcnNpb24gc3RhbmRhcmQtb3V0cHV0ICIqSGVscCoiIHByaW5jIGRvY3Vt ZW50YXRpb24tcHJvcGVydHkgdmFyaWFibGUtZG9jdW1lbnRhdGlvbiBzdHJpbmctbWF0Y2ggIlhF bWFjcyIgaGVscC1zZXR1cC14cmVmIHZoZGwtZG9jLXZhcmlhYmxlIGhlbHAtbW9kZSBwcmludC1o ZWxwLXJldHVybi1tZXNzYWdlXSA1ICgjJCAuIDEwNTUzOSkgbmlsXSkKI0A1MSBEaXNwbGF5IFZI REwgbW9kZSBkb2N1bWVudGF0aW9uIGluICpIZWxwKiBidWZmZXIuHwooZGVmYWxpYXMgJ3ZoZGwt ZG9jLW1vZGUgI1tuaWwgIlwzMDNcMjIwXDMwNAghXDIxMFwzMDRcMzA1IVwyMTBcMzA0XDMwNlwz MDchIVwyMTBcMzEwXDMxMQlcIlwyMDQdAFwzMTJcMzEzQ3RcIlwyMTBcMjEyXG5xXDIxMFwzMTQg XDIxMClcMzE1IFwyMjFcMjA3IiBbbW9kZS1uYW1lIGVtYWNzLXZlcnNpb24gc3RhbmRhcmQtb3V0 cHV0ICIqSGVscCoiIHByaW5jICIgbW9kZTpcbiIgZG9jdW1lbnRhdGlvbiB2aGRsLW1vZGUgc3Ry aW5nLW1hdGNoICJYRW1hY3MiIGhlbHAtc2V0dXAteHJlZiB2aGRsLWRvYy1tb2RlIGhlbHAtbW9k ZSBwcmludC1oZWxwLXJldHVybi1tZXNzYWdlXSA0ICgjJCAuIDEwNTk1MykgbmlsXSkKI0AyNyBM aXN0IG9mIFZIREwnOTMga2V5d29yZHMuHwooZGVmY29uc3QgdmhkbC05My1rZXl3b3JkcyAnKCJh YnMiICJhY2Nlc3MiICJhZnRlciIgImFsaWFzIiAiYWxsIiAiYW5kIiAiYXJjaGl0ZWN0dXJlIiAi YXJyYXkiICJhc3NlcnQiICJhdHRyaWJ1dGUiICJiZWdpbiIgImJsb2NrIiAiYm9keSIgImJ1ZmZl ciIgImJ1cyIgImNhc2UiICJjb21wb25lbnQiICJjb25maWd1cmF0aW9uIiAiY29uc3RhbnQiICJk aXNjb25uZWN0IiAiZG93bnRvIiAiZWxzZSIgImVsc2lmIiAiZW5kIiAiZW50aXR5IiAiZXhpdCIg ImZpbGUiICJmb3IiICJmdW5jdGlvbiIgImdlbmVyYXRlIiAiZ2VuZXJpYyIgImdyb3VwIiAiZ3Vh cmRlZCIgImlmIiAiaW1wdXJlIiAiaW4iICJpbmVydGlhbCIgImlub3V0IiAiaXMiICJsYWJlbCIg ImxpYnJhcnkiICJsaW5rYWdlIiAibGl0ZXJhbCIgImxvb3AiICJtYXAiICJtb2QiICJuYW5kIiAi bmV3IiAibmV4dCIgIm5vciIgIm5vdCIgIm51bGwiICJvZiIgIm9uIiAib3BlbiIgIm9yIiAib3Ro ZXJzIiAib3V0IiAicGFja2FnZSIgInBvcnQiICJwb3N0cG9uZWQiICJwcm9jZWR1cmUiICJwcm9j ZXNzIiAicHVyZSIgInJhbmdlIiAicmVjb3JkIiAicmVnaXN0ZXIiICJyZWplY3QiICJyZW0iICJy ZXBvcnQiICJyZXR1cm4iICJyb2wiICJyb3IiICJzZWxlY3QiICJzZXZlcml0eSIgInNoYXJlZCIg InNpZ25hbCIgInNsYSIgInNsbCIgInNyYSIgInNybCIgInN1YnR5cGUiICJ0aGVuIiAidG8iICJ0 cmFuc3BvcnQiICJ0eXBlIiAidW5hZmZlY3RlZCIgInVuaXRzIiAidW50aWwiICJ1c2UiICJ2YXJp YWJsZSIgIndhaXQiICJ3aGVuIiAid2hpbGUiICJ3aXRoIiAieG5vciIgInhvciIpICgjJCAuIDEw NjM2MSkpCiNAMjggTGlzdCBvZiBWSERMLUFNUyBrZXl3b3Jkcy4fCihkZWZjb25zdCB2aGRsLWFt cy1rZXl3b3JkcyAnKCJhY3Jvc3MiICJicmVhayIgImxpbWl0IiAibmF0dXJlIiAibm9pc2UiICJw cm9jZWR1cmFsIiAicXVhbnRpdHkiICJyZWZlcmVuY2UiICJzcGVjdHJ1bSIgInN1Ym5hdHVyZSIg InRlcm1pbmFsIiAidGhyb3VnaCIgInRvbGVyYW5jZSIpICgjJCAuIDEwNzIyOSkpCiNANzAgTGlz dCBvZiBWZXJpbG9nIGtleXdvcmRzIGFzIGNhbmRpZGF0ZSBmb3IgYWRkaXRpb25hbCByZXNlcnZl ZCB3b3Jkcy4fCihkZWZjb25zdCB2aGRsLXZlcmlsb2cta2V5d29yZHMgJygiYGRlZmluZSIgImBl bHNlIiAiYGVuZGlmIiAiYGlmZGVmIiAiYGluY2x1ZGUiICJgdGltZXNjYWxlIiAiYHVuZGVmIiAi YWx3YXlzIiAiYW5kIiAiYXNzaWduIiAiYmVnaW4iICJidWYiICJidWZpZjAiICJidWZpZjEiICJj YXNlIiAiY2FzZXgiICJjYXNleiIgImNtb3MiICJkZWFzc2lnbiIgImRlZmF1bHQiICJkZWZwYXJh bSIgImRpc2FibGUiICJlZGdlIiAiZWxzZSIgImVuZCIgImVuZGF0dHJpYnV0ZSIgImVuZGNhc2Ui ICJlbmRmdW5jdGlvbiIgImVuZG1vZHVsZSIgImVuZHByaW1pdGl2ZSIgImVuZHNwZWNpZnkiICJl bmR0YWJsZSIgImVuZHRhc2siICJldmVudCIgImZvciIgImZvcmNlIiAiZm9yZXZlciIgImZvcmsi ICJmdW5jdGlvbiIgImhpZ2h6MCIgImhpZ2h6MSIgImlmIiAiaW5pdGlhbCIgImlub3V0IiAiaW5w dXQiICJpbnRlZ2VyIiAiam9pbiIgImxhcmdlIiAibWFjcm9tb2R1bGUiICJtYWtlZmlsZSIgIm1l ZGl1bSIgIm1vZHVsZSIgIm5hbmQiICJuZWdlZGdlIiAibm1vcyIgIm5vciIgIm5vdCIgIm5vdGlm MCIgIm5vdGlmMSIgIm9yIiAib3V0cHV0IiAicGFyYW1ldGVyIiAicG1vcyIgInBvc2VkZ2UiICJw cmltaXRpdmUiICJwdWxsMCIgInB1bGwxIiAicHVsbGRvd24iICJwdWxsdXAiICJyY21vcyIgInJl YWwiICJyZWFsdGltZSIgInJlZyIgInJlbGVhc2UiICJyZXBlYXQiICJybm1vcyIgInJwbW9zIiAi cnRyYW4iICJydHJhbmlmMCIgInJ0cmFuaWYxIiAic2NhbGFyZWQiICJzaWduZWQiICJzbWFsbCIg InNwZWNpZnkiICJzcGVjcGFyYW0iICJzdHJlbmd0aCIgInN0cm9uZzAiICJzdHJvbmcxIiAic3Vw cGx5IiAic3VwcGx5MCIgInN1cHBseTEiICJ0YWJsZSIgInRhc2siICJ0aW1lIiAidHJhbiIgInRy YW5pZjAiICJ0cmFuaWYxIiAidHJpIiAidHJpMCIgInRyaTEiICJ0cmlhbmQiICJ0cmlvciIgInRy aXJlZyIgInZlY3RvcmVkIiAid2FpdCIgIndhbmQiICJ3ZWFrMCIgIndlYWsxIiAid2hpbGUiICJ3 aXJlIiAid29yIiAieG5vciIgInhvciIpICgjJCAuIDEwNzQ0MikpCiNAMzcgTGlzdCBvZiBWSERM JzkzIHN0YW5kYXJkaXplZCB0eXBlcy4fCihkZWZjb25zdCB2aGRsLTkzLXR5cGVzICcoImJvb2xl YW4iICJiaXQiICJiaXRfdmVjdG9yIiAiY2hhcmFjdGVyIiAic2V2ZXJpdHlfbGV2ZWwiICJpbnRl Z2VyIiAicmVhbCIgInRpbWUiICJuYXR1cmFsIiAicG9zaXRpdmUiICJzdHJpbmciICJsaW5lIiAi dGV4dCIgInNpZGUiICJ1bnNpZ25lZCIgInNpZ25lZCIgImRlbGF5X2xlbmd0aCIgImZpbGVfb3Bl bl9raW5kIiAiZmlsZV9vcGVuX3N0YXR1cyIgInN0ZF9sb2dpYyIgInN0ZF9sb2dpY192ZWN0b3Ii ICJzdGRfdWxvZ2ljIiAic3RkX3Vsb2dpY192ZWN0b3IiKSAoIyQgLiAxMDg1NzMpKQojQDM4IExp c3Qgb2YgVkhETC1BTVMgc3RhbmRhcmRpemVkIHR5cGVzLh8KKGRlZmNvbnN0IHZoZGwtYW1zLXR5 cGVzICcoImRvbWFpbl90eXBlIiAicmVhbF92ZWN0b3IiKSAoIyQgLiAxMDg5MjUpKQojQDQzIExp c3Qgb2YgTWF0aCBQYWNrYWdlcyBzdGFuZGFyZGl6ZWQgdHlwZXMuHwooZGVmY29uc3QgdmhkbC1t YXRoLXR5cGVzICcoImNvbXBsZXgiICJjb21wbGV4X3BvbGFyIikgKCMkIC4gMTA5MDM5KSkKI0A0 MiBMaXN0IG9mIFZIREwnOTMgc3RhbmRhcmRpemVkIGF0dHJpYnV0ZXMuHwooZGVmY29uc3Qgdmhk bC05My1hdHRyaWJ1dGVzICcoImJhc2UiICJsZWZ0IiAicmlnaHQiICJoaWdoIiAibG93IiAicG9z IiAidmFsIiAic3VjYyIgInByZWQiICJsZWZ0b2YiICJyaWdodG9mIiAicmFuZ2UiICJyZXZlcnNl X3JhbmdlIiAibGVuZ3RoIiAiZGVsYXllZCIgInN0YWJsZSIgInF1aWV0IiAidHJhbnNhY3Rpb24i ICJldmVudCIgImFjdGl2ZSIgImxhc3RfZXZlbnQiICJsYXN0X2FjdGl2ZSIgImxhc3RfdmFsdWUi ICJkcml2aW5nIiAiZHJpdmluZ192YWx1ZSIgImFzY2VuZGluZyIgInZhbHVlIiAiaW1hZ2UiICJz aW1wbGVfbmFtZSIgImluc3RhbmNlX25hbWUiICJwYXRoX25hbWUiICJmb3JlaWduIikgKCMkIC4g MTA5MTU3KSkKI0A0MyBMaXN0IG9mIFZIREwtQU1TIHN0YW5kYXJkaXplZCBhdHRyaWJ1dGVzLh8K KGRlZmNvbnN0IHZoZGwtYW1zLWF0dHJpYnV0ZXMgJygiYWNyb3NzIiAidGhyb3VnaCIgInJlZmVy ZW5jZSIgImNvbnRyaWJ1dGlvbiIgInRvbGVyYW5jZSIgImRvdCIgImludGVnIiAiZGVsYXllZCIg ImFib3ZlIiAiem9oIiAibHRmIiAienRmIiAicmFtcCIgInNsZXciKSAoIyQgLiAxMDk1NjgpKQoj QDUwIExpc3Qgb2YgVkhETCc5MyBzdGFuZGFyZGl6ZWQgZW51bWVyYXRpb24gdmFsdWVzLh8KKGRl ZmNvbnN0IHZoZGwtOTMtZW51bS12YWx1ZXMgJygidHJ1ZSIgImZhbHNlIiAibm90ZSIgIndhcm5p bmciICJlcnJvciIgImZhaWx1cmUiICJyZWFkX21vZGUiICJ3cml0ZV9tb2RlIiAiYXBwZW5kX21v ZGUiICJvcGVuX29rIiAic3RhdHVzX2Vycm9yIiAibmFtZV9lcnJvciIgIm1vZGVfZXJyb3IiICJm cyIgInBzIiAibnMiICJ1cyIgIm1zIiAic2VjIiAibWluIiAiaHIiICJyaWdodCIgImxlZnQiKSAo IyQgLiAxMDk3ODYpKQojQDUxIExpc3Qgb2YgVkhETC1BTVMgc3RhbmRhcmRpemVkIGVudW1lcmF0 aW9uIHZhbHVlcy4fCihkZWZjb25zdCB2aGRsLWFtcy1lbnVtLXZhbHVlcyAnKCJxdWllc2NlbnRf ZG9tYWluIiAidGltZV9kb21haW4iICJmcmVxdWVuY3lfZG9tYWluIikgKCMkIC4gMTEwMDg2KSkK I0A0NyBMaXN0IG9mIE1hdGggUGFja2FnZXMgc3RhbmRhcmRpemVkIGNvbnN0YW50cy4fCihkZWZj b25zdCB2aGRsLW1hdGgtY29uc3RhbnRzICcoIm1hdGhfZSIgIm1hdGhfMV9vdmVyX2UiICJtYXRo X3BpIiAibWF0aF90d29fcGkiICJtYXRoXzFfb3Zlcl9waSIgIm1hdGhfaGFsZl9waSIgIm1hdGhf cV9waSIgIm1hdGhfM19oYWxmX3BpIiAibWF0aF9sb2dfb2ZfMiIgIm1hdGhfbG9nX29mXzEwIiAi bWF0aF9sb2cyX29mX2UiICJtYXRoX2xvZzEwX29mX2UiICJtYXRoX3NxcnQyIiAibWF0aF9zcXJ0 MV8yIiAibWF0aF9zcXJ0X3BpIiAibWF0aF9kZWdfdG9fcmFkIiAibWF0aF9yYWRfdG9fZGVnIiAi Y2Jhc2VfMSIgImNiYXNlX2oiICJjemVybyIpICgjJCAuIDExMDI0MykpCiNANDEgTGlzdCBvZiBW SERMJzkzIHN0YW5kYXJkaXplZCBmdW5jdGlvbnMuHwooZGVmY29uc3QgdmhkbC05My1mdW5jdGlv bnMgJygibm93IiAicmVzb2x2ZWQiICJyaXNpbmdfZWRnZSIgImZhbGxpbmdfZWRnZSIgInJlYWQi ICJyZWFkbGluZSIgIndyaXRlIiAid3JpdGVsaW5lIiAiZW5kZmlsZSIgInJlc2l6ZSIgImlzX1gi ICJzdGRfbWF0Y2giICJzaGlmdF9sZWZ0IiAic2hpZnRfcmlnaHQiICJyb3RhdGVfbGVmdCIgInJv dGF0ZV9yaWdodCIgInRvX3Vuc2lnbmVkIiAidG9fc2lnbmVkIiAidG9faW50ZWdlciIgInRvX3N0 ZExvZ2ljVmVjdG9yIiAidG9fc3RkVUxvZ2ljIiAidG9fc3RkVUxvZ2ljVmVjdG9yIiAidG9fYml0 IiAidG9fYml0VmVjdG9yIiAidG9fWDAxIiAidG9fWDAxWiIgInRvX1VYMDEiICJ0b18wMSIgImNv bnZfdW5zaWduZWQiICJjb252X3NpZ25lZCIgImNvbnZfaW50ZWdlciIgImNvbnZfc3RkX2xvZ2lj X3ZlY3RvciIgInNobCIgInNociIgImV4dCIgInN4dCIpICgjJCAuIDExMDYyOCkpCiNANDIgTGlz dCBvZiBWSERMLUFNUyBzdGFuZGFyZGl6ZWQgZnVuY3Rpb25zLh8KKGRlZmNvbnN0IHZoZGwtYW1z LWZ1bmN0aW9ucyAnKCJmcmVxdWVuY3kiKSAoIyQgLiAxMTExNDcpKQojQDQ3IExpc3Qgb2YgTWF0 aCBQYWNrYWdlcyBzdGFuZGFyZGl6ZWQgZnVuY3Rpb25zLh8KKGRlZmNvbnN0IHZoZGwtbWF0aC1m dW5jdGlvbnMgJygic2lnbiIgImNlaWwiICJmbG9vciIgInJvdW5kIiAidHJ1bmMiICJmbWF4IiAi Zm1pbiIgInVuaWZvcm0iICJzcXJ0IiAiY2JydCIgImV4cCIgImxvZyIgInNpbiIgImNvcyIgInRh biIgImFyY3NpbiIgImFyY2NvcyIgImFyY3RhbiIgInNpbmgiICJjb3NoIiAidGFuaCIgImFyY3Np bmgiICJhcmNjb3NoIiAiYXJjdGFuaCIgImNtcGx4IiAiY29tcGxleF90b19wb2xhciIgInBvbGFy X3RvX2NvbXBsZXgiICJhcmciICJjb25qIikgKCMkIC4gMTExMjUzKSkKI0A1NCBMaXN0IG9mIFZI REwnOTMgc3RhbmRhcmRpemVkIHBhY2thZ2VzIGFuZCBsaWJyYXJpZXMuHwooZGVmY29uc3Qgdmhk bC05My1wYWNrYWdlcyAnKCJzdGRfbG9naWNfMTE2NCIgIm51bWVyaWNfc3RkIiAibnVtZXJpY19i aXQiICJzdGFuZGFyZCIgInRleHRpbyIgInN0ZF9sb2dpY19hcml0aCIgInN0ZF9sb2dpY19zaWdu ZWQiICJzdGRfbG9naWNfdW5zaWduZWQiICJzdGRfbG9naWNfbWlzYyIgInN0ZF9sb2dpY190ZXh0 aW8iICJpZWVlIiAic3RkIiAid29yayIpICgjJCAuIDExMTU5NikpCiNANjAgTGlzdCBvZiBNYXRo IFBhY2thZ2VzIHN0YW5kYXJkaXplZCBwYWNrYWdlcyBhbmQgbGlicmFyaWVzLh8KKGRlZmNvbnN0 IHZoZGwtbWF0aC1wYWNrYWdlcyAnKCJtYXRoX3JlYWwiICJtYXRoX2NvbXBsZXgiKSAoIyQgLiAx MTE4NzkpKQojQDI0IExpc3Qgb2YgVkhETCBrZXl3b3Jkcy4fCihkZWZ2YXIgdmhkbC1rZXl3b3Jk cyBuaWwgKCMkIC4gMTEyMDE4KSkKI0AzNCBMaXN0IG9mIFZIREwgc3RhbmRhcmRpemVkIHR5cGVz Lh8KKGRlZnZhciB2aGRsLXR5cGVzIG5pbCAoIyQgLiAxMTIwODgpKQojQDM5IExpc3Qgb2YgVkhE TCBzdGFuZGFyZGl6ZWQgYXR0cmlidXRlcy4fCihkZWZ2YXIgdmhkbC1hdHRyaWJ1dGVzIG5pbCAo IyQgLiAxMTIxNjUpKQojQDQ3IExpc3Qgb2YgVkhETCBzdGFuZGFyZGl6ZWQgZW51bWVyYXRpb24g dmFsdWVzLh8KKGRlZnZhciB2aGRsLWVudW0tdmFsdWVzIG5pbCAoIyQgLiAxMTIyNTIpKQojQDM4 IExpc3Qgb2YgVkhETCBzdGFuZGFyZGl6ZWQgY29uc3RhbnRzLh8KKGRlZnZhciB2aGRsLWNvbnN0 YW50cyBuaWwgKCMkIC4gMTEyMzQ4KSkKI0AzOCBMaXN0IG9mIFZIREwgc3RhbmRhcmRpemVkIGZ1 bmN0aW9ucy4fCihkZWZ2YXIgdmhkbC1mdW5jdGlvbnMgbmlsICgjJCAuIDExMjQzMykpCiNANTEg TGlzdCBvZiBWSERMIHN0YW5kYXJkaXplZCBwYWNrYWdlcyBhbmQgbGlicmFyaWVzLh8KKGRlZnZh ciB2aGRsLXBhY2thZ2VzIG5pbCAoIyQgLiAxMTI1MTgpKQojQDM2IExpc3Qgb2YgYWRkaXRpb25h bCByZXNlcnZlZCB3b3Jkcy4fCihkZWZ2YXIgdmhkbC1yZXNlcnZlZC13b3JkcyBuaWwgKCMkIC4g MTEyNjE1KSkKI0AyNyBSZWdleHAgZm9yIFZIREwga2V5d29yZHMuHwooZGVmdmFyIHZoZGwta2V5 d29yZHMtcmVnZXhwIG5pbCAoIyQgLiAxMTI3MDMpKQojQDM3IFJlZ2V4cCBmb3IgVkhETCBzdGFu ZGFyZGl6ZWQgdHlwZXMuHwooZGVmdmFyIHZoZGwtdHlwZXMtcmVnZXhwIG5pbCAoIyQgLiAxMTI3 ODMpKQojQDQyIFJlZ2V4cCBmb3IgVkhETCBzdGFuZGFyZGl6ZWQgYXR0cmlidXRlcy4fCihkZWZ2 YXIgdmhkbC1hdHRyaWJ1dGVzLXJlZ2V4cCBuaWwgKCMkIC4gMTEyODcwKSkKI0A1MCBSZWdleHAg Zm9yIFZIREwgc3RhbmRhcmRpemVkIGVudW1lcmF0aW9uIHZhbHVlcy4fCihkZWZ2YXIgdmhkbC1l bnVtLXZhbHVlcy1yZWdleHAgbmlsICgjJCAuIDExMjk2NykpCiNANDEgUmVnZXhwIGZvciBWSERM IHN0YW5kYXJkaXplZCBmdW5jdGlvbnMuHwooZGVmdmFyIHZoZGwtZnVuY3Rpb25zLXJlZ2V4cCBu aWwgKCMkIC4gMTEzMDczKSkKI0A1NCBSZWdleHAgZm9yIFZIREwgc3RhbmRhcmRpemVkIHBhY2th Z2VzIGFuZCBsaWJyYXJpZXMuHwooZGVmdmFyIHZoZGwtcGFja2FnZXMtcmVnZXhwIG5pbCAoIyQg LiAxMTMxNjgpKQojQDM5IFJlZ2V4cCBmb3IgYWRkaXRpb25hbCByZXNlcnZlZCB3b3Jkcy4fCihk ZWZ2YXIgdmhkbC1yZXNlcnZlZC13b3Jkcy1yZWdleHAgbmlsICgjJCAuIDExMzI3NSkpCiNAMjgg SW5pdGlhbGl6ZSByZXNlcnZlZCB3b3Jkcy4fCihkZWZhbGlhcyAndmhkbC13b3Jkcy1pbml0ICNb bmlsICJcMzA2CFwzMDcZXDMwN1xuQD1cMjA2EwAJXG5cMjExG0FAKT4pXDIwNRgAXGZcIhVcMzA2 DhBcMzA3GVwzMDdcbkA9XDIwNi4ACVxuXDIxMRtBQCk+KVwyMDU0AA4RXDMxMBlcMzEwXG5APVwy MDZFAAlcblwyMTEbQUApPilcMjA1SwAOEiMWE1wzMDYOFFwzMDcZXDMwN1xuQD1cMjA2YgAJXG5c MjExG0FAKT4pXDIwNWgADhVcIhYWXDMwNg4XXDMwNxlcMzA3XG5APVwyMDZ/AAlcblwyMTEbQUAp PilcMjA1XDIwNQAOGFwiFhlcMzA2XDMxMBlcMzEwXG5APVwyMDZcMjMyAAlcblwyMTEbQUApPilc MjA1XDI0MAAOGiEWG1wzMDYOHFwzMDcZXDMwN1xuQD1cMjA2XDI2NwAJXG5cMjExG0FAKT4pXDIw NVwyNzUADh1cMzEwGVwzMTBcbkA9XDIwNlwzMTYACVxuXDIxMRtBQCk+KVwyMDVcMzI0AA4eIxYf XDMwNg4gXDMxMBlcMzEwXG5APVwyMDZcMzUzAAlcblwyMTEbQUApPilcMjA1XDM2MQAOIVwiFlwi XDMwNg4jXDIwNVwzNzQADiQOJVwyMDUDAQ4mXDMxMSMWJ1wzMTJcMzEzDSFcMzE0URYoXDMxMlwz MTMOEyFcMzE0URYpXDMxMlwzMTMOFiFcMzE0URYqXDMxMlwzMTMOGSFcMzE0URYrXDMxMlwzMTMO HyFcMzE0URYsXDMxMlwzMTMOXCIhXDMxNFEWLVwzMTIOLlwzMTVcMjMyP1wyMDVJAQ4uXDMxNlBc MzEzDichXDMxNFIWL1wzMTcgXDIwNyIgW3ZoZGwtOTMta2V5d29yZHMgc3RhbmRhcmQgdmhkbC1z dGFuZGFyZCB4IHZoZGwtYW1zLWtleXdvcmRzIHZoZGwta2V5d29yZHMgYXBwZW5kIGFtcyBtYXRo ICgiIikgIlxcPFxcKCIgcmVnZXhwLW9wdCAiXFwpXFw+IiAiIiAiXFx8IiB2aGRsLWFiYnJldi1s aXN0LWluaXQgdmhkbC05My10eXBlcyB2aGRsLWFtcy10eXBlcyB2aGRsLW1hdGgtdHlwZXMgdmhk bC10eXBlcyB2aGRsLTkzLWF0dHJpYnV0ZXMgdmhkbC1hbXMtYXR0cmlidXRlcyB2aGRsLWF0dHJp YnV0ZXMgdmhkbC05My1lbnVtLXZhbHVlcyB2aGRsLWFtcy1lbnVtLXZhbHVlcyB2aGRsLWVudW0t dmFsdWVzIHZoZGwtbWF0aC1jb25zdGFudHMgdmhkbC1jb25zdGFudHMgdmhkbC05My1mdW5jdGlv bnMgdmhkbC1hbXMtZnVuY3Rpb25zIHZoZGwtbWF0aC1mdW5jdGlvbnMgdmhkbC1mdW5jdGlvbnMg dmhkbC05My1wYWNrYWdlcyB2aGRsLW1hdGgtcGFja2FnZXMgdmhkbC1wYWNrYWdlcyB2aGRsLWhp Z2hsaWdodC1mb3JiaWRkZW4td29yZHMgdmhkbC1mb3JiaWRkZW4td29yZHMgdmhkbC1oaWdobGln aHQtdmVyaWxvZy1rZXl3b3JkcyB2aGRsLXZlcmlsb2cta2V5d29yZHMgdmhkbC1yZXNlcnZlZC13 b3JkcyB2aGRsLWtleXdvcmRzLXJlZ2V4cCB2aGRsLXR5cGVzLXJlZ2V4cCB2aGRsLWF0dHJpYnV0 ZXMtcmVnZXhwIHZoZGwtZW51bS12YWx1ZXMtcmVnZXhwIHZoZGwtZnVuY3Rpb25zLXJlZ2V4cCB2 aGRsLXBhY2thZ2VzLXJlZ2V4cCB2aGRsLWZvcmJpZGRlbi1zeW50YXggdmhkbC1yZXNlcnZlZC13 b3Jkcy1yZWdleHBdIDYgKCMkIC4gMTEzMzczKV0pCiNAMzYgUHJlZGVmaW5lZCBhYmJyZXZpYXRp b25zIGZvciBWSERMLh8KKGRlZnZhciB2aGRsLWFiYnJldi1saXN0IG5pbCAoIyQgLiAxMTQ4OTEp KQooZGVmYWxpYXMgJ3ZoZGwtYWJicmV2LWxpc3QtaW5pdCAjW25pbCAiXDMwNghDCVxuQwtcZkMN DghDDgkOXG5DDgtcMzA3Qw5cZlwzMDdDDg0mDlwyMTEWDlwyMDciIFt2aGRsLXVwcGVyLWNhc2Ut a2V5d29yZHMgdmhkbC1rZXl3b3JkcyB2aGRsLXVwcGVyLWNhc2UtdHlwZXMgdmhkbC10eXBlcyB2 aGRsLXVwcGVyLWNhc2UtYXR0cmlidXRlcyB2aGRsLWF0dHJpYnV0ZXMgYXBwZW5kIG5pbCB2aGRs LXVwcGVyLWNhc2UtZW51bS12YWx1ZXMgdmhkbC1lbnVtLXZhbHVlcyB2aGRsLXVwcGVyLWNhc2Ut Y29uc3RhbnRzIHZoZGwtY29uc3RhbnRzIHZoZGwtZnVuY3Rpb25zIHZoZGwtcGFja2FnZXMgdmhk bC1hYmJyZXYtbGlzdF0gMTVdKQoodmhkbC13b3Jkcy1pbml0KQojQDIxMCBSZWdleHAgZGVzY3Jp YmluZyBhIFZIREwgc3ltYm9sLgpXZSBjYW5ub3QgdXNlIGp1c3QgYHdvcmQnIHN5bnRheCBjbGFz cyBzaW5jZSBgXycgY2Fubm90IGJlIGluIHdvcmQKY2xhc3MuICBQdXR0aW5nIHVuZGVyc2NvcmUg aW4gd29yZCBjbGFzcyBicmVha3MgZm9yd2FyZCB3b3JkIG1vdmVtZW50CmJlaGF2aW9yIHRoYXQg dXNlcnMgYXJlIGZhbWlsaWFyIHdpdGguHwooZGVmY29uc3QgdmhkbC1zeW1ib2wta2V5ICJcXChc XHdcXHxcXHNfXFwpKyIgKCMkIC4gMTE1MzU1KSkKI0A0OCBSZWdleHAgZGVzY3JpYmluZyBhIGNh c2Ugc3RhdGVtZW50IGhlYWRlciBrZXkuHwooZGVmY29uc3QgdmhkbC1jYXNlLWhlYWRlci1rZXkg ImNhc2VbKCAJXG5dW147PT5dK1spIAlcbl1pcyIgKCMkIC4gMTE1NjMxKSkKI0AzMyBSZWdleHAg ZGVzY3JpYmluZyBhIFZIREwgbGFiZWwuHwooZGVmY29uc3QgdmhkbC1sYWJlbC1rZXkgKGNvbmNh dCAiXFwoIiB2aGRsLXN5bWJvbC1rZXkgIlxccy0qOlxcKVtePV0iKSAoIyQgLiAxMTU3NjApKQoj QDQzMSBSZXR1cm4gdGhlIHZhbHVlIG9mIHBvaW50IGF0IGNlcnRhaW4gY29tbW9ubHkgcmVmZXJl bmNlZCBQT1NJVElPTnMuClBPU0lUSU9OIGNhbiBiZSBvbmUgb2YgdGhlIGZvbGxvd2luZyBzeW1i b2xzOgoKYm9sICAtLSBiZWdpbm5pbmcgb2YgbGluZQplb2wgIC0tIGVuZCBvZiBsaW5lCmJvZCAg LS0gYmVnaW5uaW5nIG9mIGRlZnVuCmJvaSAgLS0gYmFjayB0byBpbmRlbnRhdGlvbgplb2kgIC0t IGxhc3Qgd2hpdGVzcGFjZSBvbiBsaW5lCmlvbmwgLS0gaW5kZW50YXRpb24gb2YgbmV4dCBsaW5l CmlvcGwgLS0gaW5kZW50YXRpb24gb2YgcHJldmlvdXMgbGluZQpib25sIC0tIGJlZ2lubmluZyBv ZiBuZXh0IGxpbmUKYm9wbCAtLSBiZWdpbm5pbmcgb2YgcHJldmlvdXMgbGluZQoKVGhpcyBmdW5j dGlvbiBkb2VzIG5vdCBtb2RpZnkgcG9pbnQgb3IgbWFyay4fCihkZWZhbGlhcyAndmhkbC1wb2lu dCAnKG1hY3JvIC4gI1socG9zaXRpb24pICJcMzAxCFwyNDI9XDIwMw0ACEFBXDIwMxIAXDMwMlwz MDMIXCJcMjEwCEFAEFwzMDRcMzA1XDMwNghcMzA3PVwyMDMjAFwzMTBcMjAydwAIXDMxMT1cMjAz LQBcMzEyXDIwMncACFwzMTM9XDIwMzcAXDMxNFwyMDJ3AAhcMzE1PVwyMDNBAFwzMTZcMjAydwAI XDMxNz1cMjAzSwBcMzIwXDIwMncACFwzMjE9XDIwM1UAXDMyMlwyMDJ3AAhcMzIzPVwyMDNfAFwz MjRcMjAydwAIXDMyNT1cMjAzaQBcMzI2XDIwMncACFwzMjc9XDIwM3MAXDMzMFwyMDJ3AFwzMDJc MzMxCFwiXDMzMlwzMzMjQkJcMjA3IiBbcG9zaXRpb24gcXVvdGUgZXJyb3IgIkJhZCBidWZmZXIg cG9zaXRpb24gcmVxdWVzdGVkOiAlcyIgbGV0ICgoaGVyZSAocG9pbnQpKSkgYXBwZW5kIGJvbCAo KGJlZ2lubmluZy1vZi1saW5lKSkgZW9sICgoZW5kLW9mLWxpbmUpKSBib2QgKChzYXZlLW1hdGNo LWRhdGEgKHZoZGwtYmVnaW5uaW5nLW9mLWRlZnVuKSkpIGJvaSAoKGJhY2stdG8taW5kZW50YXRp b24pKSBlb2kgKChlbmQtb2YtbGluZSkgKHNraXAtY2hhcnMtYmFja3dhcmQgIiAJIikpIGJvbmwg KChmb3J3YXJkLWxpbmUgMSkpIGJvcGwgKChmb3J3YXJkLWxpbmUgLTEpKSBpb3BsICgoZm9yd2Fy ZC1saW5lIC0xKSAoYmFjay10by1pbmRlbnRhdGlvbikpIGlvbmwgKChmb3J3YXJkLWxpbmUgMSkg KGJhY2stdG8taW5kZW50YXRpb24pKSAiVW5rbm93biBidWZmZXIgcG9zaXRpb24gcmVxdWVzdGVk OiAlcyIgKChwcm9nMSAocG9pbnQpIChnb3RvLWNoYXIgaGVyZSkpKSBuaWxdIDYgKCMkIC4gMTE1 ODg2KV0pKQojQDU1IFNhZmVseSBleGVjdXRlIEJPRFksIHJldHVybiBuaWwgaWYgYW4gZXJyb3Ig b2NjdXJyZWQuHwooZGVmYWxpYXMgJ3ZoZGwtc2FmZSAnKG1hY3JvIC4gI1soJnJlc3QgYm9keSkg IlwzMDFcMzAyXDMwMwhCXDMwNEJCQlwyMDciIFtib2R5IGNvbmRpdGlvbi1jYXNlIG5pbCBwcm9n biAoKGVycm9yIG5pbCkpXSA0ICgjJCAuIDExNzE0OCldKSkKI0AxMTYgQSBzaW1wbGUgbWFjcm8g dG8gYXBwZW5kIHRoZSBzeW50YXggaW4gU1lNQk9MIHRvIHRoZSBzeW50YXggbGlzdC4KVHJ5IHRv IGluY3JlYXNlIHBlcmZvcm1hbmNlIGJ5IHVzaW5nIHRoaXMgbWFjcm8uHwooZGVmYWxpYXMgJ3Zo ZGwtYWRkLXN5bnRheCAnKG1hY3JvIC4gI1soc3ltYm9sICZvcHRpb25hbCByZWxwb3MpICJcMzAy XDMwM1wzMDRcMjExCAlFXDMwNUJCRVwyMDciIFtzeW1ib2wgcmVscG9zIHNldHEgdmhkbC1zeW50 YWN0aWMtY29udGV4dCBjb25zICh2aGRsLXN5bnRhY3RpYy1jb250ZXh0KV0gNiAoIyQgLiAxMTcz NDgpXSkpCiNAOTggQSBzaW1wbGUgbWFjcm8gdG8gcmV0dXJuIGNoZWNrIHRoZSBzeW50YXggbGlz dC4KVHJ5IHRvIGluY3JlYXNlIHBlcmZvcm1hbmNlIGJ5IHVzaW5nIHRoaXMgbWFjcm8uHwooZGVm YWxpYXMgJ3ZoZGwtaGFzLXN5bnRheCAnKG1hY3JvIC4gI1soc3ltYm9sKSAiXDMwMQhcMzAyQkJc MjA3IiBbc3ltYm9sIGFzc29jICh2aGRsLXN5bnRhY3RpYy1jb250ZXh0KV0gMyAoIyQgLiAxMTc2 NjApXSkpCiNAODAgUmVhZCBuZXcgb2Zmc2V0IHZhbHVlIGZvciBMQU5HRUxFTSBmcm9tIG1pbmli dWZmZXIuClJldHVybiBhIGxlZ2FsIHZhbHVlIG9ubHkuHwooZGVmYWxpYXMgJ3ZoZGwtcmVhZC1v ZmZzZXQgI1sobGFuZ2VsZW0pICJcMzA2XDMwNwgJXDIzNlwyNDNcIlwzMTBcMzExXDMxMlwyMTFc MjExGhscHR4bHhxcZlwyMDR3AFwzMTMNDhxcIlwyMTETXDMxNFwyMzBcMjAzKABcMzE1XDIwMnIA C1wzMTZcMjMwXDIwMzIAXDMxN1wyMDJyAAtcMzIwXDIzMFwyMDM8AFwzMjFcMjAycgALXDMyMlwy MzBcMjAzRgBcMzIzXDIwMnIAXDMyNFwzMjULXCJcMjAzUwBcMzI2CyFcMjAycgBcMzI3XDMzMAsh XDIxMRIhXDIwM2EAXG5cMjAycgBcMzMxXG4hXDIwM2sAXG5cMjAycgBcMzMyIFwyMTAOGxVcMzEy XDIxMRRcMjAzGABcZi4GXDIwNyIgW2xhbmdlbGVtIHZoZGwtb2Zmc2V0cy1hbGlzdCBpbnRlcm5l ZCBpbnB1dCBvZmZzZXQgcHJvbXB0IGZvcm1hdCAiJXMiICJPZmZzZXQgbXVzdCBiZSBpbnQsIGZ1 bmMsIHZhciwgb3Igb25lIG9mICssIC0sICsrLCAtLTogIiAiT2Zmc2V0OiAiIG5pbCByZWFkLXN0 cmluZyAiKyIgKyAiLSIgLSAiKysiICsrICItLSIgLS0gc3RyaW5nLW1hdGNoICJeLT9bMC05XSsk IiBzdHJpbmctdG8taW50IGZib3VuZHAgaW50ZXJuIGJvdW5kcCBkaW5nIGVycm1zZyBvbGRvZmZd IDcgKCMkIC4gMTE3ODg4KV0pCiNAMjcyIENoYW5nZSB0aGUgdmFsdWUgb2YgYSBzeW50YWN0aWMg ZWxlbWVudCBzeW1ib2wgaW4gYHZoZGwtb2Zmc2V0cy1hbGlzdCcuClNZTUJPTCBpcyB0aGUgc3lu dGFjdGljIGVsZW1lbnQgc3ltYm9sIHRvIGNoYW5nZSBhbmQgT0ZGU0VUIGlzIHRoZSBuZXcKb2Zm c2V0IGZvciB0aGF0IHN5bnRhY3RpYyBlbGVtZW50LiAgT3B0aW9uYWwgQUREIHNheXMgdG8gYWRk IFNZTUJPTCB0bwpgdmhkbC1vZmZzZXRzLWFsaXN0JyBpZiBpdCBkb2Vzbid0IGFscmVhZHkgYXBw ZWFyIHRoZXJlLh8KKGRlZmFsaWFzICd2aGRsLXNldC1vZmZzZXQgI1soc3ltYm9sIG9mZnNldCAm b3B0aW9uYWwgYWRkLXApICIIXDMwNT1cMjA0LgAIXDMwNj1cMjA0LgAIXDMwNz1cMjA0LgAIXDMx MD1cMjA0LgAIXDI1MFwyMDQuAFwzMTEIIVwyMDQuAFwzMTIIIVwyMDQuAFwzMTNcMzE0CFwiXDIx MAlcblwyMzZcMjExG1wyMDM9AAsIXDI0MVwyMTBcMjAyTwBcZlwyMDNKAAkIQlxuQhJcMjAyTwBc MzEzXDMxNQlcIlwyMTApXDMxNiBcMjA3IiBbb2Zmc2V0IHN5bWJvbCB2aGRsLW9mZnNldHMtYWxp c3QgZW50cnkgYWRkLXAgKyAtICsrIC0tIGZib3VuZHAgYm91bmRwIGVycm9yICJPZmZzZXQgbXVz dCBiZSBpbnQsIGZ1bmMsIHZhciwgb3Igb25lIG9mICssIC0sICsrLCAtLTogJXMiICIlcyBpcyBu b3QgYSB2YWxpZCBzeW50YWN0aWMgc3ltYm9sIiB2aGRsLWtlZXAtcmVnaW9uLWFjdGl2ZV0gNCAo IyQgLiAxMTg1ODUpIChsZXQqICgobGFuZ2VsZW0gKGludGVybiAoY29tcGxldGluZy1yZWFkIChj b25jYXQgIlN5bnRhY3RpYyBzeW1ib2wgdG8gY2hhbmdlIiAoaWYgY3VycmVudC1wcmVmaXgtYXJn ICIgb3IgYWRkIiAiIikgIjogIikgKG1hcGNhciAjJyhsYW1iZGEgKGxhbmdlbGVtKSAoY29ucyAo Zm9ybWF0ICIlcyIgKGNhciBsYW5nZWxlbSkpIG5pbCkpIHZoZGwtb2Zmc2V0cy1hbGlzdCkgbmls IChub3QgY3VycmVudC1wcmVmaXgtYXJnKSAobGV0KiAoKHN5bnRheCAodmhkbC1nZXQtc3ludGFj dGljLWNvbnRleHQpKSAobGVuIChsZW5ndGggc3ludGF4KSkgKGljIChmb3JtYXQgIiVzIiAoY2Fy IChudGggKDEtIGxlbikgc3ludGF4KSkpKSkgaWMpKSkpIChvZmZzZXQgKHZoZGwtcmVhZC1vZmZz ZXQgbGFuZ2VsZW0pKSkgKGxpc3QgbGFuZ2VsZW0gb2Zmc2V0IGN1cnJlbnQtcHJlZml4LWFyZykp XSkKI0A0MTggU2V0IGB2aGRsLW1vZGUnIHZhcmlhYmxlcyB0byB1c2Ugb25lIG9mIHNldmVyYWwg ZGlmZmVyZW50IGluZGVudGF0aW9uIHN0eWxlcy4KU1RZTEUgaXMgYSBzdHJpbmcgcmVwcmVzZW50 aW5nIHRoZSBkZXNpcmVkIHN0eWxlIGFuZCBvcHRpb25hbCBMT0NBTCBpcwphIGZsYWcgd2hpY2gs IGlmIG5vbi1uaWwsIG1lYW5zIHRvIG1ha2UgdGhlIHN0eWxlIHZhcmlhYmxlcyBiZWluZwpjaGFu Z2VkIGJ1ZmZlciBsb2NhbCwgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCwgd2hpY2ggaXMgdG8gc2V0 IHRoZQpnbG9iYWwgdmFyaWFibGVzLiAgSW50ZXJhY3RpdmVseSwgdGhlIGZsYWcgY29tZXMgZnJv bSB0aGUgcHJlZml4CmFyZ3VtZW50LiAgVGhlIHN0eWxlcyBhcmUgY2hvc2VuIGZyb20gdGhlIGB2 aGRsLXN0eWxlLWFsaXN0JyB2YXJpYWJsZS4fCihkZWZhbGlhcyAndmhkbC1zZXQtc3R5bGUgI1so c3R5bGUgJm9wdGlvbmFsIGxvY2FsKSAiXDMwMwgJXCJBXDIxMRpcMjA0DwBcMzA0XDMwNQhcIlwy MTBcMzA2XDMwN1xuXCJcMjEwKVwzMTAgXDIwNyIgW3N0eWxlIHZoZGwtc3R5bGUtYWxpc3QgdmFy cyBhc3NvYyBlcnJvciAiSW52YWxpZCBWSERMIGluZGVudGF0aW9uIHN0eWxlIGAlcyciIG1hcGNh ciAjWyh2YXJlbnRyeSkgIghACEEZGgtcMjAzDgBcMzA2XG4hXDIxMFxuXDMwNT1cMjA0GgBcbglM XDIwMlwiAFwzMDdcZiEVXDMxMFwzMTEJXCIqXDIwNyIgW3ZhcmVudHJ5IHZhbCB2YXIgbG9jYWwg dmhkbC1vZmZzZXRzLWFsaXN0LWRlZmF1bHQgdmhkbC1vZmZzZXRzLWFsaXN0IG1ha2UtbG9jYWwt dmFyaWFibGUgY29weS1hbGlzdCBtYXBjYXIgI1sobGFuZ2VudHJ5KSAiCEAIQRkaXDMwM1xuCVwi KlwyMDciIFtsYW5nZW50cnkgb2Zmc2V0IGxhbmdlbGVtIHZoZGwtc2V0LW9mZnNldF0gM11dIDNd IHZoZGwta2VlcC1yZWdpb24tYWN0aXZlXSA0ICgjJCAuIDExOTc2NikgKGxpc3QgKGNvbXBsZXRp bmctcmVhZCAiVXNlIHdoaWNoIFZIREwgaW5kZW50YXRpb24gc3R5bGU/ICIgdmhkbC1zdHlsZS1h bGlzdCBuaWwgdCkgY3VycmVudC1wcmVmaXgtYXJnKV0pCiNAMjcwIEdldCBvZmZzZXQgZnJvbSBM QU5HRUxFTSB3aGljaCBpcyBhIGNvbnMgY2VsbCBvZiB0aGUgZm9ybToKKFNZTUJPTCAuIFJFTFBP UykuICBUaGUgc3ltYm9sIGlzIG1hdGNoZWQgYWdhaW5zdAp2aGRsLW9mZnNldHMtYWxpc3QgYW5k IHRoZSBvZmZzZXQgZm91bmQgdGhlcmUgaXMgZWl0aGVyIHJldHVybmVkLApvciBhZGRlZCB0byB0 aGUgaW5kZW50YXRpb24gYXQgUkVMUE9TLiAgSWYgUkVMUE9TIGlzIG5pbCwgdGhlbgp0aGUgb2Zm c2V0IGlzIHNpbXBseSByZXR1cm5lZC4fCihkZWZhbGlhcyAndmhkbC1nZXQtb2Zmc2V0ICNbKGxh bmdlbGVtKSAiCEAZCEEaCQtcMjM2XDIxMRxcMjQzHVxmXDIwNCUADhBcMjAzHgBcMzA2XDMwNwlc IlwyMTBcMjAyeABcMzEwFVwzMTASXDIwMngADVwzMTE9XDIwMzEADhEVXDIwMngADVwzMTI9XDIw Mz4ADhFbFVwyMDJ4AA1cMzEzPVwyMDNOAA4RXDIxMVxcXDMxMFxcFVwyMDJ4AA1cMzE0PVwyMDNd AA4RW1wzMTVfFVwyMDJ4AA1cMjQ3XDIwNG8AXDMxNg0hXDIwM28ADQghFVwyMDJ4AA1cMjQ3XDIw NHgAXDMxNw0hFVxuXDIwM1wyMjYAXG5gHhJcMzEweVwyMTBgDhJiXDIxMClXXDIwM1wyMjYAXDIx MlxuYlwyMTBpKVwyMDJcMjI3AFwzMTANXFwsXDIwNyIgW2xhbmdlbGVtIHN5bWJvbCByZWxwb3Mg dmhkbC1vZmZzZXRzLWFsaXN0IG1hdGNoIG9mZnNldCBlcnJvciAiRG9uJ3Qga25vdyBob3cgdG8g aW5kZW50IGEgJXMiIDAgKyAtICsrIC0tIDIgZmJvdW5kcCBldmFsIHZoZGwtc3RyaWN0LXN5bnRh eC1wIHZoZGwtYmFzaWMtb2Zmc2V0IGhlcmVdIDQgKCMkIC4gMTIwODIzKV0pCiNANDIgRGV0ZXJt aW5lIGlmIHBvaW50IGlzIGluIGEgVkhETCBsaXRlcmFsLh8KKGRlZmFsaWFzICd2aGRsLWluLWxp dGVyYWwgI1soJm9wdGlvbmFsIGxpbSkgIlwyMTJcMzAyYBhcMzAzeVwyMTBgCGJcMjEwKWBcIhlc MzA0CThcMjAzGQBcMzA1XDIwMiQAXDMwNgk4XDIwMyMAXDMwN1wyMDIkAFwzMTAqXDIwNyIgW2hl cmUgc3RhdGUgcGFyc2UtcGFydGlhbC1zZXhwIDAgMyBzdHJpbmcgNCBjb21tZW50IG5pbF0gMyAo IyQgLiAxMjE2MzIpXSkKI0A0MiBEZXRlcm1pbmUgaWYgcG9pbnQgaXMgaW4gYSBWSERMIGxpdGVy YWwuHwooZGVmYWxpYXMgJ3ZoZGwtd2luLWlsICNbKCZvcHRpb25hbCBsaW0pICJcMjEyYBhcMzA1 GVwzMDUaC1wyMDYbAGAYXDMwNiAcXDMwN1wyMTZcMzEwIFwyMTAqYAhiXDIxMClcMjExG2JcMjEw YAhXXDIwM1wyMDUAXDMxMVwzMTIIXDMxMyNcMjA1MgBcMzE0XDIyNFwzMTRcMjI1e1wyMTESXDIw NDsAXDMwNVwyMDJcMjAxAFxuXDMxNVwyMzBcMjAzTgAIXDMwNX9cMjEwYFhcMjA1XDIwMQBcMzE2 XDIwMlwyMDEAXG5cMzE3XDIzMFwyMDNnAFwyMTRgCH1cMjEwXDMxMVwzMjAIXDMxMyMpP1wyMDVc MjAxAFwzMjFcMjAyXDIwMQBcblwzMjJcMjMwXDIwM1wyMDAAXDIxNGAIfVwyMTBcMzExXDMyMwhc MzEzIyk/XDIwNVwyMDEAXDMyMVwyMDJcMjAxAFwzMDURXDIwMh8ACS1cMjA3IiBbaGVyZSBzdGF0 ZSBtYXRjaCBsaW0gc2F2ZS1tYXRjaC1kYXRhLWludGVybmFsIG5pbCBtYXRjaC1kYXRhICgoc2V0 LW1hdGNoLWRhdGEgc2F2ZS1tYXRjaC1kYXRhLWludGVybmFsKSkgdmhkbC1iZWdpbm5pbmctb2Yt ZGVmdW4gcmUtc2VhcmNoLWZvcndhcmQgIi0tXFx8W1wiJ10iIG1vdmUgMCAiLS0iIGNvbW1lbnQg IlwiIiAiXFwoW15cXF1cXHxeXFwpXFwoXFxcXFxcXFxcXCkqXCIiIHN0cmluZyAiJyIgIlxcKFte XFxdXFx8XlxcKVxcKFxcXFxcXFxcXFwpPyciXSA1ICgjJCAuIDEyMTg4NildKQooYnl0ZS1jb2Rl ICJcMzAxXDMwMghcIlwyMDMLAFwzMDNcMzA0TVwyMTBcMzAxXDIwNyIgW2VtYWNzLXZlcnNpb24g c3RyaW5nLW1hdGNoICJXaW4tRW1hY3MiIHZoZGwtaW4tbGl0ZXJhbCB2aGRsLXdpbi1pbF0gMykK I0AzOSBGb3J3YXJkIHNraXAgb2Ygc3ludGFjdGljIHdoaXRlc3BhY2UuHwooZGVmYWxpYXMgJ3Zo ZGwtZm9yd2FyZC1zeW50YWN0aWMtd3MgI1soJm9wdGlvbmFsIGxpbSkgIlwyMTQIXDIwNgYAZFwy MTEYGWQaCGB9XDIxMAlgVT9cMjA1HwBgEVwzMDNcbiFcMjEwXDIwMg8ALFwyMDciIFtsaW0gaGVy ZSBodWdlbnVtIGZvcndhcmQtY29tbWVudF0gMyAoIyQgLiAxMjI3MjYpXSkKI0A1MCBGb3J3YXJk IHNraXAgc3ludGFjdGljIHdoaXRlc3BhY2UgZm9yIFdpbi1FbWFjcy4fCihkZWZhbGlhcyAndmhk bC13aW4tZnN3cyAjWygmb3B0aW9uYWwgbGltKSAiCFwyMDYFAGRcMzAyGRgJP1wyMDUjAFwzMDMI d1wyMTBcMzA0XDMwNSFcMjAzHQBcMzAyf1wyMTBcMjAyCABcMzA2XDIxMRFcMjAyCQAqXDIwNyIg W2xpbSBzdG9wIG5pbCAiIAlcbg1cZiIgbG9va2luZy1hdCAiLS0iIHRdIDMgKCMkIC4gMTIyOTQy KV0pCihieXRlLWNvZGUgIlwzMDFcMzAyCFwiXDIwMwsAXDMwM1wzMDRNXDIxMFwzMDFcMjA3IiBb ZW1hY3MtdmVyc2lvbiBzdHJpbmctbWF0Y2ggIldpbi1FbWFjcyIgdmhkbC1mb3J3YXJkLXN5bnRh Y3RpYy13cyB2aGRsLXdpbi1mc3dzXSAzKQojQDQyIEJhY2t3YXJkIHNraXAgb3ZlciBzeW50YWN0 aWMgd2hpdGVzcGFjZS4fCihkZWZhbGlhcyAndmhkbC1iYWNrd2FyZC1zeW50YWN0aWMtd3MgI1so Jm9wdGlvbmFsIGxpbSkgIlwyMTQIXDIwNgYAZVwyMTEYGWRbGghgV1wyMDUmAAhgfVwyMTAJYFU/ XDIwNSYAYBFcMzAzXG4hXDIxMFwyMDIWACxcMjA3IiBbbGltIGhlcmUgaHVnZW51bSBmb3J3YXJk LWNvbW1lbnRdIDMgKCMkIC4gMTIzMzIyKV0pCiNANTEgQmFja3dhcmQgc2tpcCBzeW50YWN0aWMg d2hpdGVzcGFjZSBmb3IgV2luLUVtYWNzLh8KKGRlZmFsaWFzICd2aGRsLXdpbi1ic3dzICNbKCZv cHRpb25hbCBsaW0pICIIXDIwNhQAYBlcMzA0IBpcMzA1XDIxNlwzMDYgXDIxMCpgCWJcMjEwKVwz MDcbGAs/XDIwNVUAXDMxMAh4XDIxMFwzMTEIIVwzMTI9XDIwM08AXDMxMwh4XDIxMFwzMTQIeFwy MTBnXDMxNVVcMjAzPgBgVGZcMzE1VVwyMDQXAGAIWFwyMDQXAFwzMTMIeFwyMTBcMzE0CHhcMjEw XDIwMjAAXDMxNlwyMTETXDIwMhgAKlwyMDciIFtsaW0gaGVyZSBzYXZlLW1hdGNoLWRhdGEtaW50 ZXJuYWwgc3RvcCBtYXRjaC1kYXRhICgoc2V0LW1hdGNoLWRhdGEgc2F2ZS1tYXRjaC1kYXRhLWlu dGVybmFsKSkgdmhkbC1iZWdpbm5pbmctb2YtZGVmdW4gbmlsICIgCVxuDVxmIiB2aGRsLWluLWxp dGVyYWwgY29tbWVudCAiXi0iICItIiA0NSB0XSAzICgjJCAuIDEyMzU1MildKQooYnl0ZS1jb2Rl ICJcMzAxXDMwMghcIlwyMDMLAFwzMDNcMzA0TVwyMTBcMzAxXDIwNyIgW2VtYWNzLXZlcnNpb24g c3RyaW5nLW1hdGNoICJXaW4tRW1hY3MiIHZoZGwtYmFja3dhcmQtc3ludGFjdGljLXdzIHZoZGwt d2luLWJzd3NdIDMpCiNAOTAgSWYgdGhlIGtleXdvcmQgYXQgUE9JTlQgaXMgYXQgYm9pLCB0aGVu IHJldHVybiAoY3VycmVudC1jb2x1bW4pIGF0CnRoYXQgcG9pbnQsIGVsc2UgbmlsLh8KKGRlZmFs aWFzICd2aGRsLWZpcnN0LXdvcmQgI1socG9pbnQpICJcMjEyCGJcMjA1FgBgYBlcMzAyIFwyMTBg CWJcMjEwKT1cMjA1FgBpKVwyMDciIFtwb2ludCBoZXJlIGJhY2stdG8taW5kZW50YXRpb25dIDMg KCMkIC4gMTI0MTY0KV0pCiNAOTAgSWYgdGhlIGtleXdvcmQgYXQgUE9JTlQgaXMgYXQgZW9pLCB0 aGVuIHJldHVybiAoY3VycmVudC1jb2x1bW4pIGF0CnRoYXQgcG9pbnQsIGVsc2UgbmlsLh8KKGRl ZmFsaWFzICd2aGRsLWxhc3Qtd29yZCAjWyhwb2ludCkgIlwyMTIIYlwyMDUlAFwyMTJcMzAyIFwy MTBgYBlcMzAzf1wyMTBcMzA0XDMwM3hcMjEwYAliXDIxMCk9XDIwNiAAXDMwNVwzMDYhKVwyMDUl AGkpXDIwNyIgW3BvaW50IGhlcmUgZm9yd2FyZC1zZXhwIG5pbCAiIAkiIGxvb2tpbmctYXQgIlxc cy0qXFwoLS1cXCk/Il0gMyAoIyQgLiAxMjQzOTUpXSkKKGJ5dGUtY29kZSAiXDMwMhBcMzAwCUIR XDMwMFwyMDciIFt2aGRsLWxpYnVuaXQtcmUgY3VycmVudC1sb2FkLWxpc3QgIlxcYlxcKGFyY2hp dGVjdHVyZVxcfGNvbmZpZ3VyYXRpb25cXHxlbnRpdHlcXHxwYWNrYWdlXFwpXFxiW15fXSJdIDIp CihkZWZhbGlhcyAndmhkbC1saWJ1bml0LXAgI1tuaWwgIlwyMTJcMzAwIFwyMTBcMzAxXDMwMndc MjEwXDMwM1wzMDQhKT9cMjA1JgBcMjEyXDMwNSBcMjEwXDMwM1wzMDYhP1wyMDUlAFwzMDAgXDIx MFwzMDcgXDIxMGdcMzEwVT8pXDIwNyIgW2ZvcndhcmQtc2V4cCAiIAlcbiIgbmlsIGxvb2tpbmct YXQgImlzXFxiW15fXSIgYmFja3dhcmQtc2V4cCAidXNlXFxiW15fXSIgdmhkbC1mb3J3YXJkLXN5 bnRhY3RpYy13cyA1OF0gMl0pCihieXRlLWNvZGUgIlwzMDIQXDMwMAlCEVwzMDBcMjA3IiBbdmhk bC1kZWZ1bi1yZSBjdXJyZW50LWxvYWQtbGlzdCAiXFxiXFwoYXJjaGl0ZWN0dXJlXFx8YmxvY2tc XHxjb25maWd1cmF0aW9uXFx8ZW50aXR5XFx8cGFja2FnZVxcfHByb2Nlc3NcXHxwcm9jZWR1cmFs XFx8cHJvY2VkdXJlXFx8ZnVuY3Rpb25cXClcXGJbXl9dIl0gMikKKGRlZmFsaWFzICd2aGRsLWRl ZnVuLXAgI1tuaWwgIlwyMTJcMzAwXDMwMSFcMjAzEwBcMjEyXDMwMiBcMjEwXDMwMFwzMDMhKT9c MjAyFABcMzA0KVwyMDciIFtsb29raW5nLWF0ICJibG9ja1xcfHByb2Nlc3NcXHxwcm9jZWR1cmFs IiBiYWNrd2FyZC1zZXhwICJlbmRcXHMtK1xcdyIgdF0gMl0pCiNAMTY5IElmIHRoZSB3b3JkIGF0 IHRoZSBjdXJyZW50IHBvc2l0aW9uIGNvcnJlc3BvbmRzIHRvIGEgImRlZnVuIgprZXl3b3JkLCB0 aGVuIHJldHVybiBhIHN0cmluZyB0aGF0IGNhbiBiZSB1c2VkIHRvIGZpbmQgdGhlCmNvcnJlc3Bv bmRpbmcgImJlZ2luIiBrZXl3b3JkLCBlbHNlIHJldHVybiBuaWwuHwooZGVmYWxpYXMgJ3ZoZGwt Y29ycmVzcG9uZGluZy1kZWZ1biAjW25pbCAiXDIxMlwzMDEIIVwyMDUbAFwzMDIgXDIwNRsAXDMw MVwzMDMhXDIwMxoAXDMwNFwyMjRcMzA0XDIyNXtcMjAyGwBcMzA1KVwyMDciIFt2aGRsLWRlZnVu LXJlIGxvb2tpbmctYXQgdmhkbC1kZWZ1bi1wICJibG9ja1xcfHByb2Nlc3NcXHxwcm9jZWR1cmFs IiAwICJpcyJdIDIgKCMkIC4gMTI1NDQzKV0pCiNAODUgQSByZWd1bGFyIGV4cHJlc3Npb24gZm9y IHNlYXJjaGluZyBmb3J3YXJkIHRoYXQgbWF0Y2hlcyBhbGwga25vd24KImJlZ2luIiBrZXl3b3Jk cy4fCihkZWZjb25zdCB2aGRsLWJlZ2luLWZ3ZC1yZSAiXFxiXFwoaXNcXHxiZWdpblxcfGJsb2Nr XFx8Y29tcG9uZW50XFx8Z2VuZXJhdGVcXHx0aGVuXFx8ZWxzZVxcfGxvb3BcXHxwcm9jZXNzXFx8 cHJvY2VkdXJhbFxcfHVuaXRzXFx8cmVjb3JkXFx8Zm9yXFwpXFxiXFwoW15fXVxcfFxcJ1xcKSIg KCMkIC4gMTI1ODMyKSkKI0A4NiBBIHJlZ3VsYXIgZXhwcmVzc2lvbiBmb3Igc2VhcmNoaW5nIGJh Y2t3YXJkIHRoYXQgbWF0Y2hlcyBhbGwga25vd24KImJlZ2luIiBrZXl3b3Jkcy4fCihkZWZjb25z dCB2aGRsLWJlZ2luLWJ3ZC1yZSAiXFxiXFwoaXNcXHxiZWdpblxcfGJsb2NrXFx8Y29tcG9uZW50 XFx8Z2VuZXJhdGVcXHx0aGVuXFx8ZWxzZVxcfGxvb3BcXHxwcm9jZXNzXFx8cHJvY2VkdXJhbFxc fHVuaXRzXFx8cmVjb3JkXFx8Zm9yXFwpXFxiW15fXSIgKCMkIC4gMTI2MTA0KSkKI0AyNjUgUmV0 dXJuIHQgaWYgd2UgYXJlIGxvb2tpbmcgYXQgYSByZWFsICJiZWdpbiIga2V5d29yZC4KQXNzdW1l cyB0aGF0IHRoZSBjYWxsZXIgd2lsbCBtYWtlIHN1cmUgdGhhdCB3ZSBhcmUgbG9va2luZyBhdAp2 aGRsLWJlZ2luLWZ3ZC1yZSwgYW5kIGFyZSBub3QgaW5zaWRlIGEgbGl0ZXJhbCwgYW5kIHRoYXQg d2UgYXJlIG5vdCBpbgp0aGUgbWlkZGxlIG9mIGFuIGlkZW50aWZpZXIgdGhhdCBqdXN0IGhhcHBl bnMgdG8gY29udGFpbiBhICJiZWdpbiIKa2V5d29yZC4fCihkZWZhbGlhcyAndmhkbC1iZWdpbi1w ICNbKCZvcHRpb25hbCBsaW0pICJcMzAzXDMwNCFcMjAzQgBcMjEyXDMwNSBcMjEwXDMwNhgIXDIw NDAAXDMwN1wzMTAJXDMxMSNcMjAzMABoXDMxMlVcMjA0JABcMzEzCSFcMjAzKgBcMzE0IFwyMTBc MjAyXGYAXDMxNVwyMTEQXDIwMxAAKWdcMzE2VT9cMjA1PABcMzAzXDMxNyE/KVwyMDNCAFwzMTVc MjA3XDMwM1wzMjAhXDIwM0oAXDMxNVwyMDdcMzAzXDMyMSFcMjAzZgBcMjEyXDMwN1wzMjIJXDMx MSNcMjEwZ1wzMTY9XDIwNmAAYAk9KVwyMDNmAFwzMTVcMjA3XDMwM1wzMjMhXDIwM3kAXDIxMlwz MDUgXDIxMFwzMDNcMzI0ISlcMjA0eQBcMzE1XDIwN1wzMDNcMzI1IVwyMDNcMjMwAFwyMTJcMzA1 IFwyMTBcMzAzXDMyNCEpXDIwNFwyMzAAXDIxMlwzMjYJIVwyMTBoXDMyN1UpXDIwNFwyMzAAXDMx NVwyMDdcMzAzXDMzMCFcMjA1XDI2MgBcMjEyXDMwNSBcMjEwXDMwM1wzMjQhKT9cMjA1XDI2MgBc MzMxXDMzMlxuXCJcMjA1XDI2MgBcMzE1XDIwNyIgW2ZvdW5kcCBsaW0gdmhkbC1zeW50YWN0aWMt Y29udGV4dCBsb29raW5nLWF0ICJpIiBiYWNrd2FyZC1zZXhwIG5pbCByZS1zZWFyY2gtYmFja3dh cmQgIjtcXHxcXGJcXChhcmNoaXRlY3R1cmVcXHxjYXNlXFx8Y29uZmlndXJhdGlvblxcfGVudGl0 eVxcfHBhY2thZ2VcXHxwcm9jZWR1cmVcXHxyZXR1cm5cXHxpc1xcfGJlZ2luXFx8cHJvY2Vzc1xc fHByb2NlZHVyYWxcXHxibG9ja1xcKVxcYlteX10iIG1vdmUgOTUgdmhkbC1pbi1saXRlcmFsIGJh Y2t3YXJkLWNoYXIgdCA1OSAiaXNcXHxiZWdpblxcfHByb2Nlc3NcXHxwcm9jZWR1cmFsXFx8Ymxv Y2siICJiZVxcfHQiICJlIiAiO1xcfFxcYndoZW5cXGJbXl9dIiAiYmxcXHxbZ2xwdXJdIiAiZW5k XFxzLStcXHciICJjIiB2aGRsLWJhY2t3YXJkLXN5bnRhY3RpYy13cyA1OCAiZiIgYXNzb2MgY29u ZmlndXJhdGlvbl0gNSAoIyQgLiAxMjYzNjYpXSkKKGRlZmFsaWFzICd2aGRsLWNvcnJlc3BvbmRp bmctbWlkICNbKCZvcHRpb25hbCBsaW0pICJcMzAwXDMwMSFcMjAzCABcMzAyXDIwN1wzMDBcMzAz IVwyMDMQAFwzMDRcMjA3XDMwNVwyMDciIFtsb29raW5nLWF0ICJpc1xcfGJsb2NrXFx8Z2VuZXJh dGVcXHxwcm9jZXNzXFx8cHJvY2VkdXJhbCIgImJlZ2luIiAidGhlbiIgIjxlbHNlPiIgImVuZCJd IDJdKQojQDQ0OSBJZiB0aGUgd29yZCBhdCB0aGUgY3VycmVudCBwb3NpdGlvbiBjb3JyZXNwb25k cyB0byBhICJiZWdpbiIKa2V5d29yZCwgdGhlbiByZXR1cm4gYSB2ZWN0b3IgY29udGFpbmluZyBl bm91Z2ggaW5mb3JtYXRpb24gdG8gZmluZAp0aGUgY29ycmVzcG9uZGluZyAiZW5kIiBrZXl3b3Jk LCBlbHNlIHJldHVybiBuaWwuICBUaGUga2V5d29yZCB0bwpzZWFyY2ggZm9yd2FyZCBmb3IgaXMg YXJlZiAwLiAgVGhlIGNvbHVtbiBpbiB3aGljaCB0aGUga2V5d29yZCBtdXN0CmFwcGVhciBpcyBh cmVmIDEgb3IgbmlsIGlmIGFueSBjb2x1bW4gaXMgc3VpdGFibGUuCkFzc3VtZXMgdGhhdCB0aGUg Y2FsbGVyIHdpbGwgbWFrZSBzdXJlIHRoYXQgd2UgYXJlIG5vdCBpbiB0aGUgbWlkZGxlCm9mIGFu IGlkZW50aWZpZXIgdGhhdCBqdXN0IGhhcHBlbnMgdG8gY29udGFpbiBhICJiZWdpbiIga2V5d29y ZC4fCihkZWZhbGlhcyAndmhkbC1jb3JyZXNwb25kaW5nLWVuZCAjWygmb3B0aW9uYWwgbGltKSAi XDIxMlwzMDIIIVwyMDVcMjYzAGhcMzAzVT9cMjA1XDI2MwBcMzA0CSE/XDIwNVwyNjMAXDMwNQkh XDIwNVwyNjMAXDMwMlwzMDYhXDIwM0AAXDMwN1wzMTBcMzExYCFcMjA1PABcMzEyYCFcMjA2PABc MjEyXDMxMwkhXDIxMFwzMTQJIVwyMTBcMzEyYCEpXCJcMjAyXDI2MwBcMzAyXDMxNSFcMjAzZQBc MzA3XDMxMFwzMTFgIVwyMDVhAFwzMTJgIVwyMDZhAFwyMTJcMzEzCSFcMjEwXDMxNAkhXDIxMFwz MTJgISlcIlwyMDJcMjYzAFwzMDJcMzE2IVwyMDNyAFwzMDdcMzEwXDMxN1wiXDIwMlwyNjMAXDMw MlwzMjAhXDIwM1wyMjEAXDMwN1wzMTBcMzEyYCFcMjA2XDIxNQBcMjEyXDMxMwkhXDIxMFwzMTQJ IVwyMTBcMzEyYCEpXCJcMjAyXDI2MwBcMzAyXDMyMSFcMjA1XDI2MwBcMzA3XDMyMlwzMTFgIVwy MDVcMjYyAFwzMTJgIVwyMDZcMjYyAFwyMTJcMzEzCSFcMjEwXDMxNAkhXDIxMFwzMTJgISlcIilc MjA3IiBbdmhkbC1iZWdpbi1md2QtcmUgbGltIGxvb2tpbmctYXQgOTUgdmhkbC1pbi1saXRlcmFs IHZoZGwtYmVnaW4tcCAiW2lnbF0iIHZlY3RvciAiZW5kIiB2aGRsLWxhc3Qtd29yZCB2aGRsLWZp cnN0LXdvcmQgdmhkbC1iZWdpbm5pbmctb2Ytc3RhdGVtZW50LTEgdmhkbC1iYWNrd2FyZC1za2lw LWxhYmVsICJiZVxcfFtlZl0iICJbY3VyXSIgbmlsICJibFxcfHAiICJ0IiAiZWxzaWZcXHxlbHNl XFx8ZW5kXFxzLStpZiJdIDQgKCMkIC4gMTI3ODA1KV0pCihieXRlLWNvZGUgIlwzMDMQXDMwMAlC EVwzMDQSXDMwMglCEVwzMDBcMjA3IiBbdmhkbC1lbmQtZndkLXJlIGN1cnJlbnQtbG9hZC1saXN0 IHZoZGwtZW5kLWJ3ZC1yZSAiXFxiXFwoZW5kXFx8ZWxzZVxcfGVsc2lmXFwpXFxiXFwoW15fXVxc fFxcJ1xcKSIgIlxcYlxcKGVuZFxcfGVsc2VcXHxlbHNpZlxcKVxcYlteX10iXSAyKQojQDI2MCBS ZXR1cm4gdCBpZiB3ZSBhcmUgbG9va2luZyBhdCBhIHJlYWwgImVuZCIga2V5d29yZC4KQXNzdW1l cyB0aGF0IHRoZSBjYWxsZXIgd2lsbCBtYWtlIHN1cmUgdGhhdCB3ZSBhcmUgbG9va2luZyBhdAp2 aGRsLWVuZC1md2QtcmUsIGFuZCBhcmUgbm90IGluc2lkZSBhIGxpdGVyYWwsIGFuZCB0aGF0IHdl IGFyZSBub3QgaW4KdGhlIG1pZGRsZSBvZiBhbiBpZGVudGlmaWVyIHRoYXQganVzdCBoYXBwZW5z IHRvIGNvbnRhaW4gYW4gImVuZCIKa2V5d29yZC4fCihkZWZhbGlhcyAndmhkbC1lbmQtcCAjWygm b3B0aW9uYWwgbGltKSAiXDMwMVwzMDIhP1wyMDYYAFwyMTJcMzAzXDMwNAhcMzA1I1wyMTBnXDMw Nj1cMjA2FwBgCD0pXDIwNyIgW2xpbSBsb29raW5nLWF0ICJlbHNlIiByZS1zZWFyY2gtYmFja3dh cmQgIjtcXHxcXGJ3aGVuXFxiW15fXSIgbW92ZSA1OV0gNCAoIyQgLiAxMjkyMTgpXSkKI0A2Mjkg SWYgdGhlIHdvcmQgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24gY29ycmVzcG9uZHMgdG8gYW4gImVu ZCIKa2V5d29yZCwgdGhlbiByZXR1cm4gYSB2ZWN0b3IgY29udGFpbmluZyBlbm91Z2ggaW5mb3Jt YXRpb24gdG8gZmluZAp0aGUgY29ycmVzcG9uZGluZyAiYmVnaW4iIGtleXdvcmQsIGVsc2UgcmV0 dXJuIG5pbC4gIFRoZSBrZXl3b3JkIHRvCnNlYXJjaCBiYWNrd2FyZCBmb3IgaXMgYXJlZiAwLiAg ICAgVGhlIGNvbHVtbiBpbiB3aGljaCB0aGUga2V5d29yZCBtdXN0CmFwcGVhciBpcyBhcmVmIDEg b3IgbmlsIGlmIGFueSBjb2x1bW4gaXMgc3VpdGFibGUuICBUaGUgc3VwcGxlbWVudGFyeQprZXl3 b3JkIHRvIHNlYXJjaCBmb3J3YXJkIGZvciBpcyBhcmVmIDIgb3IgbmlsIGlmIHRoaXMgaXMgbm90 CnJlcXVpcmVkLiAgSWYgYXJlZiAzIGlzIHQsIHRoZW4gdGhlICJiZWdpbiIga2V5d29yZCBtYXkg YmUgZm91bmQgaW4KdGhlIG1pZGRsZSBvZiBhIHN0YXRlbWVudC4KQXNzdW1lcyB0aGF0IHRoZSBj YWxsZXIgd2lsbCBtYWtlIHN1cmUgdGhhdCB3ZSBhcmUgbm90IGluIHRoZSBtaWRkbGUKb2YgYW4g aWRlbnRpZmllciB0aGF0IGp1c3QgaGFwcGVucyB0byBjb250YWluIGFuICJlbmQiIGtleXdvcmQu HwooZGVmYWxpYXMgJ3ZoZGwtY29ycmVzcG9uZGluZy1iZWdpbiAjWygmb3B0aW9uYWwgbGltKSAi XDIxMlwzMDMYXDMwNAkhXDIwNVwzMTAAXDMwNVxuIT9cMjA1XDMxMABcMzA2XG4hXDIwNVwzMTAA XDMwNFwzMDchXDIwMycAXDMxMFwzMTFcMzEyYCFcMzEzXDMwMyRcMjAyXDMxMABgEFwzMTQgXDIx MFwzMTVcMzAzd1wyMTBcMzA0XDMxNiFcMjAzQQBcMzEwXDMxN1wzMTIIIVwzMjBcMzAzJFwyMDJc MzEwAFwzMDRcMzIxIVwyMDNWAFwzMTBcMzIyXDIyNFwzMjJcMjI1e1wzMTIIIVwzMDNcMjExJFwy MDJcMzEwAFwzMDRcMzIzIVwyMDNrAFwzMTBcMzIyXDIyNFwzMjJcMjI1e1wzMTIIIVwzMDNcMzI0 JFwyMDJcMzEwAFwzMDRcMzI1IVwyMDN8AFwzMTBcMzI2XDMxMgghXDMwM1wyMTEkXDIwMlwzMTAA XDMwNFwzMjchXDIwM1wyMTUAXDMxMFwzMzBcMzEyCCFcMzMxXDMwMyRcMjAyXDMxMABcMzA0XDMz MiFcMjAzXDIzNgBcMzEwXDMzM1wzMTIIIVwzMzRcMzAzJFwyMDJcMzEwAFwzMDRcMzM1IVwyMDNc MjU3AFwzMTBcMzM2XDMxMgghXDMzN1wzMDMkXDIwMlwzMTAAXDMwNFwzNDAhXDIwM1wzMDAAXDMx MFwzNDFcMzEyCCFcMzAzXDIxMSRcMjAyXDMxMABcMzEwXDM0MlwzMTIIIVwzNDNcMzAzJCpcMjA3 IiBbcG9zIHZoZGwtZW5kLWZ3ZC1yZSBsaW0gbmlsIGxvb2tpbmctYXQgdmhkbC1pbi1saXRlcmFs IHZoZGwtZW5kLXAgImVsIiB2ZWN0b3IgImlmXFx8ZWxzaWYiIHZoZGwtZmlyc3Qtd29yZCAidGhl biIgZm9yd2FyZC1zZXhwICIgCVxuIiAiaWZcXGJbXl9dIiAiZWxzZVxcfGVsc2lmXFx8aWYiICJl bHNlXFx8dGhlbiIgImNvbXBvbmVudFxcYlteX10iIDEgIlxcKHVuaXRzXFx8cmVjb3JkXFwpXFxi W15fXSIgdCAiXFwoYmxvY2tcXHxwcm9jZXNzXFx8cHJvY2VkdXJhbFxcKVxcYlteX10iICJiZWdp biIgImNhc2VcXGJbXl9dIiAiY2FzZSIgImlzIiAiZ2VuZXJhdGVcXGJbXl9dIiAiZ2VuZXJhdGVc XHxmb3JcXHxpZiIgImdlbmVyYXRlIiAibG9vcFxcYlteX10iICJsb29wXFx8d2hpbGVcXHxmb3Ii ICJsb29wIiAiZm9yXFxiW15fXSIgImZvciIgImJlZ2luXFx8YXJjaGl0ZWN0dXJlXFx8Y29uZmln dXJhdGlvblxcfGVudGl0eVxcfHBhY2thZ2VcXHxwcm9jZWR1cmVcXHxmdW5jdGlvbiIgKCgiYmVn aW4iKSAoImFyY2hpdGVjdHVyZSIgLiAiaXMiKSAoImNvbmZpZ3VyYXRpb24iIC4gImlzIikgKCJl bnRpdHkiIC4gImlzIikgKCJwYWNrYWdlIiAuICJpcyIpICgicHJvY2VkdXJlIiAuICJpcyIpICgi ZnVuY3Rpb24iIC4gImlzIikpXSA1ICgjJCAuIDEyOTY3NSldKQooYnl0ZS1jb2RlICJcMzAyEFwz MDAJQhFcMzAwXDIwNyIgW3ZoZGwtbGVhZGVyLXJlIGN1cnJlbnQtbG9hZC1saXN0ICJcXGJcXChi bG9ja1xcfGNvbXBvbmVudFxcfHByb2Nlc3NcXHxwcm9jZWR1cmFsXFx8Zm9yXFwpXFxiW15fXSJd IDIpCihkZWZhbGlhcyAndmhkbC1lbmQtb2YtbGVhZGVyICNbbmlsICJcMjEyXDMwMFwzMDEhXDIw MyQAXDIxMlwzMDIgXDIxMFwzMDNcMzA0d1wyMTBnXDMwNVUpXDIwMx0AXDMwMlwzMDYhXDIxMFwy MDIgAFwzMDIgXDIxMGBcMjAyVQBcMzAwXDMwNyFcMjAzMgBcMzAyXDMwNiFcMjEwYFwyMDJVAFwz MDBcMzEwIVwyMDNUAFwzMDJcMzA2IVwyMTBcMzAzXDMwNHdcMjEwXDMwMFwzMTEhXDIwM1AAXDMw MiBcMjEwXDMwM1wzMDR3XDIxMFwyMDJAAGBcMjAyVQBcMzA0KVwyMDciIFtsb29raW5nLWF0ICJi bG9ja1xcfHByb2Nlc3NcXHxwcm9jZWR1cmFsIiBmb3J3YXJkLXNleHAgIiAJXG4iIG5pbCA0MCAy ICJjb21wb25lbnQiICJmb3IiICJbLDooXSJdIDJdKQooYnl0ZS1jb2RlICJcMzAyEFwzMDAJQhFc MzAwXDIwNyIgW3ZoZGwtdHJhaWxlci1yZSBjdXJyZW50LWxvYWQtbGlzdCAiXFxiXFwoaXNcXHx0 aGVuXFx8Z2VuZXJhdGVcXHxsb29wXFwpXFxiW15fXSJdIDIpCiNAODkgQSByZWd1bGFyIGV4cHJl c3Npb24gZm9yIHNlYXJjaGluZyBmb3J3YXJkIHRoYXQgbWF0Y2hlcyBhbGwga25vd24KInN0YXRl bWVudCIga2V5d29yZHMuHwooZGVmY29uc3QgdmhkbC1zdGF0ZW1lbnQtZndkLXJlICJcXGJcXChp ZlxcfGZvclxcfHdoaWxlXFwpXFxiXFwoW15fXVxcfFxcJ1xcKSIgKCMkIC4gMTMyMjI1KSkKI0A5 MCBBIHJlZ3VsYXIgZXhwcmVzc2lvbiBmb3Igc2VhcmNoaW5nIGJhY2t3YXJkIHRoYXQgbWF0Y2hl cyBhbGwga25vd24KInN0YXRlbWVudCIga2V5d29yZHMuHwooZGVmY29uc3QgdmhkbC1zdGF0ZW1l bnQtYndkLXJlICJcXGJcXChpZlxcfGZvclxcfHdoaWxlXFwpXFxiW15fXSIgKCMkIC4gMTMyNDEz KSkKI0AyNzcgUmV0dXJuIHQgaWYgd2UgYXJlIGxvb2tpbmcgYXQgYSByZWFsICJzdGF0ZW1lbnQi IGtleXdvcmQuCkFzc3VtZXMgdGhhdCB0aGUgY2FsbGVyIHdpbGwgbWFrZSBzdXJlIHRoYXQgd2Ug YXJlIGxvb2tpbmcgYXQKdmhkbC1zdGF0ZW1lbnQtZndkLXJlLCBhbmQgYXJlIG5vdCBpbnNpZGUg YSBsaXRlcmFsLCBhbmQgdGhhdCB3ZSBhcmUgbm90CmluIHRoZSBtaWRkbGUgb2YgYW4gaWRlbnRp ZmllciB0aGF0IGp1c3QgaGFwcGVucyB0byBjb250YWluIGEKInN0YXRlbWVudCIga2V5d29yZC4f CihkZWZhbGlhcyAndmhkbC1zdGF0ZW1lbnQtcCAjWygmb3B0aW9uYWwgbGltKSAiXDMwMFwzMDEh XDIwMyMAXDIxMlwzMDJcMzAzIVwyMTBcMzA0XDMwNXdcMjEwXDMwMFwzMDYhKVwyMDMjAFwyMTJc MzA3IFwyMTBcMzAwXDMxMCEpXDIwNCMAXDMxMVwyMDdcMzAwXDMxMiFcMjAzNgBcMjEyXDMwNyBc MjEwXDMwMFwzMTAhKVwyMDQ2AFwzMTFcMjA3XDMwMFwzMTMhXDIwNT0AXDMxMVwyMDciIFtsb29r aW5nLWF0ICJmIiBmb3J3YXJkLXNleHAgMiAiIAlcbiIgbmlsICJpblxcYlteX10iIGJhY2t3YXJk LXNleHAgImVuZFxccy0rXFx3IiB0ICJpIiAidyJdIDIgKCMkIC4gMTMyNTkxKV0pCiNANTMgUmVn ZXhwIGRlc2NyaWJpbmcgYSBjYXNlIHN0YXRlbWVudCBhbHRlcm5hdGl2ZSBrZXkuHwooZGVmY29u c3QgdmhkbC1jYXNlLWFsdGVybmF0aXZlLXJlICJ3aGVuWyggCVxuXVteOz0+XSs9PiIgKCMkIC4g MTMzMjA2KSkKI0AyNzIgUmV0dXJuIHQgaWYgd2UgYXJlIGxvb2tpbmcgYXQgYSByZWFsIGNhc2Ug YWx0ZXJuYXRpdmUuCkFzc3VtZXMgdGhhdCB0aGUgY2FsbGVyIHdpbGwgbWFrZSBzdXJlIHRoYXQg d2UgYXJlIGxvb2tpbmcgYXQKdmhkbC1jYXNlLWFsdGVybmF0aXZlLXJlLCBhbmQgYXJlIG5vdCBp bnNpZGUgYSBsaXRlcmFsLCBhbmQgdGhhdAp3ZSBhcmUgbm90IGluIHRoZSBtaWRkbGUgb2YgYW4g aWRlbnRpZmllciB0aGF0IGp1c3QgaGFwcGVucyB0bwpjb250YWluIGEgIndoZW4iIGtleXdvcmQu HwooZGVmYWxpYXMgJ3ZoZGwtY2FzZS1hbHRlcm5hdGl2ZS1wICNbKCZvcHRpb25hbCBsaW0pICJc MjEyXDMwMhgIXDIwNCcAXDMwM1wzMDQJXDMwNSNcMjAzJwBoXDMwNlVcMjA0GwBcMzA3CSFcMjAz IQBcMzEwIFwyMTBcMjAyAwBcMzExXDIxMRBcMjAzBwBnXDMxMj1cMjA2MABgCT0qXDIwNyIgW2Zv dW5kcCBsaW0gbmlsIHJlLXNlYXJjaC1iYWNrd2FyZCAiO1xcfDw9IiBtb3ZlIDk1IHZoZGwtaW4t bGl0ZXJhbCBiYWNrd2FyZC1jaGFyIHQgNTldIDUgKCMkIC4gMTMzMzM4KV0pCihieXRlLWNvZGUg IghcMzA0CVESXDMwMgtCE1wzMDJcMjA3IiBbdmhkbC1iZWdpbi1id2QtcmUgdmhkbC1lbmQtYndk LXJlIHZoZGwtYi10LWItcmUgY3VycmVudC1sb2FkLWxpc3QgIlxcfCJdIDMpCiNANTcgTW92ZSBi YWNrd2FyZCB0byB0aGUgcHJldmlvdXMgImJlZ2luIiBvciAiZW5kIiBrZXl3b3JkLh8KKGRlZmFs aWFzICd2aGRsLWJhY2t3YXJkLXRvLWJsb2NrICNbKCZvcHRpb25hbCBsaW0pICJcMzA1GAhcMjA0 UABcMzA2CVxuXDMwNyNcMjAzUABoXDMxMFVcMjA0GgBcMzExXG4hXDIwMyAAXDMxMiBcMjEwXDIw MgIAXDMxMwshXDIwMzgAaFwzMTBVXDIwNDgAXDMxNFxuIVwyMDM4AFwzMTVcMjExEFwyMDIDAFwz MTNcZiFcMjAzAgBoXDMxMFVcMjA0AgBcMzE2XG4hXDIwMwIAXDMxN1wyMTEQXDIwMwYACClcMjA3 IiBbZm91bmRwIHZoZGwtYi10LWItcmUgbGltIHZoZGwtYmVnaW4tZndkLXJlIHZoZGwtZW5kLWZ3 ZC1yZSBuaWwgcmUtc2VhcmNoLWJhY2t3YXJkIG1vdmUgOTUgdmhkbC1pbi1saXRlcmFsIGJhY2t3 YXJkLWNoYXIgbG9va2luZy1hdCB2aGRsLWJlZ2luLXAgYmVnaW4gdmhkbC1lbmQtcCBlbmRdIDUg KCMkIC4gMTM0MDAxKV0pCiNAODggTW92ZSBmb3J3YXJkIGFjcm9zcyBvbmUgYmFsYW5jZWQgZXhw cmVzc2lvbiAoc2V4cCkuCldpdGggQ09VTlQsIGRvIGl0IHRoYXQgbWFueSB0aW1lcy4fCihkZWZh bGlhcyAndmhkbC1mb3J3YXJkLXNleHAgI1soJm9wdGlvbmFsIGNvdW50IGxpbSkgIghcMjA2BQBc MzA2XDMwN1wzMTBcMjExGRobGFwyMTIIXDMxMVZcMjAzXDM0MABcMzEyXDMxMHdcMjEwXDMxM1xm IVwyMDM5AGhcMzE0VVwyMDQ5AFwzMTUNIVwyMDQ5AFwzMTYNIVwyMDM5AFwzMTNcMzE3IVwyMDQ5 AFwzMjBcMzIxIVwyMTBcMzIyDSFcMjExElwyMDNcMzI2AFwzMjNcblwzMTFIXDMyNFFcblwzMDZI YB4aXDMxMH9cMjEwYA4aYlwyMTApXDMxMFwyMTFcMjExHhseHB4dHh4eHx4gDh1cMjA0XDMxMABc MzI1DiBcMzEwXDMwNyNcMjAzXDMxMABcMzA2XDIyNVwyMTEWG1wyMDNcMzEwAFwzMTFcMjI0Ylwy MDNcMzEwAA4fXDIwM1wyMjUAXDMyNiAOH1VcMjA0XDIyNQBgDh5WXDIwNFwyNDQAaFwzMTRVXDIw NFwyNDQAXDMxNQ0hXDIxMRYcXDIwM1wyNjcADhxcMzI3PVwyMDNcMjYxAFwzMTB/XDIxMFwyMDJl AFwzMTB1XDIxMFwyMDJlAFwzMTNcMzE3IVwyMDRcMzAxAA4bYlwyMTBcMzA3XDIxMRYdXDIwM2oA Dh1cMjA0XDMyMQBcMzIwXDMzMCFcMjEwLgZcMjAyXDMzMQBcMzMxIFwyMTAIU1wyMTEQXDIwMg4A YBEpCWJcMjEwLFwzMTBcMjA3IiBbY291bnQgdGFyZ2V0IGVuZC12ZWMgY2FzZS1mb2xkLXNlYXJj aCB2aGRsLWVuZC1md2QtcmUgbGltIDEgdCBuaWwgMCAiIAlcbiIgbG9va2luZy1hdCA5NSB2aGRs LWluLWxpdGVyYWwgdmhkbC1lbmQtcCAiZWxzZSIgZXJyb3IgIkNvbnRhaW5pbmcgZXhwcmVzc2lv biBlbmRzIHByZW1hdHVyZWx5IGluIHZoZGwtZm9yd2FyZC1zZXhwIiB2aGRsLWNvcnJlc3BvbmRp bmctZW5kICJcXGJcXCgiICJcXClcXGJcXChbXl9dXFx8XFwnXFwpIiByZS1zZWFyY2gtZm9yd2Fy ZCBjdXJyZW50LWluZGVudGF0aW9uIGNvbW1lbnQgIlVuYmFsYW5jZWQga2V5d29yZHMgaW4gdmhk bC1mb3J3YXJkLXNleHAiIGZvcndhcmQtc2V4cCBoZXJlIHBsYWNlaG9sZGVyIGxpdGVyYWwgZm91 bmRwIGVvbCBjb2x1bW4gZW5kLXJlXSA3ICgjJCAuIDEzNDQ4NCkgInAiXSkKI0AxMzMgTW92ZSBi YWNrd2FyZCBhY3Jvc3Mgb25lIGJhbGFuY2VkIGV4cHJlc3Npb24gKHNleHApLgpXaXRoIENPVU5U LCBkbyBpdCB0aGF0IG1hbnkgdGltZXMuICBMSU0gYm91bmRzIGFueSByZXF1aXJlZCBiYWNrd2Fy ZApzZWFyY2hlcy4fCihkZWZhbGlhcyAndmhkbC1iYWNrd2FyZC1zZXhwICNbKCZvcHRpb25hbCBj b3VudCBsaW0pICIIXDIwNgUAXDMwNlwzMDdcMzEwXDIxMRkaGxhcMjEyCFwzMTFWXDIwM10BXDMx MlwzMTMhXDIwMyUAaFwzMTRVXDIwNCUAXDMxNVxmIVwyMDNEAFwzMTYgXDIxMFwzMTINIVwyMDNE AGhcMzE0VVwyMDREAFwzMTVcZiFcMjA0RABcMzE3XGYhXDIwM0QAXDMyMFwzMjEhXDIxMFwzMjJc ZiFcMjExElwyMDNWAWhcMzE0VVwyMDRWAVwzMjNcblwzMTFIXDMyNFFcblwzMDZIXG5cMzI1SGBc MzEwXDIxMVwyMTFcMjExHh4eHx4gHiEeXCIeIx4kHiUOIFwyMDRLAVwzMjYOJVxmXDMwNyNcMjAz SwFcMzA2XDIyNFwzMDZcMjI1e1wyMTEWHlwyMDNLAQ4kXDIwM1wyNDUAXDMyNyAOJFVcMjA0XDI0 NQAOI1wyMDNcMjYxAGkOJFVcMjAzXDI2MQBoXDMxNFVcMjA0XDI2MQBcMzE1XGYhXDIwM1wyNjcA XDMzMCBcMjEwXDIwMnMAXG5cMzMxSFwyMTEWJVwyMDNEAQ4lPFwyMDNcMzMzAFwzMzIOHg4lXCJc MjExFiVcMjAzRAEOJUFcMjExFiVcMjAzRAFcMzIzDiVcMzI0UVwyMTEWJVwyMDNzAFwyMTJgFiEO IFwyMDQ3AVwzMzMOJQ5cIlwzMDcjXDIwMzcBXDMwNlwyMjRiXDIwMzcBaFwzMTRVXDIwNA8BXDMx NQ4hIVwyMTEWH1wyMDMwAQ4fXDMzND1cMjAzKgFgHiZcMzEwf1wyMTBgDiZiXDIxMCkOXCJeYlwy MTBcMjAyXDM1MgBcMzEwdVwyMTBcMjAyXDM1MgBgXDIxMRYgXDIwM1wzNTcADiApXDIwM3MADiBi XDIxMFwyMDJzAFwzMDdcMjExFiBcMjAzeAAOIFwyMDRUAVwzMjBcMzM1IVwyMTAuCAhTXDIxMRBc MjAyDgBgESkJYlwyMTAsXDMxMFwyMDciIFtjb3VudCB0YXJnZXQgYmVnaW4tdmVjIGNhc2UtZm9s ZC1zZWFyY2ggbGltIHZoZGwtYmVnaW4tZndkLXJlIDEgdCBuaWwgMCBsb29raW5nLWF0ICJlbHNl XFxiXFwoW15fXVxcfFxcJ1xcKSIgOTUgdmhkbC1pbi1saXRlcmFsIGJhY2t3YXJkLXNleHAgdmhk bC1iZWdpbi1wIGVycm9yICJDb250YWluaW5nIGV4cHJlc3Npb24gZW5kcyBwcmVtYXR1cmVseSBp biB2aGRsLWJhY2t3YXJkLXNleHAiIHZoZGwtY29ycmVzcG9uZGluZy1iZWdpbiAiXFxiXFwoIiAi XFwpXFxiW15fXSIgMyByZS1zZWFyY2gtYmFja3dhcmQgY3VycmVudC1pbmRlbnRhdGlvbiBiYWNr d2FyZC1jaGFyIDIgYXNzb2MgcmUtc2VhcmNoLWZvcndhcmQgY29tbWVudCAiVW5iYWxhbmNlZCBr ZXl3b3JkcyBpbiB2aGRsLWJhY2t3YXJkLXNleHAiIGtleXdvcmQgbGl0ZXJhbCBmb3VuZHAgbGFz dC1mb3J3YXJkIGxhc3QtYmFja3dhcmQgaW50ZXJuYWwtcCBjb2x1bW4gYmVnaW4tcmUgaGVyZV0g OSAoIyQgLiAxMzU1OTcpICJwIl0pCiNAODMgTW92ZSBiYWNrd2FyZCBvdXQgb2Ygb25lIGxldmVs IG9mIGJsb2Nrcy4KV2l0aCBhcmd1bWVudCwgZG8gdGhpcyB0aGF0IG1hbnkgdGltZXMuHwooZGVm YWxpYXMgJ3ZoZGwtYmFja3dhcmQtdXAtbGlzdCAjWygmb3B0aW9uYWwgY291bnQgbGltaXQpICII XDIwNgUAXDMwNFwzMDUZGFwyMTIIXDMwNlZcMjAzJABcMzA3XG4hXDIwMxkAXDMxMFwzMTEhXDIx MFwzMTILIVwyMTAIU1wyMTEQXDIwMlxuAGARKQliKlwyMDciIFtjb3VudCB0YXJnZXQgdmhkbC1k ZWZ1bi1yZSBsaW1pdCAxIG5pbCAwIGxvb2tpbmctYXQgZXJyb3IgIlVuYmFsYW5jZWQgYmxvY2tz IiB2aGRsLWJhY2t3YXJkLXRvLWJsb2NrXSAzICgjJCAuIDEzNzA1NSkgInAiXSkKI0A0MiBNb3Zl IGZvcndhcmQgdG8gdGhlIGVuZCBvZiBhIFZIREwgZGVmdW4uHwooZGVmYWxpYXMgJ3ZoZGwtZW5k LW9mLWRlZnVuICNbKCZvcHRpb25hbCBjb3VudCkgIlwzMDEYXDMwMiBcMjEwXDMwM1wzMDQhXDIw NA8AXDMwNVwzMDYhXDIxMFwzMDcgKVwyMDciIFtjYXNlLWZvbGQtc2VhcmNoIHQgdmhkbC1iZWdp bm5pbmctb2YtZGVmdW4gbG9va2luZy1hdCAiYmxvY2tcXHxwcm9jZXNzXFx8cHJvY2VkdXJhbCIg cmUtc2VhcmNoLWZvcndhcmQgIlxcYmlzXFxiIiB2aGRsLWZvcndhcmQtc2V4cF0gMiAoIyQgLiAx Mzc0MjMpIG5pbF0pCiNANTQgUHV0IG1hcmsgYXQgZW5kIG9mIHRoaXMgImRlZnVuIiwgcG9pbnQg YXQgYmVnaW5uaW5nLh8KKGRlZmFsaWFzICd2aGRsLW1hcmstZGVmdW4gI1tuaWwgIlwzMDEYXDMw MiBcMjEwXDMwMyBcMjEwXDMwMiBcMjEwXDMwNFwzMDUhXDIwNBUAXDMwNlwzMDchXDIxMFwzMTAg XDIxMFwzMTEgKVwyMDciIFtjYXNlLWZvbGQtc2VhcmNoIHQgcHVzaC1tYXJrIHZoZGwtYmVnaW5u aW5nLW9mLWRlZnVuIGxvb2tpbmctYXQgImJsb2NrXFx8cHJvY2Vzc1xcfHByb2NlZHVyYWwiIHJl LXNlYXJjaC1mb3J3YXJkICJcXGJpc1xcYiIgdmhkbC1mb3J3YXJkLXNleHAgZXhjaGFuZ2UtcG9p bnQtYW5kLW1hcmtdIDIgKCMkIC4gMTM3NzMwKSBuaWxdKQojQDQ4NSBNb3ZlIGJhY2t3YXJkIHRv IHRoZSBiZWdpbm5pbmcgb2YgYSBWSERMIGxpYnJhcnkgdW5pdC4KUmV0dXJucyB0aGUgbG9jYXRp b24gb2YgdGhlIGNvcnJlc3BvbmRpbmcgYmVnaW4ga2V5d29yZCwgdW5sZXNzIHNlYXJjaApzdG9w cyBkdWUgdG8gYmVnaW5uaW5nIG9yIGVuZCBvZiBidWZmZXIuCk5vdGUgdGhhdCBpZiBwb2ludCBp cyBiZXR3ZWVuIHRoZSAibGlidW5pdCIga2V5d29yZCBhbmQgdGhlCmNvcnJlc3BvbmRpbmcgImJl Z2luIiBrZXl3b3JkLCB0aGVuIHRoYXQgbGlidW5pdCB3aWxsIG5vdCBiZQpyZWNvZ25pc2VkLCBh bmQgdGhlIHNlYXJjaCB3aWxsIGNvbnRpbnVlIGJhY2t3YXJkcy4gIElmIHBvaW50IGlzCmF0IHRo ZSAiYmVnaW4iIGtleXdvcmQsIHRoZW4gdGhlIGRlZnVuIHdpbGwgYmUgcmVjb2duaXNlZC4gIFRo ZQpyZXR1cm5lZCBwb2ludCBpcyBhdCB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSAibGlidW5p dCIga2V5d29yZC4fCihkZWZhbGlhcyAndmhkbC1iZWdpbm5pbmctb2YtbGlidW5pdCAjW25pbCAi YFwyMTJcMzA2dlwyMTBgVClcMzA3XDIxMVwyMTEYGRobHFxuXDIwNFwyMDEAXDMxMA1cMzA3XDMx MSNcMjAzXDIwMQBoXDMxMlVcMjA0LQBcMzEzZSFcMjA0LQBcMzE0IFwyMDQzAFwzMTUgXDIxMFwy MDIQAGAUXG5cMjA0ewBcMzE2XDMxNwtcMzIwI1wyMDN7AFwzMjFcMjI0XDIxMRBcMjAzewBoXDMx MlVcMjA0VgBcMzEzXGYhXDIxMRFcMjAzdQAJXDMyMj1cMjAzbwBgHhNcMzA3f1wyMTBgDhNiXDIx MCkLXmJcMjEwXDIwMjUAXDMwN3VcMjEwXDIwMjUACFwyMTESXDIwMzkAXGZiXDIxMFwyMDIQAFxu LVwyMDciIFtwbGFjZWhvbGRlciBsaXRlcmFsIGZvdW5kcCBsYXN0LWJhY2t3YXJkIGxhc3QtZm9y d2FyZCB2aGRsLWxpYnVuaXQtcmUgMSBuaWwgcmUtc2VhcmNoLWJhY2t3YXJkIG1vdmUgOTUgdmhk bC1pbi1saXRlcmFsIHZoZGwtbGlidW5pdC1wIGJhY2t3YXJkLWNoYXIgcmUtc2VhcmNoLWZvcndh cmQgIlxcYmlzXFxiW15fXSIgdCAwIGNvbW1lbnQgaGVyZV0gNiAoIyQgLiAxMzgwOTUpXSkKI0Ax OTkgTW92ZSBiYWNrd2FyZCB0byB0aGUgYmVnaW5uaW5nIG9mIGEgVkhETCBkZWZ1bi4KV2l0aCBh cmd1bWVudCwgZG8gaXQgdGhhdCBtYW55IHRpbWVzLgpSZXR1cm5zIHRoZSBsb2NhdGlvbiBvZiB0 aGUgY29ycmVzcG9uZGluZyBiZWdpbiBrZXl3b3JkLCB1bmxlc3Mgc2VhcmNoCnN0b3BzIGR1ZSB0 byBiZWdpbm5pbmcgb3IgZW5kIG9mIGJ1ZmZlci4fCihkZWZhbGlhcyAndmhkbC1iZWdpbm5pbmct b2YtZGVmdW4gI1soJm9wdGlvbmFsIGNvdW50KSAiCFwyMDYFAFwzMDZcMzA3YFwzMTAZGhtcMjEx GFwzMTFWXDIwM1wyNDMAXDMxMBFcbmJcMjEwXDIxMlwzMDZ2XDIxMGBUKVwzMTBcMjExHB0eFQlc MjA0XDIzMwBcMzEyDhZcMzEwXDMxMyNcMjAzXDIzMwBoXDMxNFVcMjA0PQBcMzE1ZSFcMjAzQwBc MzE2IFwyMTBcMjAyJABcMzE3IFwyMTEVXDIwMyQAYBIJXDIwNFwyMjUAXDMyMA0OFVwzMDcjXDIw M1wyMjUAaFwzMTRVXDIwNG4AXDMyMSAeF1wzMjJcMjE2XDMxNVxuIVwyMTEUKlwyMDNcMjE2AFxm XDMyMz1cMjAzXDIxMABgHhhcMzEwf1wyMTBgDhhiXDIxMCkOFV5iXDIxMFwyMDJMAFwzMTB1XDIx MFwyMDJMAFwzMTFcMjI0XDIxMRFcMjAzUABcbmJcMjEwXDIwMiQAKwhTXDIxMRBcMjAyDQBcMzI0 IFwyMTAJLFwyMDciIFtjb3VudCBmb3VuZHAgbGFzdC1mb3J3YXJkIGNhc2UtZm9sZC1zZWFyY2gg bGl0ZXJhbCBiZWdpbi1zdHJpbmcgMSB0IG5pbCAwIHJlLXNlYXJjaC1iYWNrd2FyZCBtb3ZlIDk1 IHZoZGwtaW4tbGl0ZXJhbCBiYWNrd2FyZC1jaGFyIHZoZGwtY29ycmVzcG9uZGluZy1kZWZ1biBz ZWFyY2gtZm9yd2FyZCBtYXRjaC1kYXRhICgoc2V0LW1hdGNoLWRhdGEgc2F2ZS1tYXRjaC1kYXRh LWludGVybmFsKSkgY29tbWVudCB2aGRsLWtlZXAtcmVnaW9uLWFjdGl2ZSBsYXN0LWJhY2t3YXJk IHZoZGwtZGVmdW4tcmUgc2F2ZS1tYXRjaC1kYXRhLWludGVybmFsIGhlcmVdIDUgKCMkIC4gMTM5 MTQwKSAicCJdKQojQDQ1NyBHbyB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBpbm5lcm1vc3QgVkhE TCBzdGF0ZW1lbnQuCldpdGggcHJlZml4IGFyZywgZ28gYmFjayBOIC0gMSBzdGF0ZW1lbnRzLiAg SWYgYWxyZWFkeSBhdCB0aGUKYmVnaW5uaW5nIG9mIGEgc3RhdGVtZW50IHRoZW4gZ28gdG8gdGhl IGJlZ2lubmluZyBvZiB0aGUgcHJlY2VkaW5nCm9uZS4gIElmIHdpdGhpbiBhIHN0cmluZyBvciBj b21tZW50LCBvciBuZXh0IHRvIGEgY29tbWVudCAob25seQp3aGl0ZXNwYWNlIGJldHdlZW4pLCBt b3ZlIGJ5IHNlbnRlbmNlcyBpbnN0ZWFkIG9mIHN0YXRlbWVudHMuCgpXaGVuIGNhbGxlZCBmcm9t IGEgcHJvZ3JhbSwgdGhpcyBmdW5jdGlvbiB0YWtlcyAyIG9wdGlvbmFsIGFyZ3M6IHRoZQpwcmVm aXggYXJnLCBhbmQgYSBidWZmZXIgcG9zaXRpb24gbGltaXQgd2hpY2ggaXMgdGhlIGZhcnRoZXN0 IGJhY2sgdG8Kc2VhcmNoLh8KKGRlZmFsaWFzICd2aGRsLWJlZ2lubmluZy1vZi1zdGF0ZW1lbnQg I1soJm9wdGlvbmFsIGNvdW50IGxpbSkgIghcMjA2BQBcMzA2XDMwNwlcMjA2CwBlYFwzMTAaGxkc GFwyMTIJYlwyMTBcMzExYAtcMzEwXDIxMSQSKXRcMjAzPgBcMzEyXG44XDIwNDYAXDMxM1xuOFwy MDQ2AFwzMTRcMzE1DVAhXDIwMz4AXDMxNghbIVwyMTBcMjAyTwAIXDMxN1ZcMjAzTwBcMzIwCSFc MjEwCFNcMjExEFwyMDI/AGAJXWJcMjEwLVwzMjEgXDIwNyIgW2NvdW50IGxpbSBzdGF0ZSBoZXJl IGNhc2UtZm9sZC1zZWFyY2ggY29tbWVudC1zdGFydC1za2lwIDEgdCBuaWwgcGFyc2UtcGFydGlh bC1zZXhwIDMgNCBsb29raW5nLWF0ICJbIAldKiIgZm9yd2FyZC1zZW50ZW5jZSAwIHZoZGwtYmVn aW5uaW5nLW9mLXN0YXRlbWVudC0xIHZoZGwta2VlcC1yZWdpb24tYWN0aXZlXSA2ICgjJCAuIDE0 MDEyMykgInAiXSkKKGJ5dGUtY29kZSAiXDMwNAhcMzA1CVISXDMwMgtCE1wzMDJcMjA3IiBbdmhk bC1iZWdpbi1md2QtcmUgdmhkbC1zdGF0ZW1lbnQtZndkLXJlIHZoZGwtZS1vLXMtcmUgY3VycmVu dC1sb2FkLWxpc3QgIjtcXHwiICJcXHwiXSA0KQojQDI5IFZlcnkgc2ltcGxlIGltcGxlbWVudGF0 aW9uLh8KKGRlZmFsaWFzICd2aGRsLWVuZC1vZi1zdGF0ZW1lbnQgI1tuaWwgIlwzMDEIIVwyMDci IFt2aGRsLWUtby1zLXJlIHJlLXNlYXJjaC1mb3J3YXJkXSAyICgjJCAuIDE0MTE2NikgbmlsXSkK KGJ5dGUtY29kZSAiXDMwNAhcMzA1CVISXDMwMgtCE1wzMDJcMjA3IiBbdmhkbC1iZWdpbi1id2Qt cmUgdmhkbC1zdGF0ZW1lbnQtYndkLXJlIHZoZGwtYi1vLXMtcmUgY3VycmVudC1sb2FkLWxpc3Qg IjtcXHwoXFx8KVxcfFxcYndoZW5cXGJbXl9dXFx8IiAiXFx8Il0gNCkKI0AxMDcgTW92ZSB0byB0 aGUgc3RhcnQgb2YgdGhlIGN1cnJlbnQgc3RhdGVtZW50LCBvciB0aGUgcHJldmlvdXMKc3RhdGVt ZW50IGlmIGFscmVhZHkgYXQgdGhlIGJlZ2lubmluZyBvZiBvbmUuHwooZGVmYWxpYXMgJ3ZoZGwt YmVnaW5uaW5nLW9mLXN0YXRlbWVudC0xICNbKCZvcHRpb25hbCBsaW0pICIIXDIwNgUAZWBgXDMw NhkaGxhcMzA2XDMwN1wzMTBcMjE3XDIwNCAAXDMxMVwzMTIhXDIxMFwzMDZ1XDIxMFwzMTMLIVwy MTBcMzE0EQk/XDIwNRsBbz9cMjA1GwFcMzE1XGYIXDMxNiNcMjA1GwFoXDMxN1VcMjA0PgBcMzIw CCFcMjAzRABcMzIxIFwyMTBcMjAyIABnXDMyMj1cMjAzVwBcMzA2dVwyMTBcMzEzCyFcMjEwXDMx NFwyMTERXDIwMiEAZ1wzMjM9XDIwM3gAXDMwNnVcMjEwYBJcMzI0IFwyMTBgCFdcMjAzIABcbmJc MjEwXDMxMwshXDIxMFwzMTRcMjExEVwyMDIhAGdcMzI1PVwyMDNcMjEzAFwzMDZ1XDIxMFwzMTML IVwyMTBcMzE0XDIxMRFcMjAyIQBcMzI2DSFcMjAzXDMxNQBoXDMxN1VcMjA0XDMxNQBcMzI3XDMw NiFcMjAzXDMxNQBcMzI2DhwhXDIwM1wyNzMAXDIxMmASXDMzMCBiXDIxMFwzMTMLIVwyMTBgC1dc MjAzXDI2NwBgEilcMjAyXDMwNABcMzEydlwyMTBcMzEzCyFcMjEwYBJcbmJcMjEwXDMxNFwyMTER XDIwMiEAXDMyNg4dIVwyMDNcMzQ2AGhcMzE3VVwyMDRcMzQ2AFwzMzFcMzA2IVwyMDNcMzQ2AFwz MTRcMjExEVwyMDIhAFwzMjYOHiFcMjAzFQFcMzMyCCFcMjAzFQFcMjEyYBJcMzI2Dh4hXDIxMFwz MzNcMjI1YlwyMTBcMzEzCyFcMjEwYAtXXDIwMwsBYBIpXG5iXDIxMFwzMTRcMjExEVwyMDIhAFwz MjEgXDIxMFwyMDIgACxcMjA3IiBbbGltIGRvbmVwIHBvcyBoZXJlIHZoZGwtYi1vLXMtcmUgdmhk bC1iZWdpbi1md2QtcmUgbmlsIChieXRlLWNvZGUgIlwzMDAgXDIxMFwzMDFcMjA3IiBbYmFja3dh cmQtc2V4cCB0XSAxKSAoKGVycm9yKSkgYmFja3dhcmQtdXAtbGlzdCAxIHZoZGwtZm9yd2FyZC1z eW50YWN0aWMtd3MgdCByZS1zZWFyY2gtYmFja3dhcmQgbW92ZSA5NSB2aGRsLWluLWxpdGVyYWwg YmFja3dhcmQtY2hhciA0MCA0MSBiYWNrd2FyZC1zZXhwIDU5IGxvb2tpbmctYXQgdmhkbC1iZWdp bi1wIHZoZGwtZW5kLW9mLWxlYWRlciB2aGRsLXN0YXRlbWVudC1wIHZoZGwtY2FzZS1hbHRlcm5h dGl2ZS1wIDAgdmhkbC1sZWFkZXItcmUgdmhkbC1zdGF0ZW1lbnQtZndkLXJlIHZoZGwtY2FzZS1h bHRlcm5hdGl2ZS1yZV0gNSAoIyQgLiAxNDE0NjUpXSkKI0AxMjQgSWYgdGhlcmUgaXMgYW4gZW5j bG9zaW5nIGxpYnJhcnkgdW5pdCBhdCBib2QsIHdpdGggaXQncyAiYmVnaW4iCmtleXdvcmQgYXQg cGxhY2Vob2xkZXIsIHRoZW4gcmV0dXJuIHRoZSBsaWJyYXJ5IHVuaXQgdHlwZS4fCihkZWZhbGlh cyAndmhkbC1nZXQtbGlicmFyeS11bml0ICNbKGJvZCBwbGFjZWhvbGRlcikgImAYXDMwM3lcMjEw YAhiXDIxMCkYXDIxMgliXDIxMFwzMDRcMzA1XDMwNlwyMTdcMjEwCGBYKVwyMDVbAFwyMTJcbmJc MjEwXDMwN1wzMTAhXDIwMykAXDMxMVwyMDJaAFwzMDdcMzEyIVwyMDMzAFwzMTNcMjAyWgBcMzA3 XDMxNCFcMjAzPQBcMzE1XDIwMloAXDMwN1wzMTYhXDIwNVoAXDIxMlxuYlwyMTBcMzE3IFwyMTBc MzIwCCFcMjEwXDMwN1wzMjEhXDIwM1gAXDMyMlwyMDJZAFwzMjMpKSlcMjA3IiBbaGVyZSBwbGFj ZWhvbGRlciBib2QgMCBuaWwgKHZoZGwtZm9yd2FyZC1zZXhwIDEgYm9kKSAoKGVycm9yKSkgbG9v a2luZy1hdCAiZSIgZW50aXR5ICJhIiBhcmNoaXRlY3R1cmUgImMiIGNvbmZpZ3VyYXRpb24gInAi IGZvcndhcmQtc2V4cCB2aGRsLWZvcndhcmQtc3ludGFjdGljLXdzICJib2R5XFxiW15fXSIgcGFj a2FnZS1ib2R5IHBhY2thZ2VdIDMgKCMkIC4gMTQyNzEwKV0pCiNAMTMwIEZpbmRzIGFuZCByZWNv cmRzIGFsbCB0aGUgY2xvc2VzdCBvcGVucy4KbGltIGlzIHRoZSBmdXJ0aGVzdCBiYWNrIHdlIG5l ZWQgdG8gc2VhcmNoIChpdCBzaG91bGQgYmUgdGhlCnByZXZpb3VzIGxpYnVuaXQga2V5d29yZCku HwooZGVmYWxpYXMgJ3ZoZGwtZ2V0LWJsb2NrLXN0YXRlICNbKCZvcHRpb25hbCBsaW0pICJgCFwy MDYGAGVcMzA2XDIxMVwyMTFcMjExXDIxMVwyMTFcMjExXDIxMVwyMTEZGhscHR4VHhYeFx4YGB4Z XDIxMlwyMTQIYH1cMjEwXDMwNlwzMDdcMzEwXDIxNylcMjExEVwyMDMxAAkQYAhWXDIwM1wyMzQA XGZcMjA0XDIzNABcMzExCCFcMjExFhhcMzEyPVwyMDN1AGAWF1wzMTMIIRYWXDMwNlwzMTRcMzE1 XDIxN1wyMTEWFVwyMDNqAA4VDhlYXDIwM2oADVwyMDQxAA4XFVwyMDIxAA4XFA4WElwzMTYTXDIw MjEADhhcMzE3PVwyMDMxAFwzMjAgXDIxMGAWFVwzMDYWFlwzMDZcMzIxXDMyMlwyMTdcMjA2XDIy MABcMzIzIFwyMTBgFhcNXDIwNDEADhcVXDIwMjEAKQlcMjAzXDI2MwBcZlwyMDNcMjUzAFxmCVdc MjAzXDI2MwAJFFwzMDYVXDMwNhNcMzA2ElwzMjRcZg0LXG4kLgtcMjA3IiBbbGltIGNvbnRhaW5p bmctcGFyZW4gY29udGFpbmluZy1taWQgY29udGFpbmluZy1iZWdpbiBjb250YWluaW5nLXNleHAg cHJlY2VkaW5nLXNleHAgbmlsIChieXRlLWNvZGUgIlwzMDBgXDMwMVwzMDIjXDIwNyIgW3NjYW4t bGlzdHMgLTEgMV0gNCkgKChlcnJvcikpIHZoZGwtYmFja3dhcmQtdG8tYmxvY2sgYmVnaW4gdmhk bC1jb3JyZXNwb25kaW5nLW1pZCAoYnl0ZS1jb2RlICJcMjEyXDMwMVwzMDIIXCJcMjEwYClcMjA3 IiBbbGltIHZoZGwtZm9yd2FyZC1zZXhwIDFdIDMpICgoZXJyb3IpKSB0IGVuZCBmb3J3YXJkLXNl eHAgKGJ5dGUtY29kZSAiXDMwMVwzMDIIXCJcMjEwYFwyMDciIFtsaW0gdmhkbC1iYWNrd2FyZC1z ZXhwIDFdIDMpICgoZXJyb3IpKSBiYWNrd2FyZC1zZXhwIHZlY3RvciBzZXhwLWVuZCBzZXhwLW1p ZCBzZXhwLXN0YXJ0IGtleXdvcmQgaGVyZV0gMTIgKCMkIC4gMTQzMzQxKV0pCihieXRlLWNvZGUg IghcMzA0CVESXDMwMgtCE1wzMDJcMjA3IiBbdmhkbC1jYXNlLWFsdGVybmF0aXZlLXJlIHZoZGwt Y2FzZS1oZWFkZXIta2V5IHZoZGwtcy1jLWEtcmUgY3VycmVudC1sb2FkLWxpc3QgIlxcfCJdIDMp CiNAMTQ0IFNraXAgZm9yd2FyZCBvdmVyIGNhc2Uvd2hlbiBib2RpZXMsIHdpdGggb3B0aW9uYWwg bWF4aW1hbApsaW1pdC4gSWYgbm8gbmV4dCBjYXNlIGFsdGVybmF0aXZlIGlzIGZvdW5kLCBuaWwg aXMgcmV0dXJuZWQgYW5kIHBvaW50CmlzIG5vdCBtb3ZlZC4fCihkZWZhbGlhcyAndmhkbC1za2lw LWNhc2UtYWx0ZXJuYXRpdmUgI1soJm9wdGlvbmFsIGxpbSkgIghcMjA2BQBkYFwzMDZcMjExGRob GGAIV1wyMDNSAFxuXDIwNFIAXDMwN1xmCFwzMTAjXDIwM1xmAFwzMTEgHVwzMTJcMjE2XDMxMyAq XDIwNFxmAFwzMTRcMjI0C1VcMjA0XGYAXDMxNFwyMjRiXDIxMFwzMTVcMzE2IVwyMDNLAFwzMDdc MzE3CFwzMjAjXDIwM0sAXDMyMSBcMjEwXDMyMiBcMjEwXDIwMlxmAFwzMjASXDMyMBFcMjAyXGYA CVwyMDRZAAtiXDIxMAksXDIwNyIgW2xpbSBmb3VuZHAgZG9uZXAgaGVyZSB2aGRsLXMtYy1hLXJl IHNhdmUtbWF0Y2gtZGF0YS1pbnRlcm5hbCBuaWwgcmUtc2VhcmNoLWZvcndhcmQgbW92ZSBtYXRj aC1kYXRhICgoc2V0LW1hdGNoLWRhdGEgc2F2ZS1tYXRjaC1kYXRhLWludGVybmFsKSkgdmhkbC1p bi1saXRlcmFsIDAgbG9va2luZy1hdCAiY2FzZSIgIlxcYmlzW15fXSIgdCBiYWNrd2FyZC1zZXhw IHZoZGwtZm9yd2FyZC1zZXhwXSA0ICgjJCAuIDE0NDUwMildKQojQDEyMSBTa2lwIGJhY2t3YXJk IG92ZXIgYSBsYWJlbCwgd2l0aCBvcHRpb25hbCBtYXhpbWFsCmxpbWl0LiBJZiBsYWJlbCBpcyBu b3QgZm91bmQsIG5pbCBpcyByZXR1cm5lZCBhbmQgcG9pbnQKaXMgbm90IG1vdmVkLh8KKGRlZmFs aWFzICd2aGRsLWJhY2t3YXJkLXNraXAtbGFiZWwgI1soJm9wdGlvbmFsIGxpbSkgIghcMjA2BQBl XDMwMxkYXDIxMlwzMDQIIVwyMTBoXDMwNT1cMjA1GwBcMzA2IFwyMTBgEVwzMDdcbiEpXDIwNSEA CWIqXDIwNyIgW2xpbSBwbGFjZWhvbGRlciB2aGRsLWxhYmVsLWtleSBuaWwgdmhkbC1iYWNrd2Fy ZC1zeW50YWN0aWMtd3MgNTggYmFja3dhcmQtc2V4cCBsb29raW5nLWF0XSAyICgjJCAuIDE0NTE2 NildKQojQDEyMSBTa2lwIGZvcndhcmQgb3ZlciBhIGxhYmVsLCB3aXRoIG9wdGlvbmFsIG1heGlt YWwKbGltaXQuICBJZiBsYWJlbCBpcyBub3QgZm91bmQsIG5pbCBpcyByZXR1cm5lZCBhbmQgcG9p bnQKaXMgbm90IG1vdmVkLh8KKGRlZmFsaWFzICd2aGRsLWZvcndhcmQtc2tpcC1sYWJlbCAjWygm b3B0aW9uYWwgbGltKSAiCFwyMDYFAGQYXDMwMgkhXDIwNRMAXDMwM1wyMjViXDIxMFwzMDQIISlc MjA3IiBbbGltIHZoZGwtbGFiZWwta2V5IGxvb2tpbmctYXQgMCB2aGRsLWZvcndhcmQtc3ludGFj dGljLXdzXSAyICgjJCAuIDE0NTUzMildKQojQDY3IEd1ZXNzIHRoZSBzeW50YWN0aWMgZGVzY3Jp cHRpb24gb2YgdGhlIGN1cnJlbnQgbGluZSBvZiBWSERMIGNvZGUuHwooZGVmYWxpYXMgJ3ZoZGwt Z2V0LXN5bnRhY3RpYy1jb250ZXh0ICNbbmlsICJcMjEyXDIxNFwzMDZ5XDIxMGAYXDMwNxlcMzEw GlwzMTAbXDMxMBxcMzEwHVwzMTAeMlwzMTAeM1wzMTAeNFwzMTAeNVwzMTAeNlwzMTAeN1wzMTAe OFwzMTAeOVwzMTAeOlwzMTAeO1wzMTAWPFwyMTJcMzExIBY5YBY6KQ45XDIwM1YAXDMxMg46Djlc IlwyMTEWO1wyMDNWAA47DjpCDjxCFjxcMzEzDjohXDIxMRJcMjAzcQBcblwzMDZIFFxuXDMxNEgV XG5cMzE1SBYyXG5cMzE2SBYzXGZcMjAzXDIyMwBcMjEyXGZiXDIxMFwzMTcOPSFcMjAzXDIwNABc MzIwIBY0YB4+XDMwNnlcMjEwYA4+YlwyMTAqXDIwMlwyMjQAZRY6CGJcMjEwXDMyMVwzMTB3XDIx MFwzMjIOOiETZxY2Cz9cMjA1XDI2MwBcMzE3Dj8hXDIwNVwyNjMAXDMyMyAWNws/XDIwNVwzMDMA XDMxNw5AIVwyMDVcMzAzAFwzMjQgFjhcMzI1DjohXDIxMGgWNQhiXDIxMFwzMjFcMzEwd1wyMTAL XDMyNj5cMjAzXDM2MAALYB4+XDMyN3lcMjEwYA4+YlwyMTApQg48QhY8XDIwMlwzNzQDXGZcMjA0 ewFcMjEyDVwyMDQBAVwzMzAOOiFcMjEwXDIwMhoBDWJcMjEwYGAePlwzMzEgXDIxMGAOPmJcMjEw KVVcMjA0GgFcMzMwDjohXDIxMG9cMjAzXCIBXDMzMgghXDIxMGAWOSkON1wyMDM3AVwzMzMOOUIO PEIWPFwyMDJcMzc0Aw44XDIwM0gBXDMzNA45Qg48QhY8XDIwMlwzNzQDXDMyNQ46IVwyMTBvXDIw NFcBaFwzMzVVXDIwM2MBXDMzNg45Qg48QhY8XDIwMlwzNzQDXDMzMA46IVwyMTBvXDIwM3ABXDMz MgghXDIxMFwzMzdgQg48QhY8XDIwMlwzNzQDDjJcMjA0GwJcMzI1XGYhXDIxMA42XDM0MD1cMjAz XDI0NAFcZmJcMjEwXDM0MWAePlwzMzEgXDIxMGAOPmJcMjEwKUIOPEIWPFwyMDJcMzc0Aw41XDM0 Mj1cMjAzXDMwNAFcZmJcMjEwXDM0M2AePlwzMzEgXDIxMGAOPmJcMjEwKUIOPEIWPFwyMDJcMzc0 A1wyMTJcZlRiXDIxMFwzMjFcMzEwd1wyMTBcMzE3XDM0NCEpXDIwNFwzNzUBXDIxMlwzMzBcZiFc MjEwXDM0NVwzMTB4XDIxMGBcZlgpXDIwM1wzNzUBXGZiXDIxMFwzNDZgHj5cMzMxIFwyMTBgDj5i XDIxMClCDjxCFjxcMjAyXDM3NANcMzMwXGYhXDIxMFwzMzIIIVwyMTBcMzQ3YB4+XDMzMSBcMjEw YA4+YlwyMTApQg48QhY8XDIwMlwzNzQDDjdcMjAzUgJcMzE3DjMhXDIwM1ICXGZiXDIxMFwzMTcO QSFcMjAzOAJcMzUwIFwyMTBcMzMwXDMxMCFcMjEwXDM1MWAePlwzMzEgXDIxMGAOPmJcMjEwKSFc MjEwXDMzM2BCDjxCFjxcMjAyXDM3NAMOOFwyMDNcMjAyAlxmYlwyMTBcMzE3DkEhXDIwM2gCXDM1 MCBcMjEwXDMzMFwzMTAhXDIxMFwzNTFgHj5cMzMxIFwyMTBgDj5iXDIxMCkhXDIxMFwzMzRgQg48 QhY8XDIwMlwzNzQDDjVcMzM1VVwyMDQdAw43XDIwM1wyMzUCXDMxNw5BIVwyMDQdA1wyMTJcMzUx XGYhKVwyMDQdA1wzMTcOQiFcMjAzXDI1MQJcMzUyIFwyMDQdAwhcMjEyXDMzMFxmIVwyMTBcMzMy CCFcMjEwYFwyMTEWOSlWXDIwMx0DDjlcZlVcMjA0HQNcMjEyDjliXDIxMFwzMTcOQyE/XDIwNlwz MjQCXDMwNlwyMjUIVilcMjAzHQMOOR5ECFwyMTIOOWJcMjEwXDM1MwghXDIxMGBcMjExFkQpVlwy MDMDA1wyMTIORGJcMjEwDkRcMzMxIFwyMTBgKT1cMjAzAwMORBY5KVwzMzcOOUIOPEIWPA43XDIw M1wzNzQDXDMzM1wzMTBCDjxCFjxcMjAyXDM3NANcMzE3DkMhXDIwM1EDXDM1NFxmIVwyMDNRA1xm YlwyMTBcMzE3DkEhXDIwMzsDXDM1MCBcMjEwXDMzMFwzMTAhXDIxMFwzNTVgHj5cMzMxIFwyMTBg Dj5iXDIxMClCDjxCFjxcMjAyXDM3NAMONFwyMDNdAw40YlwyMTBcMjAyYwNcZmJcMjEwXDM1MCBc MjEwXDMzMgghXDIxMGAWOVwzMTAeRVwzMTcOQyFcMjAzXDIyMANgFkVcMzU2CCFcMjA0dwNcMzE3 DkMhXDIxMFwzMDZcMjI1YlwyMTBcMzMyCCFcMjEwYBY5XDIwMm0DDkVcMjAzXDI0NwNgCFVcMjAz XDI0NwNcMzU3DkVCDjxCFjxcMjAyXDM3MwNgCFdcMjAzXDMwNgNcMzM2DjlCDjxCFjwON1wyMDNc MzczA1wzMzNcMzEwQg48QhY8XDIwMlwzNzMDXGZiXDIxMFwzMTcOQSFcMjAzXDMyNwNcMzUwIFwy MTBcMzMwXDMxMCFcMjEwXDM1MWAePlwzMzEgXDIxMGAOPmJcMjEwKSFcMjEwXDM2MGBCDjxCFjwO N1wyMDNcMzczA1wzMzNcMzEwQg48QhY8KQhiXDIxMFwzMjFcMzEwd1wyMTBcMzE3XDM0NCFcMjAz EQRcMzYxXDMxMEIOPEIWPA48LhJcMjA3IiBbaW5kZW50LXBvaW50IGNhc2UtZm9sZC1zZWFyY2gg dmVjIGxpdGVyYWwgY29udGFpbmluZy1zZXhwIHByZWNlZGluZy1zZXhwIDAgdCBuaWwgdmhkbC1i ZWdpbm5pbmctb2YtbGlidW5pdCB2aGRsLWdldC1saWJyYXJ5LXVuaXQgdmhkbC1nZXQtYmxvY2st c3RhdGUgMSAyIDMgbG9va2luZy1hdCB2aGRsLWVuZC1vZi1sZWFkZXIgIiAJIiB2aGRsLWluLWxp dGVyYWwgdmhkbC1iZWdpbi1wIHZoZGwtZW5kLXAgdmhkbC1iYWNrd2FyZC1zeW50YWN0aWMtd3Mg KHN0cmluZyBjb21tZW50KSAtMSB2aGRsLWJlZ2lubmluZy1vZi1zdGF0ZW1lbnQtMSBiYWNrLXRv LWluZGVudGF0aW9uIHZoZGwtZm9yd2FyZC1zeW50YWN0aWMtd3MgYmxvY2stb3BlbiBibG9jay1j bG9zZSA1OSBzdGF0ZW1lbnQgc3RhdGVtZW50LWNvbnQgNDEgYXJnbGlzdC1jbG9zZSA0MCBhcmds aXN0LWludHJvICItLSIgIiAJKCIgYXJnbGlzdC1jb250LW5vbmVtcHR5IGFyZ2xpc3QtY29udCBm b3J3YXJkLXNleHAgdmhkbC1iYWNrd2FyZC1za2lwLWxhYmVsIHZoZGwtc3RhdGVtZW50LXAgdmhk bC1mb3J3YXJkLXNraXAtbGFiZWwgdmhkbC1jYXNlLWFsdGVybmF0aXZlLXAgY2FzZS1hbHRlcm5h dGl2ZSB2aGRsLXNraXAtY2FzZS1hbHRlcm5hdGl2ZSBzdGF0ZW1lbnQtY2FzZS1pbnRybyBzdGF0 ZW1lbnQtYmxvY2staW50cm8gY29tbWVudCBjb250YWluaW5nLWJlZ2luIGNvbnRhaW5pbmctbWlk IGNvbnRhaW5pbmctbGVhZGVyIGNoYXItYmVmb3JlLWlwIGNoYXItYWZ0ZXItaXAgYmVnaW4tYWZ0 ZXItaXAgZW5kLWFmdGVyLWlwIHBsYWNlaG9sZGVyIGxpbSBsaWJyYXJ5LXVuaXQgdmhkbC1zeW50 YWN0aWMtY29udGV4dCB2aGRsLWxlYWRlci1yZSBoZXJlIHZoZGwtYmVnaW4tZndkLXJlIHZoZGwt ZW5kLWZ3ZC1yZSB2aGRsLXRyYWlsZXItcmUgdmhkbC1zdGF0ZW1lbnQtZndkLXJlIHZoZGwtY2Fz ZS1hbHRlcm5hdGl2ZS1yZSBuZXcgaW5jYXNlLXBdIDMgKCMkIC4gMTQ1ODM3KV0pCiNAMTE4IExp bmV1cCB0aGUgY3VycmVudCBhcmdsaXN0IGxpbmUgd2l0aCB0aGUgYXJnbGlzdCBhcHBlYXJpbmcg anVzdAphZnRlciB0aGUgY29udGFpbmluZyBwYXJlbiB3aGljaCBzdGFydHMgdGhlIGFyZ2xpc3Qu HwooZGVmYWxpYXMgJ3ZoZGwtbGluZXVwLWFyZ2xpc3QgI1sobGFuZ2VsZW0pICJcMjEyXDIxMghA XDMwNT5cMjAzIABcMzA2eVwyMTBcMzA3XDMxMCFcMjEwXDMxMWAZXDMxMn9cMjEwYAliXDIxMCl3 XDIxMFwyMDIkAAhBYlwyMTBgKRpcMjEyCEFiXDIxMGkpG1wyMTJcMzA2eVwyMTBcMzEzXDMxNCEp XDIwM00AXDMwNlwyMjViXDIxMFwzMTUgXDIxMFwzMTJ1XDIxMFwzMTYgXDIxMGkLWlwyMDJ4AFxu YlwyMTBsXDIwNHUAYBlcMzEyf1wyMTBgCWJcMjEwKVwzMTJ1XDIxMFwzMTFcMzEyd1wyMTBgGRxc MzE2IFwyMTBgXGZXXDIwM3QACWJcMjEwKmkLWitcMjA3IiBbbGFuZ2VsZW0gaGVyZSBjb250YWlu aW5nLXNleHAgY3MtY3VyY29sIGVvbCAoYXJnbGlzdC1pbnRybyBhcmdsaXN0LWNvbnQtbm9uZW1w dHkpIDAgYmFja3dhcmQtdXAtbGlzdCAxICIgCSIgbmlsIGxvb2tpbmctYXQgIlsgCV0qKSIgYmFj a3dhcmQtc2V4cCB2aGRsLWZvcndhcmQtc3ludGFjdGljLXdzXSAzICgjJCAuIDE0OTA1MyldKQoj QDYwIExpbmV1cCBhbiBhcmdsaXN0LWludHJvIGxpbmUgdG8ganVzdCBhZnRlciB0aGUgb3BlbiBw YXJlbi4fCihkZWZhbGlhcyAndmhkbC1saW5ldXAtYXJnbGlzdC1pbnRybyAjWyhsYW5nZWxlbSkg IlwyMTJcMjEyCEFiXDIxMGkpXDIxMlwzMDR5XDIxMFwzMDVcMzA2IVwyMTBcMzA3YBlcMzEwf1wy MTBgCWJcMjEwKXdcMjEwaSkaG1xuC1pcMzExWitcMjA3IiBbbGFuZ2VsZW0gaGVyZSBjZS1jdXJj b2wgY3MtY3VyY29sIDAgYmFja3dhcmQtdXAtbGlzdCAxICIgCSIgbmlsIC0xXSA0ICgjJCAuIDE0 OTY4NildKQojQDEzMyBTdXBwb3J0IG9sZCBiZWhhdmlvciBmb3IgY29tbWVudCBpbmRlbnRhdGlv bi4gIFdlIGxvb2sgYXQKdmhkbC1jb21tZW50LW9ubHktbGluZS1vZmZzZXQgdG8gZGVjaWRlIGhv dyB0byBpbmRlbnQgY29tbWVudApvbmx5LWxpbmVzLh8KKGRlZmFsaWFzICd2aGRsLWxpbmV1cC1j b21tZW50ICNbKGxhbmdlbGVtKSAiXDIxMlwzMDIgXDIxMGkIWVwyMDMPAFwzMDMgXDIwMicAblwy MDQcAAlcMjQyXDIwNicACVwyMDInAAlcMjQzXDIwNicACVwyNDJcMjA2JwBcMzA0KVwyMDciIFtj b21tZW50LWNvbHVtbiB2aGRsLWNvbW1lbnQtb25seS1saW5lLW9mZnNldCBiYWNrLXRvLWluZGVu dGF0aW9uIHZoZGwtY29tbWVudC1pbmRlbnQgLTEwMDBdIDIgKCMkIC4gMTQ5OTgxKV0pCiNANTUg TGluZSB1cCBzdGF0ZW1lbnQtY29udCBhZnRlciB0aGUgYXNzaWdubWVudCBvcGVyYXRvci4fCihk ZWZhbGlhcyAndmhkbC1saW5ldXAtc3RhdGVtZW50LWNvbnQgI1sobGFuZ2VsZW0pICJcMjEyCEEZ XDIxMmAaXDMwNiBcMjEwYFxuYlwyMTApYlwyMTBcMzA3XDMxMGAaXDMxMX9cMjEwYFxuYlwyMTAp XDMxMiNcMjA1LgBgYBpcMzA2IFwyMTBgXG5iXDIxMClaKRsJYlwyMTBpHFwzMTEdDVwyMDRcMjEy AGBgGlwzMTF/XDIxMGBcbmJcMjEwKVdcMjAzXDIxMgBcMzA3XDMxM2AaXDMxMX9cMjEwYFxuYlwy MTApXDMxNCNcMjEwXDMxNQhBIVwyMDNmAFwzMTF1XDIxMFwyMDI3AGhcMzE2VVwyMDNcMjAxAGAa XDMxMX9cMjEwYFxuYlwyMTApXDMxN2BcMzIwXDIxMSNeYlwyMTBcMjAyNwBcMzIxXDMyMiE/XDIx MRVcMjAzOwANXDIwNFwyMjMADhVcMjAyXDI0NQALXDIwNFwyNDAAXDMxMXVcMjEwXDMyM1wzMTF3 XDIxMFwzMjQTaQtaXGZaLVwyMDciIFtsYW5nZWxlbSByZWxwb3MgaGVyZSBhc3NpZ25wIGN1cmNv bCBmb3VuZHAgYmFjay10by1pbmRlbnRhdGlvbiByZS1zZWFyY2gtZm9yd2FyZCAiXFwoPFxcfDpc XCk9IiBuaWwgdCAiXFwoPFxcfDpcXCk9XFx8KCIgbW92ZSB2aGRsLWluLWxpdGVyYWwgNDAgc2Nh bi1saXN0cyAxIGxvb2tpbmctYXQgIlxccy0qJCIgIiAJIiAwIHZoZGwtYmFzaWMtb2Zmc2V0XSA2 ICgjJCAuIDE1MDM2NildKQojQDYwIENoZWNrIGlmIHBvaW50IGlzIHRvIHJpZ2h0IG9mIGJlZ2lu bmluZyBjb21tZW50IGRlbGltaXRlci4fCihkZWZhbGlhcyAndmhkbC1pbi1jb21tZW50LXAgI1tu aWwgImAYXDIxMlwzMDF5XDIxMFwzMDJcMzAzCFwzMDQjKlwyMDciIFtwb3NpdGlvbiAwIHJlLXNl YXJjaC1mb3J3YXJkICJeXFwoW15cIl0qXCJbXlwiXSpcIlxcKSpbXlwiXSotLSIgdF0gNCAoIyQg LiAxNTEwNzIpXSkKKHB1dCAndmhkbC1pbi1jb21tZW50LXAgJ2J5dGUtb3B0aW1pemVyICdieXRl LWNvbXBpbGUtaW5saW5lLWV4cGFuZCkKI0AzMiBDaGVjayBpZiBwb2ludCBpcyBpbiBhIHN0cmlu Zy4fCihkZWZhbGlhcyAndmhkbC1pbi1zdHJpbmctcCAjW25pbCAiYBhcMjEyXDMwMXlcMjEwCFwz MDJcMzAzCFwzMDQjKj1cMjA3IiBbcG9zaXRpb24gMCByZS1zZWFyY2gtZm9yd2FyZCAiXlxcKFte XCJdKlwiW15cIl0qXCJcXCkqW15cIl0qXCJbXlwiXSoiIHRdIDUgKCMkIC4gMTUxMzY0KV0pCihw dXQgJ3ZoZGwtaW4tc3RyaW5nLXAgJ2J5dGUtb3B0aW1pemVyICdieXRlLWNvbXBpbGUtaW5saW5l LWV4cGFuZCkKI0A0NSBDaGVjayBpZiBwb2ludCBpcyBpbiBhIGNvbW1lbnQgb3IgYSBzdHJpbmcu HwooZGVmYWxpYXMgJ3ZoZGwtaW4tY29tbWVudC1vci1zdHJpbmctcCAjW25pbCAiYBhcMjEyXDMw MXlcMjEwXDMwMlwzMDMIXDMwNCMqXDIwNR0AYBhcMjEyXDMwMXlcMjEwCFwzMDJcMzA1CFwzMDQj Kj1cMjA3IiBbcG9zaXRpb24gMCByZS1zZWFyY2gtZm9yd2FyZCAiXlxcKFteXCJdKlwiW15cIl0q XCJcXCkqW15cIl0qLS0iIHQgIl5cXChbXlwiXSpcIlteXCJdKlwiXFwpKlteXCJdKlwiW15cIl0q Il0gNSAoIyQgLiAxNTE2MzQpXSkKKHB1dCAndmhkbC1pbi1jb21tZW50LW9yLXN0cmluZy1wICdi eXRlLW9wdGltaXplciAnYnl0ZS1jb21waWxlLWlubGluZS1leHBhbmQpCiNAMjI0IElmIHByZWNl ZWRpbmcgY2hhcmFjdGVyIGlzIHBhcnQgb2YgYSB3b3JkIG9yIGEgcGFyZW4gdGhlbiBoaXBwaWUt ZXhwYW5kLAplbHNlIGlmIHJpZ2h0IG9mIG5vbiB3aGl0ZXNwYWNlIG9uIGxpbmUgdGhlbiB0YWIt dG8tdGFiLXN0b3AsCmVsc2UgaWYgbGFzdCBjb21tYW5kIHdhcyBhIHRhYiBvciByZXR1cm4gdGhl biBkZWRlbnQgb25lIHN0ZXAsCmVsc2UgaW5kZW50IGBjb3JyZWN0bHknLh8KKGRlZmFsaWFzICd2 aGRsLWVsZWN0cmljLXRhYiAjWygmb3B0aW9uYWwgcHJlZml4LWFyZykgIlwzMDYYXDMwN1wzMTBc MzExCSNcMjEwaHpcMzEyVVwyMDMcAFxuP1wzMDYbHFwzMTMNIVwyMTAqXDIwMmMAaFwzMTRVXDIw NCgAaFwzMTVVXDIwMzUAXG4/XDMwNhscXDMxNg0hXDIxMCpcMjAyYwBpXDMxNyBWXDIwM0IAXDMy MCBcMjEwXDIwMmMADhdcMzIxPVwyMDRQAA4XXDMyMj1cMjAzYABcMzE3IFwzMjNVXDIwNGAAXDMy NA4YXDMwNlwiXDIxMFwyMDJjAFwzMjUgXDIxMFwzMjFcMjExFhkQDhpcMjA0cwBcMzA3XDMxMFwz MjYJI1wyMTAIKVwyMDciIFtyZXN1bHQgdmhkbC1tb2RlLXN5bnRheC10YWJsZSB2aGRsLXdvcmQt Y29tcGxldGlvbi1jYXNlLXNlbnNpdGl2ZSBjYXNlLXJlcGxhY2UgY2FzZS1mb2xkLXNlYXJjaCBw cmVmaXgtYXJnIG5pbCBtb2RpZnktc3ludGF4LWVudHJ5IDk1ICJ3IiAxMTkgdmhkbC1leHBhbmQt YWJicmV2IDQwIDQxIHZoZGwtZXhwYW5kLXBhcmVuIGN1cnJlbnQtaW5kZW50YXRpb24gdGFiLXRv LXRhYi1zdG9wIHZoZGwtZWxlY3RyaWMtdGFiIHZoZGwtZWxlY3RyaWMtcmV0dXJuIDAgYmFja3dh cmQtZGVsZXRlLWNoYXItdW50YWJpZnkgdmhkbC1pbmRlbnQtbGluZSAiXyIgbGFzdC1jb21tYW5k IHZoZGwtYmFzaWMtb2Zmc2V0IHRoaXMtY29tbWFuZCB2aGRsLXVuZGVyc2NvcmUtaXMtcGFydC1v Zi13b3JkXSA0ICgjJCAuIDE1MjAxMSkgIipQIl0pCiNAOTcgbmV3bGluZS1hbmQtaW5kZW50IG9y IGluZGVudC1uZXctY29tbWVudC1saW5lIGlmIGluIGNvbW1lbnQgYW5kIHByZWNlZGluZwpjaGFy YWN0ZXIgaXMgYSBzcGFjZS4fCihkZWZhbGlhcyAndmhkbC1lbGVjdHJpYy1yZXR1cm4gI1tuaWwg ImhcMzAxVVwyMDMYAGAYXDIxMlwzMDJ5XDIxMFwzMDNcMzA0CFwzMDUjKlwyMDMYAFwzMDYgXDIw N1wzMDcgXDIwNyIgW3Bvc2l0aW9uIDMyIDAgcmUtc2VhcmNoLWZvcndhcmQgIl5cXChbXlwiXSpc IlteXCJdKlwiXFwpKlteXCJdKi0tIiB0IGluZGVudC1uZXctY29tbWVudC1saW5lIG5ld2xpbmUt YW5kLWluZGVudF0gNCAoIyQgLiAxNTI5NjcpIG5pbF0pCiNANjYgQXJyYXkgdmFyaWFibGUgZm9y IHByb2dyZXNzIGluZm9ybWF0aW9uOiAwIGJlZ2luLCAxIGVuZCwgMiB0aW1lLh8KKGRlZnZhciB2 aGRsLXByb2dyZXNzLWluZm8gbmlsICgjJCAuIDE1MzMxMikpCiNAODIgSW5kZW50IHRoZSBjdXJy ZW50IGxpbmUgYXMgVkhETCBjb2RlLiAgUmV0dXJucyB0aGUgYW1vdW50IG9mCmluZGVudGF0aW9u IGNoYW5nZS4fCihkZWZhbGlhcyAndmhkbC1pbmRlbnQtbGluZSAjW25pbCAiXDMwNiAYZGBaGQhA QFwzMDc9XDIwMx8AXDMxMAhAIVxuWVwyMDMfAFwzMTAIQCFcMjAyJgBcMzExXDMxMlwzMTNcMzEw CFwiXCJcMjExG1wzMTQgWhwNXDIwMzYAXDMxNVwzMTYICyNcMjEwXGZcMzE3VVwyMDRcXABgHhpc MzE3eVwyMTBgDhpiXDIxMClgHhpcMzIwIFwyMTBgDhpiXDIxMCl8XDIxMFwzMTd5XDIxMAtqXDIx MGBgHhpcMzIwIFwyMTBgDhpiXDIxMClXXDIwM3MAXDMyMCBcMjEwXDIwMlwyMDAAZAlaYFZcMjAz XDIwMABkCVpiXDIxMFwzMjFcMzIyIVwyMTAOG1wyMDNcMzE1AA4bXDMyMw4bXDMyM0hcMzI0XGZW XDIwM1wyMzIAXDMxN1wyMDJcMjMzAFxmXFxJXDIxMA4cXDMyNSBBQA4bXDMyNkhaV1wyMDNcMzE1 AFwzMTVcMzI3YA4bXDMxN0haXDMzMF8OG1wzMjNIDhtcMzE3SFpcMjQ1XDMzMSNcMjEwDhtcMzI2 XDMyNSBBQElcMjEwXGYsXDIwNyIgW3N5bnRheCBwb3MgY29tbWVudC1jb2x1bW4gaW5kZW50IHNo aWZ0LWFtdCB2aGRsLWVjaG8tc3ludGFjdGljLWluZm9ybWF0aW9uLXAgdmhkbC1nZXQtc3ludGFj dGljLWNvbnRleHQgY29tbWVudCB2aGRsLWdldC1vZmZzZXQgYXBwbHkgKyBtYXBjYXIgY3VycmVu dC1pbmRlbnRhdGlvbiBtZXNzYWdlICJzeW50YXg6ICVzLCBpbmRlbnQ9ICVkIiAwIGJhY2stdG8t aW5kZW50YXRpb24gcnVuLWhvb2tzIHZoZGwtc3BlY2lhbC1pbmRlbnQtaG9vayAxIC01MDAgY3Vy cmVudC10aW1lIDIgIkluZGVudGluZy4uLiAoJTJkJXMpIiAxMDAgIiUiIGhlcmUgdmhkbC1wcm9n cmVzcy1pbmZvIHZoZGwtcHJvZ3Jlc3MtaW50ZXJ2YWxdIDcgKCMkIC4gMTUzNDI5KSBuaWxdKQoj QDEwMyBJbmRlbnQgd2hvbGUgYnVmZmVyIGFzIFZIREwgY29kZS4KQ2FsbHMgYGluZGVudC1yZWdp b24nIGZvciB3aG9sZSBidWZmZXIgYW5kIGFkZHMgcHJvZ3Jlc3MgcmVwb3J0aW5nLh8KKGRlZmFs aWFzICd2aGRsLWluZGVudC1idWZmZXIgI1tuaWwgIghcMjAzXG4AXDMwMmVkXDMwMyMRXDMwNGVk XDMwNSNcMjEwCFwyMDMYAFwzMDZcMzA3IVwyMTBcMzA1XDIxMRFcMjA3IiBbdmhkbC1wcm9ncmVz cy1pbnRlcnZhbCB2aGRsLXByb2dyZXNzLWluZm8gdmVjdG9yIDAgaW5kZW50LXJlZ2lvbiBuaWwg bWVzc2FnZSAiSW5kZW50aW5nLi4uZG9uZSJdIDQgKCMkIC4gMTU0MzYxKSBuaWxdKQojQDczIElu ZGVudCByZWdpb24gYXMgVkhETCBjb2RlLgpBZGRzIHByb2dyZXNzIHJlcG9ydGluZyB0byBgaW5k ZW50LXJlZ2lvbicuHwooZGVmYWxpYXMgJ3ZoZGwtaW5kZW50LXJlZ2lvbiAjWyhzdGFydCBlbmQg Y29sdW1uKSAiCFwyMDNcbgBcMzA1CVxuXDMwNiMTXDMwNwlcblxmI1wyMTAIXDIwMxgAXDMxMFwz MTEhXDIxMFwzMTJcMjExE1wyMDciIFt2aGRsLXByb2dyZXNzLWludGVydmFsIHN0YXJ0IGVuZCB2 aGRsLXByb2dyZXNzLWluZm8gY29sdW1uIHZlY3RvciAwIGluZGVudC1yZWdpb24gbWVzc2FnZSAi SW5kZW50aW5nLi4uZG9uZSIgbmlsXSA0ICgjJCAuIDE1NDY5NikgInJcblAiXSkKI0AxNDUgSW5k ZW50IGVhY2ggbGluZSBvZiB0aGUgbGlzdCBzdGFydGluZyBqdXN0IGFmdGVyIHBvaW50LgpJZiBv cHRpb25hbCBhcmcgRU5EUE9TIGlzIGdpdmVuLCBpbmRlbnQgZWFjaCBsaW5lLCBzdG9wcGluZyB3 aGVuCkVORFBPUyBpcyBlbmNvdW50ZXJlZC4fCihkZWZhbGlhcyAndmhkbC1pbmRlbnQtc2V4cCAj Wygmb3B0aW9uYWwgZW5kcG9zKSAiXDIxMmBcMzAzXDMwNAhcIlwyMTBgGRpcMzA1XG4JXDMwNCMr XDIwNyIgW2VuZHBvcyBlbmQgYmVnIHZoZGwtZm9yd2FyZC1zZXhwIG5pbCBpbmRlbnQtcmVnaW9u XSA0ICgjJCAuIDE1NTAzNykgbmlsXSkKI0A0NiBTaG93IHN5bnRhY3RpYyBpbmZvcm1hdGlvbiBm b3IgY3VycmVudCBsaW5lLh8KKGRlZmFsaWFzICd2aGRsLXNob3ctc3ludGFjdGljLWluZm9ybWF0 aW9uICNbbmlsICJcMzAwXDMwMVwzMDIgXCJcMjEwXDMwMyBcMjA3IiBbbWVzc2FnZSAic3ludGFj dGljIGFuYWx5c2lzOiAlcyIgdmhkbC1nZXQtc3ludGFjdGljLWNvbnRleHQgdmhkbC1rZWVwLXJl Z2lvbi1hY3RpdmVdIDMgKCMkIC4gMTU1MzU0KSBuaWxdKQojQDQ3IENoZWNrIHN5bnRhY3RpYyBp bmZvcm1hdGlvbiBmb3IgY3VycmVudCBsaW5lLh8KKGRlZmFsaWFzICd2aGRsLXJlZ3Jlc3MtbGlu ZSAjWygmb3B0aW9uYWwgYXJnKSAiXDIxMlwzMDV/XDIxMFwzMDZcMzA3YBhcMzEweVwyMTBgCGJc MjEwKVwzMTEjXDIwNRsAXDMxMnVcMjEwXDMxM3AhKVwzMTQgXDMwNRkaG1wzMTVcMzE2XG5cIlwy MTBcZlwyMDRDAAtcMjAzQwALPFwyMDNDAAsJXDIzMlwyMDRuAFwzMTdcMzIwCwkjXDIxMFwyMDJu AFwyMTJcMzEweVwyMTBcMzIxXDMyMiFcMjA0bQBcMzA1f1wyMTBcMzA2XDMwN2AYXDMxMHlcMjEw YAhiXDIxMClcMzExI1wyMDNkAFwzMjMgXDIxMFwzMjRjXDIxMFwzMjVcMzI2CVwiY1wyMTApK1wz MjcgXDIwNyIgW2hlcmUgZXhwdXJnYXRlZCBhY3R1YWwgZXhwZWN0ZWQgYXJnIG5pbCBzZWFyY2gt YmFja3dhcmQgIiAtLSAoKCIgMCB0IDQgcmVhZCB2aGRsLWdldC1zeW50YWN0aWMtY29udGV4dCBt YXBjYXIgI1soZWx0KSAiCEBcMzAyPj9cMjA1DwBcMzAzCQhDXCJcMjExEVwyMDciIFtlbHQgZXhw dXJnYXRlZCAoZW50aXR5IGNvbmZpZ3VyYXRpb24gcGFja2FnZSBwYWNrYWdlLWJvZHkgYXJjaGl0 ZWN0dXJlKSBhcHBlbmRdIDNdIGVycm9yICJTaG91bGQgYmU6ICVzLCBpczogJXMiIGxvb2tpbmct YXQgIl5cXHMtKlxcKC0tLipcXCk/JCIga2lsbC1saW5lICIgLS0gIiBmb3JtYXQgIiVzIiB2aGRs LWtlZXAtcmVnaW9uLWFjdGl2ZV0gNCAoIyQgLiAxNTU1OTMpICJQIl0pCiNANDY5IFRoZSBmb3Jt YXQgb2YgdGhpcyBhbGlzdCBpcyAoTU9ERVMgW29yIE1PREVdIFJFR0VYUCBBTElHTi1QQVRURVJO IFNVQkVYUCkuCkl0IGlzIHNlYXJjaGVkIGluIG9yZGVyLiAgSWYgUkVHRVhQIGlzIGZvdW5kIGFu eXdoZXJlIGluIHRoZSBmaXJzdApsaW5lIG9mIGEgcmVnaW9uIHRvIGJlIGFsaWduZWQsIEFMSUdO LVBBVFRFUk4gd2lsbCBiZSB1c2VkIGZvciB0aGF0CnJlZ2lvbi4gIEFMSUdOLVBBVFRFUk4gbXVz dCBpbmNsdWRlIHRoZSB3aGl0ZXNwYWNlIHRvIGJlIGV4cGFuZGVkIG9yCmNvbnRyYWN0ZWQuICBJ dCBtYXkgYWxzbyBwcm92aWRlIHJlZ2V4cHMgZm9yIHRoZSB0ZXh0IHN1cnJvdW5kaW5nIHRoZQp3 aGl0ZXNwYWNlLiAgU1VCRVhQIHNwZWNpZmllcyB3aGljaCBzdWItZXhwcmVzc2lvbiBvZgpBTElH Ti1QQVRURVJOIG1hdGNoZXMgdGhlIHdoaXRlIHNwYWNlIHRvIGJlIGV4cGFuZGVkL2NvbnRyYWN0 ZWQuHwooZGVmdmFyIHZoZGwtYWxpZ24tYWxpc3QgJygodmhkbC1tb2RlICJcXDxcXChjb25zdGFu dFxcfHF1YW50aXR5XFx8c2lnbmFsXFx8dGVybWluYWxcXHx2YXJpYWJsZVxcKVsgCV0iICJcXDxc XChjb25zdGFudFxcfHF1YW50aXR5XFx8c2lnbmFsXFx8dGVybWluYWxcXHx2YXJpYWJsZVxcKVxc KFsgCV0rXFwpIiAyKSAodmhkbC1tb2RlICI6W149XSIgIlxcKFsgCV0qXFwpOltePV0iKSAodmhk bC1tb2RlICI6WyAJXSpcXChpblxcfG91dFxcfGlub3V0XFx8YnVmZmVyXFx8XFwpXFw+IiAiOlsg CV0qXFwoaW5cXHxvdXRcXHxpbm91dFxcfGJ1ZmZlclxcfFxcKVxcKFsgCV0rXFwpIiAyKSAodmhk bC1tb2RlICI9PSIgIlxcKFsgCV0qXFwpPT0iIDEpICh2aGRsLW1vZGUgIjo9IiAiXFwoWyAJXSpc XCk6PSIgMSkgKHZoZGwtbW9kZSAiPD0iICJcXChbIAldKlxcKTw9IiAxKSAodmhkbC1tb2RlICI9 PiIgIlxcKFsgCV0qXFwpPT4iIDEpICh2aGRsLW1vZGUgIjo9IiAiXFwoWyAJXSpcXCk6PSIgMSkg KHZoZGwtbW9kZSAiPD0iICJcXChbIAldKlxcKTw9IiAxKSAodmhkbC1tb2RlICJbIAldYWZ0ZXJc XD4iICJbXiAJXVxcKFsgCV0rXFwpYWZ0ZXJcXD4iIDEpICh2aGRsLW1vZGUgIlsgCV13aGVuXFw+ IiAiW14gCV1cXChbIAldK1xcKXdoZW5cXD4iIDEpICh2aGRsLW1vZGUgIlsgCV1lbHNlXFw+IiAi W14gCV1cXChbIAldK1xcKWVsc2VcXD4iIDEpKSAoIyQgLiAxNTYzNDMpKQojQDE0MyBJZiBSRUdF WFAgaXMgbm90IGZvdW5kIG9uIHRoZSBmaXJzdCBsaW5lIG9mIHRoZSByZWdpb24gdGhhdCBjbGF1 c2UKaXMgaWdub3JlZC4gIElmIHRoaXMgdmFyaWFibGUgaXMgbm9uLW5pbCwgdGhlbiB0aGUgY2xh dXNlIGlzIHRyaWVkIGFueXdheS4fCihkZWZ2YXIgdmhkbC1hbGlnbi10cnktYWxsLWNsYXVzZXMg dCAoIyQgLiAxNTc1NDEpKQojQDMwNyBBdHRlbXB0IHRvIGFsaWduIGEgcmFuZ2Ugb2YgbGluZXMg YmFzZWQgb24gdGhlIGNvbnRlbnQgb2YgdGhlCmxpbmVzLiAgVGhlIGRlZmluaXRpb24gb2YgYGFs aWdubWVudC1saXN0JyBkZXRlcm1pbmVzIHRoZSBtYXRjaGluZwpvcmRlciBhbmQgdGhlIG1hbm5l ciBpbiB3aGljaCB0aGUgbGluZXMgYXJlIGFsaWduZWQuICBJZiBBTElHTk1FTlQtTElTVAppcyBu b3Qgc3BlY2lmaWVkIGB2aGRsLWFsaWduLWFsaXN0JyBpcyB1c2VkLiAgSWYgSU5ERU5UIGlzIG5v bi1uaWwsCmluZGVudGF0aW9uIGlzIGRvbmUgYmVmb3JlIGFsaWduaW5nLh8KKGRlZmFsaWFzICd2 aGRsLWFsaWduLXJlZ2lvbiAjWyhiZWdpbiBlbmQgJm9wdGlvbmFsIHNwYWNpbmcgYWxpZ25tZW50 LWxpc3QgaW5kZW50KSAiCFwyMDYFAAkQXG5cMjA2CwBcMzA2ElwyMTJcMzA3XDIxMRscDWJcMjEw XDMxMCAVDhNiXDIxMFwzMTF5XDIxMGBcMjExFhMUC1wyMDMtAFwzMTJcZg1cMzA3I1wyMTArXDMx M1wzMTQIIR4UHhVcMzA3HhZcMzE1XDMxNlwzMTcOFyNcMjEwDhRcMjA1XDIzNgBcMjEyDhNiXDIx MFwzMDdcMjEyXDMwN39cMjEwYCkeGB4ZDhRAXDIxMRYZQDxcMjAzaQAOGg4ZQD5cMjA0cgAOGg4Z QD1cMjAzXDIyNQAOG1wyMDRcMjAzAFwzMjAOGUFADhhcMzEzI1wyMDNcMjI1AFwzMjEOEw0OGUFB QA4ZQUFBQFxuJVwyMTAOFEEWFCtcMjAyQAAWFg4cXDIwNFwyNTQAXDMxNVwzMTZcMzIyDhcjXDIx MA4WK1wyMDciIFthbGlnbm1lbnQtbGlzdCB2aGRsLWFsaWduLWFsaXN0IHNwYWNpbmcgaW5kZW50 IGJvbCBlbmQgMSBuaWwgcG9pbnQtbWFya2VyIDAgaW5kZW50LXJlZ2lvbiB0IGNvcHktYWxpc3Qg bW9kaWZ5LXN5bnRheC1lbnRyeSA5NSAidyIgcmUtc2VhcmNoLWZvcndhcmQgdmhkbC1hbGlnbi1y ZWdpb24tMSAiXyIgYmVnaW4gY29weSBjYXNlLWZvbGQtc2VhcmNoIHJlc3VsdCB2aGRsLW1vZGUt c3ludGF4LXRhYmxlIGVvbCBlbGVtZW50IG1ham9yLW1vZGUgdmhkbC1hbGlnbi10cnktYWxsLWNs YXVzZXMgdmhkbC11bmRlcnNjb3JlLWlzLXBhcnQtb2Ytd29yZF0gNyAoIyQgLiAxNTc3NDIpICJy XG5wIl0pCiNANDAwIEFsaWduIGEgcmFuZ2Ugb2YgbGluZXMgZnJvbSBCRUdJTiB0byBFTkQuICBU aGUgcmVndWxhciBleHByZXNzaW9uCk1BVENIIG11c3QgbWF0Y2ggZXhhY3RseSBvbmUgZmllbGRz OiB0aGUgd2hpdGVzcGFjZSB0byBiZQpjb250cmFjdGVkL2V4cGFuZGVkLiAgVGhlIGFsaWdubWVu dCBjb2x1bW4gd2lsbCBlcXVhbCB0aGUKcmlnaHRtb3N0IGNvbHVtbiBvZiB0aGUgd2lkZXN0IHdo aXRlc3BhY2UgYmxvY2suIFNQQUNJTkcgaXMKdGhlIGFtb3VudCBvZiBleHRyYSBzcGFjZXMgdG8g YWRkIHRvIHRoZSBjYWxjdWxhdGVkIG1heGltdW0gcmVxdWlyZWQuClNQQUNJTkcgZGVmYXVsdHMg dG8gMSBzbyB0aGF0IGF0IGxlYXN0IG9uZSBzcGFjZSBpcyBpbnNlcnRlZCBhZnRlcgp0aGUgdG9r ZW4gaW4gTUFUQ0guHwooZGVmYWxpYXMgJ3ZoZGwtYWxpZ24tcmVnaW9uLTEgI1soYmVnaW4gZW5k IG1hdGNoICZvcHRpb25hbCBzdWJzdHIgc3BhY2luZykgIghcMjA2BQBcMzA2EAlcMjA2CwBcMzA2 EVwyMTJcMzA3XDMxMFwyMTFcMzA3XDIxMVwyMTEaGxwdHg8eEA4RYlwyMTBcMzA3f1wyMTBgE1wz MTB5XDIxMGBcMjExFhEUXGYOEldcMjAzcgBcMjEyXDMxMQ4TC1wzMTIjXDIwM18AYB4UXDIxMlwz MTB5XDIxMFwzMTFcMzEzDhRcMzEyIypcMjA0XwAJXDIyNFxmWlwyMTEWEA4PVlwyMDNfAA4QFg8p XDMwN3lcMjEwYBRcMjEyXDMwN39cMjEwYCkTDVQVXDIwMiwADhFcMjExFGJcMjEwXDIxMlwzMDd/ XDIxMGApEw1cMzEwVlwyMDVcMzI0AFwzMTEOEwtcMzEyI1wyMDNcMjc2AGAeFFwyMTJcMzEweVwy MTBcMzExXDMxMw4UXDMxMiMqXDIwNFwyNzYACVwyMjUJXDIyNFoSCVwyMjRcZloWEAlcMjI0Ylwy MTBcMzE0XG4hXDIxMFwzMTVcMzE2Dg8OEFoIXFxcIlwyMTBcMzEweVwyMTBcMzA3eVwyMTBgFFwy MTJcMzA3f1wyMTBgKRMNU1wyMTEVXDIwMlwyMDAALgdcMjA3IiBbc3BhY2luZyBzdWJzdHIgd2lk dGggZW9sIGJvbCBsaW5lcyAxIG5pbCAwIHJlLXNlYXJjaC1mb3J3YXJkIHQgIl5cXChbXlwiXSpc IlteXCJdKlwiXFwpKlteXCJdKi0tIiBkZWxldGUtY2hhciBpbnNlcnQtY2hhciAzMiBtYXggZGlz dGFuY2UgYmVnaW4gZW5kIG1hdGNoIHBvc2l0aW9uXSA3ICgjJCAuIDE1ODgxNSldKQojQDM0IEFs aWduIGlubGluZSBjb21tZW50cyBpbiByZWdpb24uHwooZGVmYWxpYXMgJ3ZoZGwtYWxpZ24taW5s aW5lLWNvbW1lbnQtcmVnaW9uLTEgI1soYmVnIGVuZCAmb3B0aW9uYWwgc3BhY2luZykgIlwyMTJc MzA2XDIxMVwzMDcYGRpcMzEwG1wzMTFcMzEyXDMxM1xmI1wyMTANYlwyMTBgDhdXXDIwM1cAXDMx NFwzMTUhXDIwNDgAXDMxNFwzMTYhXDIwMzgAXG5cMzE3XDIyNVwzMTdcMjI0Wl0SCVwzMjBcMjI1 XDMyMFwyMjRaXRFcMjAyUQBcMzE0XDMyMSFcMjAzUQBcMzE3XDIyNVwzMTdcMjI0Wg4YWVwyMDNR AAlcMzIwXDIyNVwzMjBcMjI0Wl0RXDMxN3lcMjEwXDIwMhIADWJcMjEwDhlcMjA2YABcMzIwFhlc bg4ZXFwSYA4XV1wyMDVcMzAyAFwzMTRcMzE1IVwyMDRcMjc0AFwzMTRcMzIyIVwyMDRcMjEzAFwz MTRcMzIzIVwyMDNcMjc0AFwzMTdcMjI1XDMxN1wyMjRaDhhZXDIwM1wyNzQAXDMxN1wyMjViXDIx MFwzMTdcMjI0XDMxN1wyMjV8XDIxMFwzMjRcMzI1DhlcIlwyMTBcbg4YWFwyMDNcMjUxAA4Yalwy MTBcMjAyXDI3NABcbglcXA4aWFwyMDNcMjcwAFxualwyMTBcMjAyXDI3NAAOGGpcMjEwXDMxN3lc MjEwXDIwMmcAEw4bXDIwNFwzMTYAXDMxMVwzMTJcMzI2XGYjXDIxMAstXDIwNyIgW2Nhc2UtZm9s ZC1zZWFyY2ggaGlnaC1sZW5ndGggaGlnaC1zdGFydCByZXN1bHQgdmhkbC1tb2RlLXN5bnRheC10 YWJsZSBiZWcgMCB0IG5pbCBtb2RpZnktc3ludGF4LWVudHJ5IDk1ICJ3IiBsb29raW5nLWF0ICJe XFxzLSpcXChiZWdpblxcfGVuZFxcKVxcPiIgIl5cXCguKlteIAlcbi1dK1xcKVxccy0qXFwoLS1c XHMtKi4qXFwpJCIgMSAyICJeXFwoXFxzLSpcXCkpXFwoLS1cXHMtKi4qXFwpJCIgIl4uKlteIAlc bi1dK1xcKFxccy0qXFwpLS0iICJeXFwoXFxzLSpcXCktLSIgaW5zZXJ0LWNoYXIgMzIgIl8iIGVu ZCBjb21tZW50LWNvbHVtbiBzcGFjaW5nIGVuZC1jb21tZW50LWNvbHVtbiB2aGRsLXVuZGVyc2Nv cmUtaXMtcGFydC1vZi13b3JkXSA0ICgjJCAuIDE1OTk0MCldKQojQDM1IEFsaWduIHJlZ2lvbiB3 aXRob3V0IGluZGVudGF0aW9uLh8KKGRlZmFsaWFzICd2aGRsLWFsaWduLW5vaW5kZW50LXJlZ2lv biAjWyhiZWcgZW5kICZvcHRpb25hbCBzcGFjaW5nIG5vLW1lc3NhZ2UpICJcMjEyXDMwNhgJYlwy MTBcMzA3eVwyMTBgEVxuYlwyMTBcMzEwIBJcMzExCVxuXCJcMjEwC1wyMDQeAFwzMTJcMzEzIVwy MTBcMzE0CVxuXDMxNSNcMjEwCWJcMjEwXGZcMjA0OQBcMzE2CVxuDSNcMjEwXDMxNwlcblwiXDIx MFwyMDJvAAlcbldcMjAzXgBcMzIwXDMyMVxuXDMxNSNcMjAzXgBcMzEwIBBcMzE2CQgNI1wyMTBc MzE3CQhcIlwyMTAIVFwyMTERYlwyMTBcMjAyOQAJXG5XXDIwM28AXDMxNglcbg0jXDIxMFwzMTcJ XG5cIlwyMTAqCz9cMjA1eABcMzEyXDMyMiFcMjA3IiBbcG9zIGJlZyBlbmQgbm8tbWVzc2FnZSB2 aGRsLWFsaWduLWdyb3VwcyBzcGFjaW5nIG5pbCAwIHBvaW50LW1hcmtlciB1bnRhYmlmeSBtZXNz YWdlICJBbGlnbmluZy4uLiIgdmhkbC1maXh1cC13aGl0ZXNwYWNlLXJlZ2lvbiB0IHZoZGwtYWxp Z24tcmVnaW9uIHZoZGwtYWxpZ24taW5saW5lLWNvbW1lbnQtcmVnaW9uLTEgcmUtc2VhcmNoLWZv cndhcmQgIl5cXHMtKiQiICJBbGlnbmluZy4uLmRvbmUiXSA1ICgjJCAuIDE2MDk1NCkgInJcblAi XSkKI0A0MyBBbGlnbiBncm91cCBvZiBsaW5lcyBiZXR3ZWVuIGVtcHR5IGxpbmVzLh8KKGRlZmFs aWFzICd2aGRsLWFsaWduLWdyb3VwICNbKCZvcHRpb25hbCBzcGFjaW5nKSAiXDIxMmBcMzA0XDIx MRgZGlwzMDVcMzA2XDMwNFwzMDcjXDIwMxQAXDMxMCBcMjAyFQBkEFxuYlwyMTBcMzExXDMwNlwz MDRcMzA3I1wyMDMlAGBcMjAyJgBlEVwzMTIJCFwiXDIxMFwzMTNcMzE0IVwyMTBcMzE1CQhcMzA3 I1wyMTBcMzE2CQgLI1wyMTBcMzE3CQhcIlwyMTBcMzEzXDMyMCEsXDIwNyIgW2VuZCBiZWcgc3Rh cnQgc3BhY2luZyBuaWwgcmUtc2VhcmNoLWZvcndhcmQgIl5cXHMtKiQiIHQgcG9pbnQtbWFya2Vy IHJlLXNlYXJjaC1iYWNrd2FyZCB1bnRhYmlmeSBtZXNzYWdlICJBbGlnbmluZy4uLiIgdmhkbC1m aXh1cC13aGl0ZXNwYWNlLXJlZ2lvbiB2aGRsLWFsaWduLXJlZ2lvbiB2aGRsLWFsaWduLWlubGlu ZS1jb21tZW50LXJlZ2lvbi0xICJBbGlnbmluZy4uLmRvbmUiXSA0ICgjJCAuIDE2MTYwMykgbmls XSkKI0AzNSBBbGlnbiBidWZmZXIgd2l0aG91dCBpbmRlbnRhdGlvbi4fCihkZWZhbGlhcyAndmhk bC1hbGlnbi1ub2luZGVudC1idWZmZXIgI1tuaWwgIlwzMDBlZFwiXDIwNyIgW3ZoZGwtYWxpZ24t bm9pbmRlbnQtcmVnaW9uXSAzICgjJCAuIDE2MjExNikgbmlsXSkKI0AxNDggQWxpZ24gaW5saW5l IGNvbW1lbnRzIHdpdGhpbiBhIHJlZ2lvbi4gIEdyb3VwcyBvZiBjb2RlIGxpbmVzIHNlcGFyYXRl ZCBieQplbXB0eSBsaW5lcyBhcmUgYWxpZ25lZCBpbmRpdmlkdWFsbHksIGlmIGB2aGRsLWFsaWdu LWdyb3VwcycgaXMgbm9uLW5pbC4fCihkZWZhbGlhcyAndmhkbC1hbGlnbi1pbmxpbmUtY29tbWVu dC1yZWdpb24gI1soYmVnIGVuZCAmb3B0aW9uYWwgc3BhY2luZyBuby1tZXNzYWdlKSAiXDIxMlwz MDYYCWJcMjEwXDMwN3lcMjEwYBFcbmJcMjEwXDMxMCASXDMxMQlcblwiXDIxMAtcMjA0HgBcMzEy XDMxMyFcMjEwCWJcMjEwXGZcMjA0LgBcMzE0CVxuDSNcMjEwXDIwMloACVxuV1wyMDNOAFwzMTVc MzE2XG5cMzE3I1wyMDNOAFwzMTAgEFwzMTQJCA0jXDIxMAhUXDIxMRFiXDIxMFwyMDIuAAlcbldc MjAzWgBcMzE0CVxuDSNcMjEwKQs/XDIwNWMAXDMxMlwzMjAhKVwyMDciIFtwb3MgYmVnIGVuZCBu by1tZXNzYWdlIHZoZGwtYWxpZ24tZ3JvdXBzIHNwYWNpbmcgbmlsIDAgcG9pbnQtbWFya2VyIHVu dGFiaWZ5IG1lc3NhZ2UgIkFsaWduaW5nIGlubGluZSBjb21tZW50cy4uLiIgdmhkbC1hbGlnbi1p bmxpbmUtY29tbWVudC1yZWdpb24tMSByZS1zZWFyY2gtZm9yd2FyZCAiXlxccy0qJCIgdCAiQWxp Z25pbmcgaW5saW5lIGNvbW1lbnRzLi4uZG9uZSJdIDUgKCMkIC4gMTYyMjY3KSAiclxuUCJdKQoj QDY4IEFsaWduIGlubGluZSBjb21tZW50cyB3aXRoaW4gYSBncm91cCBvZiBsaW5lcyBiZXR3ZWVu IGVtcHR5IGxpbmVzLh8KKGRlZmFsaWFzICd2aGRsLWFsaWduLWlubGluZS1jb21tZW50LWdyb3Vw ICNbKCZvcHRpb25hbCBzcGFjaW5nKSAiXDIxMmBcMzAzXDIxMRgZGlwzMDRcMzA1XDMwM1wzMDYj XDIwMxQAXDMwNyBcMjAyFQBkEFxuYlwyMTBcMzEwXDMwNVwzMDNcMzA2I1wyMDMlAGBcMjAyJgBl EVwzMTEJCFwiXDIxMFwzMTJcMzEzIVwyMTBcMzE0CQhcIlwyMTBcMzEyXDMxNSEsXDIwNyIgW2Vu ZCBiZWcgc3RhcnQgbmlsIHJlLXNlYXJjaC1mb3J3YXJkICJeXFxzLSokIiB0IHBvaW50LW1hcmtl ciByZS1zZWFyY2gtYmFja3dhcmQgdW50YWJpZnkgbWVzc2FnZSAiQWxpZ25pbmcgaW5saW5lIGNv bW1lbnRzLi4uIiB2aGRsLWFsaWduLWlubGluZS1jb21tZW50LXJlZ2lvbi0xICJBbGlnbmluZyBp bmxpbmUgY29tbWVudHMuLi5kb25lIl0gNCAoIyQgLiAxNjI5NjcpIG5pbF0pCiNAMTQ2IEFsaWdu IGlubGluZSBjb21tZW50cyB3aXRoaW4gYnVmZmVyLiAgR3JvdXBzIG9mIGNvZGUgbGluZXMgc2Vw YXJhdGVkIGJ5CmVtcHR5IGxpbmVzIGFyZSBhbGlnbmVkIGluZGl2aWR1YWxseSwgaWYgYHZoZGwt YWxpZ24tZ3JvdXBzJyBpcyBub24tbmlsLh8KKGRlZmFsaWFzICd2aGRsLWFsaWduLWlubGluZS1j b21tZW50LWJ1ZmZlciAjW25pbCAiXDMwMGVkXCJcMjA3IiBbdmhkbC1hbGlnbi1pbmxpbmUtY29t bWVudC1yZWdpb25dIDMgKCMkIC4gMTYzNDcxKSBuaWxdKQojQDE4NCBGaXh1cCB3aGl0ZXNwYWNl IGluIHJlZ2lvbi4gIFN1cnJvdW5kIG9wZXJhdG9yIHN5bWJvbHMgYnkgb25lIHNwYWNlLAplbGlt aW5hdGUgbXVsdGlwbGUgc3BhY2VzIChleGNlcHQgYXQgYmVnaW5uaW5nIG9mIGxpbmUpLCBlbGlt aW5hdGUgc3BhY2VzIGF0CmVuZCBvZiBsaW5lLCBkbyBub3RoaW5nIGluIGNvbW1lbnRzLh8KKGRl ZmFsaWFzICd2aGRsLWZpeHVwLXdoaXRlc3BhY2UtcmVnaW9uICNbKGJlZyBlbmQgJm9wdGlvbmFs IG5vLW1lc3NhZ2UpICIIXDIwNAgAXDMwM1wzMDQhXDIxMFwyMTIJYlwyMTBcMzA1IBFcbmJcMjEw XDMwNlwzMDcJXDMxMCNcMjAzMgBcMzExXDMxMiFcMzEzXDIzMlwyMDMrAFwzMDZcMzE0CVwzMTAj XDIxMFwyMDISAFwzMTVcMzE2IVwyMTBcMjAyEgBcbmJcMjEwXDMwNlwzMTcJXDMxMCNcMjAzWQBc MzExXDMyMCFcMzEzXDIzMlwyMDNOAFwzMDZcMzE0CVwzMTAjXDIxMFwyMDI1AFwzMTVcMzIxXDMy MlwyMTFcMjExXDMyMCVcMjEwXDIwMjUAXG5iXDIxMFwzMjNcMzI0IVwyMDNqAFwzMDZcMzI0CVwz MTAjXDIwNFxcAFwzMjNcMzI1IVwyMDNcMjAxAFwzMDZcMzI1CVwzMTAjXDIwM1wyMDEAXDMxNVwz MjZcMzIyXDIxMSNcMjEwXDIwMlxcAFwzMjNcMzI3IVwyMDNcMjMwAFwzMDZcMzI3CVwzMTAjXDIw M1wyMzAAXDMxNVwzMzBcMzIyXDIxMSNcMjEwXDIwMlxcAFwzMjNcMzMxIVwyMDNcMjQ2AFwzMDZc MzMxCVwzMTAjXDIwNFxcAFwzMjNcMzMyIVwyMDNcMjc1AFwzMDZcMzMzCVwzMTAjXDIwM1wyNzUA XDMxNVwzMzRcMzIyXDIxMSNcMjEwXDIwMlxcAFwzMjNcMzMzIVwyMDNcMzI0AFwzMDZcMzMzCVwz MTAjXDIwM1wzMjQAXDMxNVwzMzVcMzIyXDIxMSNcMjEwXDIwMlxcAFwzMDZcMzM2CVwzMTAjXDIw NFxcACkIP1wyMDVcMzQ1AFwzMDNcMzM3IVwyMDciIFtuby1tZXNzYWdlIGVuZCBiZWcgbWVzc2Fn ZSAiRml4aW5nIHVwIHdoaXRlc3BhY2UuLi4iIHBvaW50LW1hcmtlciByZS1zZWFyY2gtZm9yd2Fy ZCAiXFwoW14vOjw+PV1cXHxeXFwpXFwoLS1cXHw6XFx8PVxcfDxcXHw+XFx8Oj1cXHw8PVxcfD49 XFx8PT5cXClcXChbXj0+XVxcfCRcXCkiIHQgbWF0Y2gtc3RyaW5nIDIgIi0tIiAiLipcbiIgcmVw bGFjZS1tYXRjaCAiXFwxIFxcMiBcXDMiICJcXCgtLVxcfFxccy0qXFwoWyw7XVxcKVxcKSIgMSAi XFwyICIgbmlsIGxvb2tpbmctYXQgIi0tLipcbiIgIlxccy0rJCIgIiIgIlxccy0rOyIgIjsiICJe XFxzLSsiICJcXHMtKy0tIiAiXFxzLSsiICIgICIgIiAiICJcXFMtKyIgIkZpeGluZyB1cCB3aGl0 ZXNwYWNlLi4uZG9uZSJdIDYgKCMkIC4gMTYzNzQ1KSAiciJdKQojQDE4NCBGaXh1cCB3aGl0ZXNw YWNlIGluIGJ1ZmZlci4gIFN1cnJvdW5kIG9wZXJhdG9yIHN5bWJvbHMgYnkgb25lIHNwYWNlLApl bGltaW5hdGUgbXVsdGlwbGUgc3BhY2VzIChleGNlcHQgYXQgYmVnaW5uaW5nIG9mIGxpbmUpLCBl bGltaW5hdGUgc3BhY2VzIGF0CmVuZCBvZiBsaW5lLCBkbyBub3RoaW5nIGluIGNvbW1lbnRzLh8K KGRlZmFsaWFzICd2aGRsLWZpeHVwLXdoaXRlc3BhY2UtYnVmZmVyICNbbmlsICJcMzAwZWRcIlwy MDciIFt2aGRsLWZpeHVwLXdoaXRlc3BhY2UtcmVnaW9uXSAzICgjJCAuIDE2NTA1OSkgbmlsXSkK I0AyNDMgQmVhdXRpZnkgcmVnaW9uIGJ5IGFwcGx5aW5nIGluZGVudGF0aW9uLCB3aGl0ZXNwYWNl IGZpeHVwLCBhbGlnbm1lbnQsIGFuZApjYXNlIGZpeGluZyB0byBhIHJlc2lvbi4gIENhbGxzIGZ1 bmN0aW9ucyBgdmhkbC1pbmRlbnQtYnVmZmVyJywKYHZoZGwtYWxpZ24tbm9pbmRlbnQtYnVmZmVy JyAodmFyaWFibGUgYHZoZGwtYWxpZ24tZ3JvdXBzJyBzZXQgdG8gbm9uLW5pbCksIGFuZApgdmhk bC1maXgtY2FzZS1idWZmZXInLh8KKGRlZmFsaWFzICd2aGRsLWJlYXV0aWZ5LXJlZ2lvbiAjWyhi ZWcgZW5kKSAiXDMwMwgJXDMwNCNcMjEwXDMwNRpcMzA2CAlcIlwyMTApXDMwNwgJXCJcMjA3IiBb YmVnIGVuZCB2aGRsLWFsaWduLWdyb3VwcyB2aGRsLWluZGVudC1yZWdpb24gbmlsIHQgdmhkbC1h bGlnbi1ub2luZGVudC1yZWdpb24gdmhkbC1maXgtY2FzZS1yZWdpb25dIDQgKCMkIC4gMTY1MzYz KSAiciJdKQojQDE1OCBCZWF1dGlmeSBidWZmZXIgYnkgYXBwbHlpbmcgaW5kZW50YXRpb24sIHdo aXRlc3BhY2UgZml4dXAsIGFsaWdubWVudCwgYW5kCmNhc2UgZml4aW5nIHRvIGVudGlyZSBidWZm ZXIuICBDYWxscyBgdmhkbC1iZWF1dGlmeS1yZWdpb24nIGZvciB0aGUgZW50aXJlCmJ1ZmZlci4f CihkZWZhbGlhcyAndmhkbC1iZWF1dGlmeS1idWZmZXIgI1tuaWwgIlwzMDBlZFwiXDIwNyIgW3Zo ZGwtYmVhdXRpZnktcmVnaW9uXSAzICgjJCAuIDE2NTgyNykgbmlsXSkKI0A1MSBTeW50YXggb2Yg cHJvbXB0IGluc2VydGVkIGJ5IHRlbXBsYXRlIGdlbmVyYXRvcnMuHwooZGVmY29uc3QgdmhkbC10 ZW1wbGF0ZS1wcm9tcHQtc3ludGF4ICJbXiA9PD5dW148PkAuXG5dKlteID08Pl0iICgjJCAuIDE2 NjA4OCkpCiNAMTE4IEluZGljYXRlcyB3aGV0aGVyIGEgdGVtcGxhdGUgaGFzIGJlZW4gaW52b2tl ZCBieSBhIGhvb2sgb3IgYnkga2V5IG9yIG1lbnUuClVzZWQgZm9yIHVuZG9pbmcgYWZ0ZXIgdGVt cGxhdGUgYWJvcnRpb24uHwooZGVmdmFyIHZoZGwtdGVtcGxhdGUtaW52b2tlZC1ieS1ob29rIG5p bCAoIyQgLiAxNjYyMjUpKQooYnl0ZS1jb2RlICJcMzAxXDMwMlwzMDNcMzA0CFwiXDIwMw0AXDMw NVwyMDIOAFwzMDZcIlwyMDciIFtlbWFjcy12ZXJzaW9uIGRlZmFsaWFzIHZoZGwtY2hhcmFjdGVy LXRvLWV2ZW50IHN0cmluZy1tYXRjaCAiWEVtYWNzIiBjaGFyYWN0ZXItdG8tZXZlbnQgaWRlbnRp dHldIDUpCiNANDkgVXBkYXRlIHRoZSBtb2RlbGluZSBzdHJpbmcgZm9yIFZIREwgbWFqb3IgbW9k ZS4fCihkZWZhbGlhcyAndmhkbC1tb2RlLWxpbmUtdXBkYXRlICNbbmlsICJcMzAzCFwyMDQJAAlc MjA1XG4AXDMwNAhcMjA1DwBcMzA1CVwyMDUUAFwzMDZSElwzMDcgXDIwNyIgW3ZoZGwtZWxlY3Ry aWMtbW9kZSB2aGRsLXN0dXR0ZXItbW9kZSBtb2RlLW5hbWUgIlZIREwiICIvIiAiZSIgInMiIGZv cmNlLW1vZGUtbGluZS11cGRhdGVdIDQgKCMkIC4gMTY2NTY2KV0pCiNAMTA2IFRvZ2dsZSBWSERM IGVsZWN0cmljIG1vZGUuClR1cm4gb24gaWYgQVJHIHBvc2l0aXZlLCB0dXJuIG9mZiBpZiBBUkcg bmVnYXRpdmUsIHRvZ2dsZSBpZiBBUkcgemVybyBvciBuaWwuHwooZGVmYWxpYXMgJ3ZoZGwtZWxl Y3RyaWMtbW9kZSAjWyhhcmcpICIIXDIwM1xuAAhcMzAyVVwyMDMPAAk/XDIwMhoACFwzMDJWXDIw MxkAXDMwM1wyMDIaAFwzMDQRXDMwNSBcMjA3IiBbYXJnIHZoZGwtZWxlY3RyaWMtbW9kZSAwIHQg bmlsIHZoZGwtbW9kZS1saW5lLXVwZGF0ZV0gMiAoIyQgLiAxNjY4MjgpICJQIl0pCiNAMTA4IFRv Z2dsZSBWSERMIHN0dXR0ZXJpbmcgbW9kZS4KVHVybiBvbiBpZiBBUkcgcG9zaXRpdmUsIHR1cm4g b2ZmIGlmIEFSRyBuZWdhdGl2ZSwgdG9nZ2xlIGlmIEFSRyB6ZXJvIG9yIG5pbC4fCihkZWZhbGlh cyAndmhkbC1zdHV0dGVyLW1vZGUgI1soYXJnKSAiCFwyMDNcbgAIXDMwMlVcMjAzDwAJP1wyMDIa AAhcMzAyVlwyMDMZAFwzMDNcMjAyGgBcMzA0EVwzMDUgXDIwNyIgW2FyZyB2aGRsLXN0dXR0ZXIt bW9kZSAwIHQgbmlsIHZoZGwtbW9kZS1saW5lLXVwZGF0ZV0gMiAoIyQgLiAxNjcxMjIpICJQIl0p CiNAODEgLS0gc3RhcnRzIGEgY29tbWVudCwgLS0tIGRyYXdzIGEgaG9yaXpvbnRhbCBsaW5lLAot LS0tIHN0YXJ0cyBhIGRpc3BsYXkgY29tbWVudB8KKGRlZmFsaWFzICd2aGRsLWVsZWN0cmljLWRh c2ggI1soY291bnQpICIIXDIwM10ACVwyMDMZAAlgVVwyMDMZAFwzMDYRXG5iXDIxMFwzMDd5XDIx MFwzMTAgXDIwN2hcMzExVVwyMDQjAFwzMTILIVwyMDdcMzEyCyFcMjEwXDMxM1wzMTQhXDIxMFwz MTUgXDIxMRxcMzExVVwyMDNUAFwzMTYgXDIxMFwzMTNcMzE3IVwyMTBcMzE1IFwyMTEcXDMxMVVc MjAzSgBcMzEwXDMyMCFcMjAyUABcMzIxXGYhQ1wyMTEVKVwyMDJbAFwzMjFcZiFDFVwzMjIgKVwy MDdcMzEyCyFcMjA3IiBbdmhkbC1zdHV0dGVyLW1vZGUgYWJicmV2LXN0YXJ0LWxvY2F0aW9uIGxh c3QtYWJicmV2LWxvY2F0aW9uIGNvdW50IG5leHQtaW5wdXQgdW5yZWFkLWNvbW1hbmQtZXZlbnRz IG5pbCAwIHZoZGwtY29tbWVudC1kaXNwbGF5IDQ1IHNlbGYtaW5zZXJ0LWNvbW1hbmQgbWVzc2Fn ZSAiRW50ZXIgJy0nIGZvciBob3Jpei4gbGluZSwgJ0NSJyBmb3IgY29tbWVudGluZy1vdXQgY29k ZSwgZWxzZSBlbnRlciBjb21tZW50IiByZWFkLWNoYXIgdmhkbC1jb21tZW50LWRpc3BsYXktbGlu ZSAiRW50ZXIgJy0nIGZvciBkaXNwbGF5IGNvbW1lbnQsIGVsc2UgY29udGludWUgY29kaW5nIiB0 IHZoZGwtY2hhcmFjdGVyLXRvLWV2ZW50IHZoZGwtY29tbWVudC1pbnNlcnRdIDMgKCMkIC4gMTY3 NDE1KSAicCJdKQojQDI3ICdbJyAtLT4gJygnLCAnKFsnIC0tPiAnWycfCihkZWZhbGlhcyAndmhk bC1lbGVjdHJpYy1vcGVuLWJyYWNrZXQgI1soY291bnQpICIIXDIwMx4ACVwzMDJVXDIwMx4AaFwz MDNVXDIwMxkAXDMwNFwzMDUhXDIxMFwzMDZcMzA3XDMwMlwiXDIwN1wzMDZcMzAzXDMwMlwiXDIw N1wzMTAJIVwyMDciIFt2aGRsLXN0dXR0ZXItbW9kZSBjb3VudCAxIDQwIGRlbGV0ZS1jaGFyIC0x IGluc2VydC1jaGFyIDkxIHNlbGYtaW5zZXJ0LWNvbW1hbmRdIDMgKCMkIC4gMTY4MTY2KSAicCJd KQojQDI3ICddJyAtLT4gJyknLCAnKV0nIC0tPiAnXScfCihkZWZhbGlhcyAndmhkbC1lbGVjdHJp Yy1jbG9zZS1icmFja2V0ICNbKGNvdW50KSAiCFwyMDMkAAlcMzAyVVwyMDMkAGhcMzAzVVwyMDMc AFwzMDRcMzA1IVwyMTBcMzA2XDMwN1wzMDJcIlwyMTBcMjAyIQBcMzA2XDMwM1wzMDJcIlwyMTBc MzEwIFwyMDdcMzExCSFcMjA3IiBbdmhkbC1zdHV0dGVyLW1vZGUgY291bnQgMSA0MSBkZWxldGUt Y2hhciAtMSBpbnNlcnQtY2hhciA5MyBibGluay1tYXRjaGluZy1vcGVuIHNlbGYtaW5zZXJ0LWNv bW1hbmRdIDMgKCMkIC4gMTY4NDQyKSAicCJdKQojQDEwICcnIC0tPiAiHwooZGVmYWxpYXMgJ3Zo ZGwtZWxlY3RyaWMtcXVvdGUgI1soY291bnQpICIIXDIwMx4ACVwzMDNVXDIwMx4AaFxuVVwyMDMZ AFwzMDRcMzAzIVwyMTBcMzA1XDMwNlwzMDNcIlwyMDdcMzA1XDMwN1wzMDNcIlwyMDdcMzEwCSFc MjA3IiBbdmhkbC1zdHV0dGVyLW1vZGUgY291bnQgbGFzdC1pbnB1dC1jaGFyIDEgZGVsZXRlLWJh Y2t3YXJkLWNoYXIgaW5zZXJ0LWNoYXIgMzQgMzkgc2VsZi1pbnNlcnQtY29tbWFuZF0gMyAoIyQg LiAxNjg3NTQpICJwIl0pCiNAMzQgJzs7JyAtLT4gJyA6ICcsICc6IDsnIC0tPiAnIDo9ICcfCihk ZWZhbGlhcyAndmhkbC1lbGVjdHJpYy1zZW1pY29sb24gI1soY291bnQpICIIXDIwMzwACVwzMDVV XDIwMzwAaFxuVVwyMDMkAFwzMDZcMzA3IVwyMTBoXDMxMD1cMjA0HQBcMzExY1wyMTBcMzEyY1wy MTBcMzEzXDIxMRNcMjA3XGZcMzEzPVwyMDM3AGhcMzEwVVwyMDM3AFwzMDZcMzA3IVwyMTBcMzE0 Y1wyMDdcMzE1XDMxNlwzMDVcIlwyMDdcMzE3CSFcMjA3IiBbdmhkbC1zdHV0dGVyLW1vZGUgY291 bnQgbGFzdC1pbnB1dC1jaGFyIHRoaXMtY29tbWFuZCBsYXN0LWNvbW1hbmQgMSBkZWxldGUtY2hh ciAtMSAzMiAiICIgIjogIiB2aGRsLWVsZWN0cmljLWNvbG9uICI9ICIgaW5zZXJ0LWNoYXIgNTkg c2VsZi1pbnNlcnQtY29tbWFuZF0gMyAoIyQgLiAxNjkwMjYpICJwIl0pCiNAMTcgJywsJyAtLT4g JyA8PSAnHwooZGVmYWxpYXMgJ3ZoZGwtZWxlY3RyaWMtY29tbWEgI1soY291bnQpICIIXDIwMyUA CVwzMDNVXDIwMyUAaFxuVVwyMDMgAFwzMDRcMzA1IVwyMTBoXDMwNj1cMjA0HQBcMzA3Y1wyMTBc MzEwY1wyMDdcMzExXDMxMlwzMDNcIlwyMDdcMzEzCSFcMjA3IiBbdmhkbC1zdHV0dGVyLW1vZGUg Y291bnQgbGFzdC1pbnB1dC1jaGFyIDEgZGVsZXRlLWNoYXIgLTEgMzIgIiAiICI8PSAiIGluc2Vy dC1jaGFyIDQ0IHNlbGYtaW5zZXJ0LWNvbW1hbmRdIDMgKCMkIC4gMTY5NDUyKSAicCJdKQojQDE3 ICcuLicgLS0+ICcgPT4gJx8KKGRlZmFsaWFzICd2aGRsLWVsZWN0cmljLXBlcmlvZCAjWyhjb3Vu dCkgIghcMjAzJQAJXDMwM1VcMjAzJQBoXG5VXDIwMyAAXDMwNFwzMDUhXDIxMGhcMzA2PVwyMDQd AFwzMDdjXDIxMFwzMTBjXDIwN1wzMTFcMzEyXDMwM1wiXDIwN1wzMTMJIVwyMDciIFt2aGRsLXN0 dXR0ZXItbW9kZSBjb3VudCBsYXN0LWlucHV0LWNoYXIgMSBkZWxldGUtY2hhciAtMSAzMiAiICIg Ij0+ICIgaW5zZXJ0LWNoYXIgNDYgc2VsZi1pbnNlcnQtY29tbWFuZF0gMyAoIyQgLiAxNjk3NDcp ICJwIl0pCiNAMTcgJz09JyAtLT4gJyA9PSAnHwooZGVmYWxpYXMgJ3ZoZGwtZWxlY3RyaWMtZXF1 YWwgI1soY291bnQpICIIXDIwMyUACVwzMDNVXDIwMyUAaFxuVVwyMDMgAFwzMDRcMzA1IVwyMTBo XDMwNj1cMjA0HQBcMzA3Y1wyMTBcMzEwY1wyMDdcMzExXDMxMlwzMDNcIlwyMDdcMzEzCSFcMjA3 IiBbdmhkbC1zdHV0dGVyLW1vZGUgY291bnQgbGFzdC1pbnB1dC1jaGFyIDEgZGVsZXRlLWNoYXIg LTEgMzIgIiAiICI9PSAiIGluc2VydC1jaGFyIDYxIHNlbGYtaW5zZXJ0LWNvbW1hbmRdIDMgKCMk IC4gMTcwMDQzKSAicCJdKQojQDY1IEluc2VydCBhIHBhaXIgb2Ygcm91bmQgcGFyZW50aGVzZXMs IHBsYWNpbmcgcG9pbnQgYmV0d2VlbiB0aGVtLh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXBh aXJlZC1wYXJlbnMgI1tuaWwgIlwzMDBjXDIxMFwzMDEgXDIwNyIgWyIoKSIgYmFja3dhcmQtY2hh cl0gMSAoIyQgLiAxNzAzMzgpIG5pbF0pCiNAMjcgSW5zZXJ0IGFsaWFzIGRlY2xhcmF0aW9uLh8K KGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWFsaWFzICNbbmlsICJgGFwzMDRcMzA1IVwyMTBcMzA2 XDMwN1wzMTBcMzExCGAlXDIwNUIAXDMxMmNcMjEwXDMwNlwzMTNcMzE0GVwzMTRcbkA9XDIwNiYA CVxuXDIxMRtBQCk+KVwyMDUrAFwzMTVcMzE2UVwzMTBcMzExI1wyMDQ3AFwzMTdcMzIwIVwyMTBc MzA0XDMyMSFcMjEwXDMwNlwzMDdcMzIyXCJcMjEwXDMyMyApXDIwNyIgW3N0YXJ0IHN0YW5kYXJk IHZoZGwtc3RhbmRhcmQgeCB2aGRsLWluc2VydC1rZXl3b3JkICJBTElBUyAiIHZoZGwtdGVtcGxh dGUtZmllbGQgIm5hbWUiIG5pbCB0ICIgOiAiICJbdHlwZSIgYW1zICIgb3IgbmF0dXJlIiAiXSIg YmFja3dhcmQtZGVsZXRlLWNoYXIgMyAiIElTICIgIjsiIHZoZGwtY29tbWVudC1pbnNlcnQtaW5s aW5lXSA2ICgjJCAuIDE3MDUxNykgbmlsXSkKI0AyMiBJbnNlcnQgYXJjaGl0ZWN0dXJlLh8KKGRl ZmFsaWFzICd2aGRsLXRlbXBsYXRlLWFyY2hpdGVjdHVyZSAjW25pbCAiXDMwNiBgXDMwN1wyMTFc MjExXDMxMBgZGhscHVwzMTFcMzEyIVwyMTBcMzEzXDMxNFwzMDdcMzEwXGZgJVwyMTETXDIwNVwy MDIAXDMxMVwzMTUhXDIxMFwyMTJcMzA3Hh1cMzE2XDMxN1wzMjAOHiNcMjEwXDMyMVwzMjJcMzA3 XDMxMCMSXDMyM1wzMjQhXDIxMREWHQ4fXDIwNEUAXDMxNlwzMTdcMzI1Dh4jXDIxMCpcblwyMDNW AAlcMzI2XDIzMlwyMDRWAAljXDIxMFwyMDJaAFwzMTNcMzI3IVwyMTBcMzExXDMzMCFcMjEwXDMz MVwzMzIeIFwzMzIOIUA9XDIwNnUADiAOIVwyMTEeXCJBQCk+KT9cMjA1ewBcMzMzCw0OI1wzMzQ+ JC4GXDIwNyIgW2Nhc2UtZm9sZC1zZWFyY2ggc3RyaW5nIGVudGl0eS1leGlzdHMgYXJjaC1uYW1l IHN0YXJ0IG1hcmdpbiBjdXJyZW50LWluZGVudGF0aW9uIG5pbCB0IHZoZGwtaW5zZXJ0LWtleXdv cmQgIkFSQ0hJVEVDVFVSRSAiIHZoZGwtdGVtcGxhdGUtZmllbGQgIm5hbWUiICIgT0YgIiBtb2Rp Znktc3ludGF4LWVudHJ5IDk1ICJ3IiByZS1zZWFyY2gtYmFja3dhcmQgIlxcPGVudGl0eSBcXChc XHcrXFwpIGlzXFw+IiBtYXRjaC1zdHJpbmcgMSAiXyIgIiIgImVudGl0eSBuYW1lIiAiIElTIiB2 aGRsLXRlbXBsYXRlLWJlZ2luLWVuZCA4NyAiQVJDSElURUNUVVJFIiAodW5pdCBhbGwpIHJlc3Vs dCB2aGRsLW1vZGUtc3ludGF4LXRhYmxlIHZoZGwtdW5kZXJzY29yZS1pcy1wYXJ0LW9mLXdvcmQg c3RhbmRhcmQgdmhkbC1zdGFuZGFyZCB4IHZoZGwtaW5zZXJ0LWVtcHR5LWxpbmVzXSA2ICgjJCAu IDE3MDk3NSkgbmlsXSkKI0AzMSBJbnNlcnQgYXJyYXkgdHlwZSBkZWZpbml0aW9uLh8KKGRlZmFs aWFzICd2aGRsLXRlbXBsYXRlLWFycmF5ICNbKGtpbmQgJm9wdGlvbmFsIHNlY29uZGFyeSkgImAY XDMwM1wzMDQhXDIxMFwzMDVcMzA2XDMwNwk/CGAlXDIwNBUACVwyMDUqAFwzMDNcMzEwIVwyMTBc MzA1XG5cMzExPVwyMDMkAFwzMTJcMjAyJQBcMzEzIVwyMTBcMzAzXDMxNCEpXDIwNyIgW3N0YXJ0 IHNlY29uZGFyeSBraW5kIHZoZGwtaW5zZXJ0LWtleXdvcmQgIkFSUkFZICgiIHZoZGwtdGVtcGxh dGUtZmllbGQgInJhbmdlIiBuaWwgIikgT0YgIiB0eXBlICJ0eXBlIiAibmF0dXJlIiAiOyJdIDYg KCMkIC4gMTcxODE4KSBuaWxdKQojQDMyIEluc2VydCBhbiBhc3NlcnRpb24gc3RhdGVtZW50Lh8K KGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWFzc2VydCAjW25pbCAiYBhcMzAyXDMwMyFcMjEwCVwy MDMNAFwzMDRjXDIxMFwzMDVcMzA2XDMwN1wzMTAIYCVcMjA1SAAJXDIwMx4AXDMxMWNcMjEwYBBc MzAyXDMxMiFcMjEwXDMwNVwzMTNcMzA3XDIxMVwyMTFcMjExXDMxMCYGXDIwNDQACGB8XDIxMGAQ XDMwMlwzMTQhXDIxMFwzMDVcMzE1XDMwN1wzMTAjXDIwNEYACGB8XDIxMFwzMTZjKVwyMDciIFtz dGFydCB2aGRsLWNvbmRpdGlvbnMtaW4tcGFyZW50aGVzaXMgdmhkbC1pbnNlcnQta2V5d29yZCAi QVNTRVJUICIgIigiIHZoZGwtdGVtcGxhdGUtZmllbGQgImNvbmRpdGlvbiAobmVnYXRlZCkiIG5p bCB0ICIpIiAiIFJFUE9SVCAiICJzdHJpbmcgZXhwcmVzc2lvbiIgIiBTRVZFUklUWSAiICJbTk9U RSB8IFdBUk5JTkcgfCBFUlJPUiB8IEZBSUxVUkVdIiAiOyJdIDcgKCMkIC4gMTcyMTY1KSBuaWxd KQojQDUxIEluc2VydCBhbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gb3Igc3BlY2lmaWNhdGlvbi4f CihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1hdHRyaWJ1dGUgI1tuaWwgIlwzMDBcMzAxXDMwMlwz MDMjXDMwND1cMjAzDQBcMzA1IFwyMDdcMzA2IFwyMDciIFt2aGRsLWRlY2lzaW9uLXF1ZXJ5ICJh dHRyaWJ1dGUiICIoZCllY2xhcmF0aW9uIG9yIChzKXBlY2lmaWNhdGlvbj8iIHQgMTE1IHZoZGwt dGVtcGxhdGUtYXR0cmlidXRlLXNwZWMgdmhkbC10ZW1wbGF0ZS1hdHRyaWJ1dGUtZGVjbF0gNCAo IyQgLiAxNzI2NjApIG5pbF0pCiNAMzQgSW5zZXJ0IGFuIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi4f CihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1hdHRyaWJ1dGUtZGVjbCAjW25pbCAiYBhcMzAxXDMw MiFcMjEwXDMwM1wzMDRcMzA1XDMwNghgJVwyMDUXAFwzMDNcMzA3XDMxMFwiXDIxMFwzMTEgKVwy MDciIFtzdGFydCB2aGRsLWluc2VydC1rZXl3b3JkICJBVFRSSUJVVEUgIiB2aGRsLXRlbXBsYXRl LWZpZWxkICJuYW1lIiAiIDogIiB0ICJ0eXBlIiAiOyIgdmhkbC1jb21tZW50LWluc2VydC1pbmxp bmVdIDYgKCMkIC4gMTcyOTYyKSBuaWxdKQojQDM2IEluc2VydCBhbiBhdHRyaWJ1dGUgc3BlY2lm aWNhdGlvbi4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1hdHRyaWJ1dGUtc3BlYyAjW25pbCAi YBhcMzAxXDMwMiFcMjEwXDMwM1wzMDRcMzA1XDMwNghgJVwyMDUlAFwzMDFcMzA3IVwyMTBcMzAz XDMxMFwzMTFcIlwyMTBcMzAzXDMxMiFcMjEwXDMwMVwzMTMhXDIxMFwzMDNcMzE0XDMxNVwiKVwy MDciIFtzdGFydCB2aGRsLWluc2VydC1rZXl3b3JkICJBVFRSSUJVVEUgIiB2aGRsLXRlbXBsYXRl LWZpZWxkICJuYW1lIiBuaWwgdCAiIE9GICIgImVudGl0eSBuYW1lcyB8IE9USEVSUyB8IEFMTCIg IiA6ICIgImVudGl0eSBjbGFzcyIgIiBJUyAiICJleHByZXNzaW9uIiAiOyJdIDYgKCMkIC4gMTcz MjU0KSBuaWxdKQojQDE3IEluc2VydCBhIGJsb2NrLh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRl LWJsb2NrICNbbmlsICJcMzA2IGBcMzA3GBkaXDMxMFwzMTEhXDIxMAliXDIxMFwzMTJcMzEzXDMw N1wzMTQJYFwzMTVcXCVcMjExEFwyMDVYAFwzMTZ2XDIxMFwzMTZ1XDIxMFwzMTdjXDIxMFwzMTJc MzIwXDMwN1wzMTQjXDIwMzMAXDMyMWNcMjEwXDIwMjcAXDMyMlwzMjMhXDIxMFwzMjQbXDMyNFxm QD1cMjA2SAALXGZcMjExHUFAKT4pXDIwNFAAXDMxMFwzMjUhXDIxMFwzMjZcMzI3CFxuI1wyMTBc MzMwICtcMjA3IiBbbGFiZWwgc3RhcnQgbWFyZ2luIHN0YW5kYXJkIHZoZGwtc3RhbmRhcmQgeCBj dXJyZW50LWluZGVudGF0aW9uIG5pbCB2aGRsLWluc2VydC1rZXl3b3JkICI6IEJMT0NLICIgdmhk bC10ZW1wbGF0ZS1maWVsZCAibGFiZWwiIHQgOCAxICIoIiAiW2d1YXJkIGV4cHJlc3Npb25dIiAi KSIgZGVsZXRlLWNoYXIgLTIgODcgIiBJUyIgdmhkbC10ZW1wbGF0ZS1iZWdpbi1lbmQgIkJMT0NL IiB2aGRsLWNvbW1lbnQtYmxvY2tdIDcgKCMkIC4gMTczNjM4KSBuaWxdKQojQDQxIEluc2VydCBh IGJsb2NrIGNvbmZpZ3VyYXRpb24gc3RhdGVtZW50Lh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRl LWJsb2NrLWNvbmZpZ3VyYXRpb24gI1tuaWwgIlwzMDMgYBgZXDMwNFwzMDUhXDIxMFwzMDZcMzA3 XDMxMFwzMTEIYCVcMjA1JQBcMzA0XDMxMiFcMjEwCWpcMjEwXDMwNFwzMTMhXDIxMFwzMTR/XDIx MAlcblxcaipcMjA3IiBbc3RhcnQgbWFyZ2luIHZoZGwtYmFzaWMtb2Zmc2V0IGN1cnJlbnQtaW5k ZW50YXRpb24gdmhkbC1pbnNlcnQta2V5d29yZCAiRk9SICIgdmhkbC10ZW1wbGF0ZS1maWVsZCAi YmxvY2sgbmFtZSIgbmlsIHQgIlxuXG4iICJFTkQgRk9SOyIgMF0gNiAoIyQgLiAxNzQxODQpIG5p bF0pCiNAMjcgSW5zZXJ0IGEgYnJlYWsgc3RhdGVtZW50Lh8KKGRlZmFsaWFzICd2aGRsLXRlbXBs YXRlLWJyZWFrICNbbmlsICJcMzAyGFwzMDNcMzA0IVwyMTBgEFwzMDVjXDIxMFwzMDNcMzA2IVwy MTBcMzA3XDMxMFwzMTFcMzEyI1wyMDMfAFwzMDdcMzEzXDMxNFwiXDIxMFwyMDIrAFwzMTVcMzE2 IVwyMTBcMzA3XDMxMFwzMTRcMzEyI1wyMDM3AFwzMDdcMzE3IVwyMTBgEFwzMjBjXDIxMFwyMDIL AAhgfFwyMTBcMzIxIFwyMDRVAFwzMDNcMzIyIVwyMTBcMzA3XDMyM1wzMDJcMzEyI1wyMDNRAGAQ XDIwMlUACGB8XDIxMFwzMDNcMzI0IVwyMTAJXDIwM2AAXDMyNWNcMjEwXDMwN1wzMjZcMzAyXDMx MiNcMjAzcgAJXDIwM3YAXDMyN2NcMjEwXDIwMnYACGB8XDIxMFwzMzBjKVwyMDciIFtwb3NpdGlv biB2aGRsLWNvbmRpdGlvbnMtaW4tcGFyZW50aGVzaXMgbmlsIHZoZGwtaW5zZXJ0LWtleXdvcmQg IkJSRUFLIiAiICIgIkZPUiAiIHZoZGwtdGVtcGxhdGUtZmllbGQgIltxdWFudGl0eSBuYW1lXSIg IiBVU0UgIiB0ICJxdWFudGl0eSBuYW1lIiAiID0+ICIga2lsbC13b3JkIC0xICJleHByZXNzaW9u IiAiLCAiIHZoZGwtc2VxdWVudGlhbC1zdGF0ZW1lbnQtcCAiIE9OICIgIltzZW5zaXRpdml0eSBs aXN0XSIgIiBXSEVOICIgIigiICJbY29uZGl0aW9uXSIgIikiICI7Il0gNCAoIyQgLiAxNzQ1NDMp IG5pbF0pCiNAMjYgSW5zZXJ0IGEgY2FzZSBzdGF0ZW1lbnQuHwooZGVmYWxpYXMgJ3ZoZGwtdGVt cGxhdGUtY2FzZSAjWygmb3B0aW9uYWwga2luZCkgIlwzMDYgYFwzMDcYGRoLXDIwNBYAXDMxMCBc MjAzFABcMzExXDIwMhUAXDMxMhNcZlwzMTM9XDIwMzQAXDMxNB1cMzE0DiFAPVwyMDYwAA0OIVwy MTEeXCJBQCk+KVwyMDM7AFwzMTVcMzE2IVwyMTBcMjAyVgBcMzE1XDMxNyFcMjEwCWJcMjEwXDMy MFwzMjFcMzA3XDMyMiNcMjExEFwyMDRQAFwzMjNcMzI0IVwyMTBcMzI1dlwyMTBcMzI1dVwyMTBc MzIwXDMyNlwzMDdcMzIyCWAlXDIwNVwyNDUAXDMxNVwzMjcLXDMxMT1cMjAzbABcMzMwXDIwMm0A XDMzMVwzMzJRIVwyMTBcbmpcMjEwXDMxNVwzMzMhXDIxMAhcMjAzXDIwMQBcMzI3CFwyNjECXDIx MFwzMzRjXDIxMFwzMzV5XDIxMFxuDiNcXGpcMjEwXDMxNVwzMzYhXDIxMGAeJFwzMzdjXDIxMFxu DiNcXGpcMjEwXDMxNVwzNDAhXDIxMA4kYikrXDIwNyIgW2xhYmVsIHN0YXJ0IG1hcmdpbiBraW5k IHZoZGwtb3B0aW9uYWwtbGFiZWxzIHN0YW5kYXJkIGN1cnJlbnQtaW5kZW50YXRpb24gbmlsIHZo ZGwtc2VxdWVudGlhbC1zdGF0ZW1lbnQtcCBpcyB1c2UgYWxsIDg3IHZoZGwtaW5zZXJ0LWtleXdv cmQgIkNBU0UgIiAiOiBDQVNFICIgdmhkbC10ZW1wbGF0ZS1maWVsZCAiW2xhYmVsXSIgdCBkZWxl dGUtY2hhciAyIDEgImV4cHJlc3Npb24iICIgIiAiSVMiICJVU0UiICJcblxuIiAiRU5EIENBU0Ui ICI7IiAtMSAiV0hFTiAiICIgPT4gO1xuIiAiV0hFTiBPVEhFUlMgPT4gbnVsbDsiIHZoZGwtc3Rh bmRhcmQgeCB2aGRsLWJhc2ljLW9mZnNldCBwb3NpdGlvbl0gNyAoIyQgLiAxNzUyMzApIG5pbF0p CiNAMzcgSW5zZXJ0IGEgc2VxdWVudGlhbCBjYXNlIHN0YXRlbWVudC4fCihkZWZhbGlhcyAndmhk bC10ZW1wbGF0ZS1jYXNlLWlzICNbbmlsICJcMzAwXDMwMSFcMjA3IiBbdmhkbC10ZW1wbGF0ZS1j YXNlIGlzXSAyICgjJCAuIDE3NjA3OSkgbmlsXSkKI0AzOSBJbnNlcnQgYSBzaW11bHRhbmVvdXMg Y2FzZSBzdGF0ZW1lbnQuHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtY2FzZS11c2UgI1tuaWwg IlwzMDBcMzAxIVwyMDciIFt2aGRsLXRlbXBsYXRlLWNhc2UgdXNlXSAyICgjJCAuIDE3NjIyMikg bmlsXSkKI0AzMyBJbnNlcnQgYSBjb21wb25lbnQgZGVjbGFyYXRpb24uHwooZGVmYWxpYXMgJ3Zo ZGwtdGVtcGxhdGUtY29tcG9uZW50ICNbbmlsICJcMzAwIFwyMDciIFt2aGRsLXRlbXBsYXRlLWNv bXBvbmVudC1kZWNsXSAxICgjJCAuIDE3NjM2OSkgbmlsXSkKI0AxMTEgSW5zZXJ0IGEgY29tcG9u ZW50IGNvbmZpZ3VyYXRpb24gKHVzZXMgYHZoZGwtdGVtcGxhdGUtY29uZmlndXJhdGlvbi1zcGVj JwpzaW5jZSB0aGVzZSBhcmUgYWxtb3N0IGVxdWl2YWxlbnQpLh8KKGRlZmFsaWFzICd2aGRsLXRl bXBsYXRlLWNvbXBvbmVudC1jb25mICNbbmlsICJcMzAyIFwzMDNcMzA0IRgZCFwyMDUdAFwzMDVj XDIxMAlqXDIxMFwzMDZcMzA3IVwyMTAIXDMxMD1cMjA1HQBcMzExfypcMjA3IiBbcmVzdWx0IG1h cmdpbiBjdXJyZW50LWluZGVudGF0aW9uIHZoZGwtdGVtcGxhdGUtY29uZmlndXJhdGlvbi1zcGVj IHQgIlxuIiB2aGRsLWluc2VydC1rZXl3b3JkICJFTkQgRk9SOyIgbm8tdXNlIDBdIDMgKCMkIC4g MTc2NTE0KSBuaWxdKQojQDMzIEluc2VydCBhIGNvbXBvbmVudCBkZWNsYXJhdGlvbi4fCihkZWZh bGlhcyAndmhkbC10ZW1wbGF0ZS1jb21wb25lbnQtZGVjbCAjW25pbCAiXDMwNiBgXDMwN1wyMTEY GRobXDMxMFwzMTEhXDIxMFwzMTJcMzEzXDMwN1wzMTRcbmAlXDIxMRFcMjA1YwBcMzE1Y1wyMTAL alwyMTBcMzEwXDMxNiFcMjEwXDMxNxxcMzE3DUA9XDIwNjUAXGYNXDIxMR4XQUApPilcMjA0PgBc MzIwCVwyNjECXDIxMFwzMjFjXDIxMGkQXDMyMn9cMjEwCw4YXFxqXDIxMFwzMjNcMzE0XDIxMVwi XDIxMFwzMjRjXDIxMAsOGFxcalwyMTBcMzI1XDMxNCFcMjEwXDMyNnlcMjEwCHUsXDIwNyIgW2Vu ZC1jb2x1bW4gbmFtZSBzdGFydCBtYXJnaW4gc3RhbmRhcmQgdmhkbC1zdGFuZGFyZCBjdXJyZW50 LWluZGVudGF0aW9uIG5pbCB2aGRsLWluc2VydC1rZXl3b3JkICJDT01QT05FTlQgIiB2aGRsLXRl bXBsYXRlLWZpZWxkICJuYW1lIiB0ICJcblxuIiAiRU5EIENPTVBPTkVOVCIgODcgIiAiICI7IiAw IHZoZGwtdGVtcGxhdGUtZ2VuZXJpYy1saXN0ICJcbiIgdmhkbC10ZW1wbGF0ZS1wb3J0LWxpc3Qg MSB4IHZoZGwtYmFzaWMtb2Zmc2V0XSA2ICgjJCAuIDE3Njg5MCkgbmlsXSkKI0A0NSBJbnNlcnQg YSBjb21wb25lbnQgaW5zdGFudGlhdGlvbiBzdGF0ZW1lbnQuHwooZGVmYWxpYXMgJ3ZoZGwtdGVt cGxhdGUtY29tcG9uZW50LWluc3QgI1tuaWwgIlwzMDYgYFwzMDdcMjExGBkaG1wzMTBcMzExXDMw N1wzMTJcbmAlXDIwNVwyNzcAXDMxM2NcMjEwXDMxNBxcMzE0DUA9XDIwNigAXGYNXDIxMR4lQUAp PilcMjAzMwBcMzEwXDMxNSFcMjEwXDIwMlwyMDcAXDMxMFwzMTZcMzE3XDMxMiNcMjExEVwyMDY+ AFwzMjBcMjI2XDIxMRFcMzIxXDIzMlwyMDNrAFwzMTBcMzIyXDMyM1wzMDdcMjExXDIxMVwyMTFc MzI0JgdcMjEwXDMxMFwzMjVcMzI2XCJcMjEwXDMxMFwzMjdcMzA3XDMxMiNcMjAzZABcMzMwY1wy MTBcMjAyXDIwNwBcMzMxXDMzMiFcMjEwXDIwMlwyMDcACVwzMzNcMjMyXDIwM1wyMDMAXDMxMFwz MjJcMzIzXDMwN1wyMTFcMjExXDIxMVwzMjQmB1wyMTBcMzEwXDMzNCFcMjEwXDIwMlwyMDcAXDMx MFwzMTUhXDIxMFwzMzVjXDIxMAsOJlxcalwyMTBgEFwzMzZcMzM3IVwyMTBcMzQwCFwzMTJcMjEx I1wyMDNcMjQ3AFwzMzVjXDIxMAsOJlxcalwyMTBgEFwzMzZcMzQxIVwyMTBcMzQwCFwzMTJcMjEx I1wyMDRcMjc1AFwzNDJcMzQzIVwyMTBcMzMxXDMzMiFcMjEwXDM0NGMsXDIwNyIgW3Bvc2l0aW9u IHVuaXQgc3RhcnQgbWFyZ2luIHN0YW5kYXJkIHZoZGwtc3RhbmRhcmQgY3VycmVudC1pbmRlbnRh dGlvbiBuaWwgdmhkbC10ZW1wbGF0ZS1maWVsZCAiaW5zdGFuY2UgbGFiZWwiIHQgIjogIiA4NyAi Y29tcG9uZW50IG5hbWUiICJbQ09NUE9ORU5UIHwgRU5USVRZIHwgQ09ORklHVVJBVElPTl0iICIg IiAiIiAiRU5USVRZIiAibGlicmFyeSBuYW1lIiAiLiIgIndvcmsiICJlbnRpdHkgbmFtZSIgIigi ICJbYXJjaGl0ZWN0dXJlIG5hbWVdIiAiKSIgZGVsZXRlLWNoYXIgLTEgIkNPTkZJR1VSQVRJT04i ICJjb25maWd1cmF0aW9uIG5hbWUiICJcbiIgdmhkbC1pbnNlcnQta2V5d29yZCAiR0VORVJJQyAi IHZoZGwtdGVtcGxhdGUtbWFwICJQT1JUICIga2lsbC1saW5lIDAgIjsiIHggdmhkbC1iYXNpYy1v ZmZzZXRdIDkgKCMkIC4gMTc3NDkxKSBuaWxdKQojQDQxIEluc2VydCBhIGNvbmRpdGlvbmFsIHNp Z25hbCBhc3NpZ25tZW50Lh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWNvbmRpdGlvbmFsLXNp Z25hbC1hc3N0ICNbbmlsICJcMzA1XDMwNiFcMjA1ZABcMzA3Y1wyMTBpYFwzMTAYGRpcMzA1XDMx MSFcMjEwYBBcMzEyXDMxMyFcMjEwC1wyMDMgAFwzMTRjXDIxMFwzMDVcMzE1XDMxMFwzMTYjXDIw M1MAC1wyMDMvAFwzMTdjXDIxMGAQXDMxMlwzMjAhXDIxMFwzMjFjXDIxMFxualwyMTBcMzA1XDMy MlwzMTBcMzE2I1wyMDNTAGAQXDMxMlwzMTMhXDIxMAtcMjAzIABcMzE0Y1wyMTBcMjAyIAAIYHxc MjEwXDMyM2NcMjEwXGZcMjA1YwBcMzI0CWBcMzI1IytcMjA3IiBbcG9zaXRpb24gc3RhcnQgbWFy Z2luIHZoZGwtY29uZGl0aW9ucy1pbi1wYXJlbnRoZXNpcyB2aGRsLWF1dG8tYWxpZ24gdmhkbC10 ZW1wbGF0ZS1maWVsZCAidGFyZ2V0IHNpZ25hbCIgIiA8PSAiIG5pbCAid2F2ZWZvcm0iIHZoZGwt aW5zZXJ0LWtleXdvcmQgIiBXSEVOICIgIigiICJbY29uZGl0aW9uXSIgdCAiKSIgIiBFTFNFIiAi XG4iICJbd2F2ZWZvcm1dIiAiOyIgdmhkbC1hbGlnbi1ub2luZGVudC1yZWdpb24gMV0gNCAoIyQg LiAxNzg1NTgpIG5pbF0pCiNAMTk2IEluc2VydCBhIGNvbmZpZ3VyYXRpb24gc3BlY2lmaWNhdGlv biBpZiB3aXRoaW4gYW4gYXJjaGl0ZWN0dXJlLAphIGJsb2NrIG9yIGNvbXBvbmVudCBjb25maWd1 cmF0aW9uIGlmIHdpdGhpbiBhIGNvbmZpZ3VyYXRpb24gZGVjbGFyYXRpb24sCmEgY29uZmlndXJh dGlvbiBkZWNsYXJhdGlvbiBpZiBub3Qgd2l0aGluIGEgZGVzaWduIHVuaXQuHwooZGVmYWxpYXMg J3ZoZGwtdGVtcGxhdGUtY29uZmlndXJhdGlvbiAjW25pbCAiXDMwNBhcMzA1GVwzMDZcMzA3XDMx MFxuI1wyMTBcMjEyXDMxMVwzMTJcMzA1XDMwNCMpXDIwM1wiAFwzMTNcMzE0IVwyMjZcMzE1XDIz MlwyMDNcIgBcMzE2IFwyMDJLAFwyMTJcMzExXDMxN1wzMDVcMzA0IylcMjAzSQBcMzEzXDMxNCFc MjI2XDMyMFwyMzJcMjAzSQBcMzIxXDMyMlwzMjNcMzA0I1wzMjQ9XDIwM0QAXDMyNSBcMjAySwBc MzI2IFwyMDJLAFwzMjcgEQtcMjA0VgBcMzA2XDMwN1wzMzBcbiNcMjEwCSpcMjA3IiBbY2FzZS1m b2xkLXNlYXJjaCByZXN1bHQgdmhkbC1tb2RlLXN5bnRheC10YWJsZSB2aGRsLXVuZGVyc2NvcmUt aXMtcGFydC1vZi13b3JkIHQgbmlsIG1vZGlmeS1zeW50YXgtZW50cnkgOTUgInciIHJlLXNlYXJj aC1iYWNrd2FyZCAiXlxcKGFyY2hpdGVjdHVyZVxcfGVuZFxcKVxcPiIgbWF0Y2gtc3RyaW5nIDEg IkFSQ0hJVEVDVFVSRSIgdmhkbC10ZW1wbGF0ZS1jb25maWd1cmF0aW9uLXNwZWMgIl5cXChjb25m aWd1cmF0aW9uXFx8ZW5kXFwpXFw+IiAiQ09ORklHVVJBVElPTiIgdmhkbC1kZWNpc2lvbi1xdWVy eSAiY29uZmlndXJhdGlvbiIgIihiKWxvY2sgb3IgKGMpb21wb25lbnQgY29uZmlndXJhdGlvbj8i IDk5IHZoZGwtdGVtcGxhdGUtY29tcG9uZW50LWNvbmYgdmhkbC10ZW1wbGF0ZS1ibG9jay1jb25m aWd1cmF0aW9uIHZoZGwtdGVtcGxhdGUtY29uZmlndXJhdGlvbi1kZWNsICJfIl0gNCAoIyQgLiAx NzkxNzMpIG5pbF0pCiNAMzkgSW5zZXJ0IGEgY29uZmlndXJhdGlvbiBzcGVjaWZpY2F0aW9uLh8K KGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWNvbmZpZ3VyYXRpb24tc3BlYyAjWygmb3B0aW9uYWwg b3B0aW9uYWwtdXNlKSAiXDMwNiBgXDMwN1wyMTEYGRobXDMxMFwzMTEhXDIxMFwzMTJcMzEzXDMx NFwzMTVcbmAlXDIwNVwzMzAAXDMxMlwzMTZcMzE3XCJcMjEwC1xmXFxqXDIxMGASXDMxMFwzMjAh XDIxMA1cMjAzPQBcMzEyXDMyMVwzMjJcMzE1I1wyMTERXDIwND0AXG5gfFwyMTBcMzIzXDIwMlwz MzAADVwyMDRGAFwzMTJcMzI0XDMyMlwiEQlcMjA2SwBcMzI1XDIyNlwyMTERXDMyNlwyMzJcMjAz XDI3MABcMzEyXDMyN1wzMzBcMzA3XDIxMVwyMTFcMjExXDMzMSYHXDIxMFwzMTJcMzMyXDMzM1wi XDIxMFwzMTJcMzM0XDMwN1wzMTUjXDIwM3EAXDMzNWNcMjEwXDIwMnUAXDMzNlwzMzchXDIxMFwz MTdjXDIxMAtcZlwyMTFcXFwzNDBcXFxcalwyMTBgEFwzMTBcMzQxIVwyMTBcMzQyCFwzMTVcMjEx I1wyMDNcMjMzAFwzMTdjXDIxMAtcZlwyMTFcXFwzNDBcXFxcalwyMTBgEFwzMTBcMzQzIVwyMTBc MzQyCFwzMTVcMjExI1wyMDRcMjYxAFwzNDRcMzQwIVwyMTBcMzM2XDMzNyFcMjEwXDM0NWNcMjEw XDMxNVwyMDJcMzMwAAlcMzQ2XDIzMlwyMDNcMzIwAFwzMTJcMzI3XDMzMFwzMDdcMjExXDIxMVwy MTFcMzMxJgdcMjEwXDMxMlwzNDdcMzQ1XCJcMjAyXDMzMABcMzUwXDM1MSFcMjEwXDM0NWNcMjEw XDMxNSxcMjA3IiBbcG9zaXRpb24gYXNwZWN0IHN0YXJ0IG1hcmdpbiB2aGRsLWJhc2ljLW9mZnNl dCBvcHRpb25hbC11c2UgY3VycmVudC1pbmRlbnRhdGlvbiBuaWwgdmhkbC1pbnNlcnQta2V5d29y ZCAiRk9SICIgdmhkbC10ZW1wbGF0ZS1maWVsZCAiY29tcG9uZW50IG5hbWVzIHwgT1RIRVJTIHwg QUxMIiAiIDogIiB0ICJjb21wb25lbnQgdHlwZSIgIlxuIiAiVVNFICIgIltFTlRJVFkgfCBDT05G SUdVUkFUSU9OIHwgT1BFTl0iICIgIiBuby11c2UgIkVOVElUWSB8IENPTkZJR1VSQVRJT04gfCBP UEVOIiAiIiAiRU5USVRZIiAibGlicmFyeSBuYW1lIiAiLiIgIndvcmsiICJlbnRpdHkgbmFtZSIg IigiICJbYXJjaGl0ZWN0dXJlIG5hbWVdIiAiKSIgZGVsZXRlLWNoYXIgLTEgMCAiR0VORVJJQyAi IHZoZGwtdGVtcGxhdGUtbWFwICJQT1JUICIga2lsbC1saW5lICI7IiAiQ09ORklHVVJBVElPTiIg ImNvbmZpZ3VyYXRpb24gbmFtZSIgYmFja3dhcmQtZGVsZXRlLWNoYXIgMV0gOSAoIyQgLiAxODAx MzgpIG5pbF0pCiNAMzcgSW5zZXJ0IGEgY29uZmlndXJhdGlvbiBkZWNsYXJhdGlvbi4fCihkZWZh bGlhcyAndmhkbC10ZW1wbGF0ZS1jb25maWd1cmF0aW9uLWRlY2wgI1tuaWwgIlwzMDYgYFwzMDdc MzEwXDIxMVwyMTFcMjExGBkaGxwdHh9cMzExXDMxMiFcMjEwXDMxM1wzMTRcMzEwXDMwNw1gJVwy MTERXDIwNVwyNTYAXDMxMVwzMTUhXDIxMFwyMTJcMzEwHiBcMzE2XDMxN1wzMjAOISNcMjEwXDMy MVwzMjJcMzEwXDMwNyMTXDMyM1wzMjQhXDIxMRIWIA5cIlwyMDRIAFwzMTZcMzE3XDMyNQ4hI1wy MTAqC1wyMDNZAFxuXDMyNlwyMzJcMjA0WQBcbmNcMjEwXDIwMl0AXDMxM1wzMjchXDIxMFwzMTFc MzMwIVwyMTAOI1wzMzE+XDIwM2sAXDMzMmNcMjEwDh8OJFxcalwyMTBgEFwzMzJjXDIxMA4jXDMz Mz5cMjAzXDIwMQBcMzMyY1wyMTAOH2pcMjEwXDMxMVwzMzQhXDIxMFwzMzUeJVwzMzUOJkA9XDIw NlwyMzcADiUOJlwyMTEeJ0FAKT4pXDIwNFwyNDcAXDMxMVwzMTIhXDIxMAlcMzM2XDI2MQJcMjEw CGIuB1wyMDciIFtwb3NpdGlvbiBuYW1lIHN0cmluZyBlbnRpdHktZXhpc3RzIGNhc2UtZm9sZC1z ZWFyY2ggc3RhcnQgY3VycmVudC1pbmRlbnRhdGlvbiB0IG5pbCB2aGRsLWluc2VydC1rZXl3b3Jk ICJDT05GSUdVUkFUSU9OICIgdmhkbC10ZW1wbGF0ZS1maWVsZCAibmFtZSIgIiBPRiAiIG1vZGlm eS1zeW50YXgtZW50cnkgOTUgInciIHJlLXNlYXJjaC1iYWNrd2FyZCAiXFw8ZW50aXR5IFxcKFxc dypcXCkgaXNcXD4iIG1hdGNoLXN0cmluZyAxICJfIiAiIiAiZW50aXR5IG5hbWUiICIgSVNcbiIg KHVuaXQgYWxsKSAiXG4iICh1bml0IGFsbCkgIkVORCAiIDg3ICI7IiBtYXJnaW4gcmVzdWx0IHZo ZGwtbW9kZS1zeW50YXgtdGFibGUgdmhkbC11bmRlcnNjb3JlLWlzLXBhcnQtb2Ytd29yZCB2aGRs LWluc2VydC1lbXB0eS1saW5lcyB2aGRsLWJhc2ljLW9mZnNldCBzdGFuZGFyZCB2aGRsLXN0YW5k YXJkIHhdIDcgKCMkIC4gMTgxMzg5KSBuaWxdKQojQDMyIEluc2VydCBhIGNvbnN0YW50IGRlY2xh cmF0aW9uLh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWNvbnN0YW50ICNbbmlsICJgXDMwMyAY GVwzMDRcMzA1IVwyMTBcMzA2XDMwN1wzMTBcMzExCWAlXDIwNUUAXDMxMmNcMjEwCFwyMDMeAFwz MDRcMzEzIVwyMTBcMzA2XDMxNCFcMjEwCFwyMDMuAFwzMTVjXDIxMFwzMTYgXDIwMkUAYBpcMzE3 Y1wyMTBcMzA2XDMyMFwzMTBcMzExI1wyMDQ/AFxuYHxcMjEwXDMxNWNcMjEwXDMxNiApKlwyMDci IFtpbi1hcmdsaXN0IHN0YXJ0IHBvc2l0aW9uIHZoZGwtaW4tYXJndW1lbnQtbGlzdC1wIHZoZGwt aW5zZXJ0LWtleXdvcmQgIkNPTlNUQU5UICIgdmhkbC10ZW1wbGF0ZS1maWVsZCAibmFtZSIgbmls IHQgIiA6ICIgIklOICIgInR5cGUiICI7IiB2aGRsLWNvbW1lbnQtaW5zZXJ0LWlubGluZSAiIDo9 ICIgIltpbml0aWFsaXphdGlvbl0iXSA2ICgjJCAuIDE4MjM3NykgbmlsXSkKI0AxNyBJbnNlcnQg bm90aGluZy4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1kZWZhdWx0ICNbbmlsICJcMzAwY1wy MTBcMzAxIFwyMTBcMzAyXDMwMyFcMjEwXDMwNFwzMDMhXDIxMFwzMDN1XDIwNyIgWyIgIiB1bmV4 cGFuZC1hYmJyZXYgYmFja3dhcmQtd29yZCAxIHZoZGwtY2FzZS13b3JkXSAyICgjJCAuIDE4Mjg0 OSkgbmlsXSkKI0AyOCBJbnNlcnQgbm90aGluZyBhbmQgaW5kZW50Lh8KKGRlZmFsaWFzICd2aGRs LXRlbXBsYXRlLWRlZmF1bHQtaW5kZW50ICNbbmlsICJcMzAwY1wyMTBcMzAxIFwyMTBcMzAyXDMw MyFcMjEwXDMwNFwzMDMhXDIxMFwzMDN1XDIxMFwzMDUgXDIwNyIgWyIgIiB1bmV4cGFuZC1hYmJy ZXYgYmFja3dhcmQtd29yZCAxIHZoZGwtY2FzZS13b3JkIHZoZGwtaW5kZW50LWxpbmVdIDIgKCMk IC4gMTgzMDQxKSBuaWxdKQojQDMyIEluc2VydCBhIGRpc2Nvbm5lY3Qgc3RhdGVtZW50Lh8KKGRl ZmFsaWFzICd2aGRsLXRlbXBsYXRlLWRpc2Nvbm5lY3QgI1tuaWwgImAYXDMwMVwzMDIhXDIxMFwz MDNcMzA0XDMwNVwzMDYIYCVcMjA1HABcMzAzXDMwNyFcMjEwXDMwMVwzMTAhXDIxMFwzMDNcMzEx XDMxMlwiKVwyMDciIFtzdGFydCB2aGRsLWluc2VydC1rZXl3b3JkICJESVNDT05ORUNUICIgdmhk bC10ZW1wbGF0ZS1maWVsZCAic2lnbmFsIG5hbWVzIHwgT1RIRVJTIHwgQUxMIiAiIDogIiB0ICJ0 eXBlIiAiIEFGVEVSICIgInRpbWUgZXhwcmVzc2lvbiIgIjsiXSA2ICgjJCAuIDE4MzI3Nykgbmls XSkKI0AyNyBJbnNlcnQgYW4gZWxzZSBzdGF0ZW1lbnQuHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxh dGUtZWxzZSAjW25pbCAiXDMwNlwzMDcYGVwzMDcaXDMxMFwzMTFcMzEyCyNcMjEwXDMxM1wzMTQh XDIxMFwyMTJcMzE1XDMxNlwzMDdcMzA2I1wyMTBcMzE3XDMyMCFcMjI2XDMyMVwyMzIpXDIwMyYA XDMyMmNcMjAyMwBcMzIzIFwyMTBcMzI0IBBcMzI1Y1wyMTAIXGZcXGoSDVwyMDQ+AFwzMTBcMzEx XDMyNgsjXDIxMFxuK1wyMDciIFttYXJnaW4gY2FzZS1mb2xkLXNlYXJjaCByZXN1bHQgdmhkbC1t b2RlLXN5bnRheC10YWJsZSB2aGRsLWJhc2ljLW9mZnNldCB2aGRsLXVuZGVyc2NvcmUtaXMtcGFy dC1vZi13b3JkIHQgbmlsIG1vZGlmeS1zeW50YXgtZW50cnkgOTUgInciIHZoZGwtaW5zZXJ0LWtl eXdvcmQgIkVMU0UiIHJlLXNlYXJjaC1iYWNrd2FyZCAiXFwoXFw8d2hlblxcPlxcfDtcXCkiIG1h dGNoLXN0cmluZyAxICJXSEVOIiAiICIgdmhkbC1pbmRlbnQtbGluZSBjdXJyZW50LWluZGVudGF0 aW9uICJcbiIgIl8iXSA0ICgjJCAuIDE4MzYwNSkgbmlsXSkKI0AyOCBJbnNlcnQgYW4gZWxzaWYg c3RhdGVtZW50Lh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWVsc2lmICNbbmlsICJgXDMwNBgZ XDMwNVwzMDYhXDIxMFxuXDIwMw8AXDMwN2NcMjEwXDMxMFwzMTFcMzA0XDMxMglgJVwyMDU6AFxu XDIwMyAAXDMxM2NcMjEwXDMxNCBcMjEwXDMxNSAQXDMwNVwzMTZcMzE3IFwyMDMxAFwzMjBcMjAy MgBcMzIxXDMyMlEhXDIxMAgLXFxqKlwyMDciIFttYXJnaW4gc3RhcnQgdmhkbC1jb25kaXRpb25z LWluLXBhcmVudGhlc2lzIHZoZGwtYmFzaWMtb2Zmc2V0IG5pbCB2aGRsLWluc2VydC1rZXl3b3Jk ICJFTFNJRiAiICIoIiB2aGRsLXRlbXBsYXRlLWZpZWxkICJjb25kaXRpb24iIHQgIikiIHZoZGwt aW5kZW50LWxpbmUgY3VycmVudC1pbmRlbnRhdGlvbiAiICIgdmhkbC1zZXF1ZW50aWFsLXN0YXRl bWVudC1wICJUSEVOIiAiVVNFIiAiXG4iXSA2ICgjJCAuIDE4NDE1MSkgbmlsXSkKI0AxOSBJbnNl cnQgYW4gZW50aXR5Lh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWVudGl0eSAjW25pbCAiXDMw NiBgXDMwN1wyMTEYGRobXDMxMFwzMTEhXDIxMFwzMTJcMzEzXDMwN1wzMTRcbmAlXDIxMRFcMjA1 XDIxNABcMzEwXDMxNSFcMjEwC2pcMjEwXDMxMFwzMTYhXDIxMFwzMTccXDMxNw1APVwyMDY2AFxm DVwyMTEeGUFAKT4pXDIwND4AXDMxMFwzMTEhXDIxMAlcMzIwXDI2MQJcMjEwaRBcMzIxf1wyMTAL DhpcXGpcMjEwDhtcMzIyPlwyMDNYAFwzMjNjXDIxMAsOGlxcalwyMTBcMzI0XDMxNCFcMjAzbgAO G1wzMjU+XDIwM24AXDMyM2NcMjEwXDMyM2NcMjEwCw4aXFxqXDIxMFwzMjZcMzE0IVwyMDNcMjA3 AA4bXDMyNz5cMjAzXDIwNwBcMzIzY1wyMTBcMzMweVwyMTAIdSxcMjA3IiBbZW5kLWNvbHVtbiBu YW1lIHN0YXJ0IG1hcmdpbiBzdGFuZGFyZCB2aGRsLXN0YW5kYXJkIGN1cnJlbnQtaW5kZW50YXRp b24gbmlsIHZoZGwtaW5zZXJ0LWtleXdvcmQgIkVOVElUWSAiIHZoZGwtdGVtcGxhdGUtZmllbGQg Im5hbWUiIHQgIiBJU1xuXG4iICJFTkQgIiA4NyAiOyIgMCAodW5pdCBhbGwpICJcbiIgdmhkbC10 ZW1wbGF0ZS1nZW5lcmljLWxpc3QgKHVuaXQgYWxsKSB2aGRsLXRlbXBsYXRlLXBvcnQtbGlzdCAo dW5pdCBhbGwpIDEgeCB2aGRsLWJhc2ljLW9mZnNldCB2aGRsLWluc2VydC1lbXB0eS1saW5lc10g NiAoIyQgLiAxODQ2MTkpIG5pbF0pCiNAMjcgSW5zZXJ0IGFuIGV4aXQgc3RhdGVtZW50Lh8KKGRl ZmFsaWFzICd2aGRsLXRlbXBsYXRlLWV4aXQgI1tuaWwgImAYXDMwM1wzMDQhXDIxMFwzMDVcMzA2 XDMwN1wzMTAjXDIwNBIAXDMxMVwzMTIhXDIxMGAZXDMwM1wzMTMhXDIxMFxuXDIwMx8AXDMxNGNc MjEwXDMwNVwzMTVcMzA3XDMxMCNcMjAzMQBcblwyMDM1AFwzMTZjXDIxMFwyMDI1AAlgfFwyMTAp XDMxN2MpXDIwNyIgW3N0YXJ0IHBvc2l0aW9uIHZoZGwtY29uZGl0aW9ucy1pbi1wYXJlbnRoZXNp cyB2aGRsLWluc2VydC1rZXl3b3JkICJFWElUICIgdmhkbC10ZW1wbGF0ZS1maWVsZCAiW2xvb3Ag bGFiZWxdIiBuaWwgdCBkZWxldGUtY2hhciAtMSAiIFdIRU4gIiAiKCIgIltjb25kaXRpb25dIiAi KSIgIjsiXSA0ICgjJCAuIDE4NTMzNCkgbmlsXSkKI0AyOCBJbnNlcnQgYSBmaWxlIGRlY2xhcmF0 aW9uLh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWZpbGUgI1tuaWwgImAYXDMwNFwzMDUhXDIx MFwzMDZcMzA3XDMxMFwzMTEIYCVcMjA1agBcMzEyY1wyMTBcMzA2XDMxMyFcMjEwXDMxNBlcMzE0 XG5APVwyMDYoAAlcblwyMTEbQUApPilcMjA0PABcMzA0XDMxNSFcMjEwXDMwNlwzMTZcMzEwXDMx MSNcMjA0PABcMzE3XDMyMCFcMjEwXDMwNFwzMjEhXDIxMFwzMTQZXDMxNFxuQD1cMjA2UQAJXG5c MjExG0FAKT4pXDIwM1sAXDMwNlwzMjJcMzIzXDMxMSNcMjEwXDMwNlwzMjRcMzEwXDIxMVwyMTFc MjExXDMxMSYGXDIxMFwzMjVjXDIxMFwzMjYgKVwyMDciIFtzdGFydCBzdGFuZGFyZCB2aGRsLXN0 YW5kYXJkIHggdmhkbC1pbnNlcnQta2V5d29yZCAiRklMRSAiIHZoZGwtdGVtcGxhdGUtZmllbGQg Im5hbWUiIG5pbCB0ICIgOiAiICJ0eXBlIiA4NyAiIE9QRU4gIiAiW1JFQURfTU9ERSB8IFdSSVRF X01PREUgfCBBUFBFTkRfTU9ERV0iIGJhY2t3YXJkLWRlbGV0ZS1jaGFyIDYgIiBJUyAiICJbSU4g fCBPVVRdIiAiICIgImZpbGVuYW1lLXN0cmluZyIgIjsiIHZoZGwtY29tbWVudC1pbnNlcnQtaW5s aW5lXSA3ICgjJCAuIDE4NTc0MSkgbmlsXSkKI0AyMTIgSW5zZXJ0IGEgYmxvY2sgb3IgY29tcG9u ZW50IGNvbmZpZ3VyYXRpb24gaWYgd2l0aGluIGEgY29uZmlndXJhdGlvbgpkZWNsYXJhdGlvbiwg YSBjb25maWd1cmF0aW9uIHNwZWNpZmljYXRpb24gaWYgd2l0aGluIGFuIGFyY2hpdGVjdHVyZQpk ZWNsYXJhdGl2ZSBwYXJ0IChhbmQgbm90IHdpdGhpbiBhIHN1YnByb2dyYW0pLCBhbmQgYSBmb3It bG9vcCBvdGhlcndpc2UuHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtZm9yICNbbmlsICJcMzA0 GFwzMDUZXDMwNlwzMDdcMzEwXG4jXDIxMFwyMTJcMzExXDMxMlwzMDVcMzA0IylcMjAzMQBcMzEz XDMxNCFcMjI2XDMxNVwyMzJcMjAzMQBcMzE2XDMxN1wzMjBcMzA0I1wzMjE9XDIwMywAXDMyMiBc MjAycgBcMzIzIFwyMDJyAFwyMTJcMzExXDMyNFwzMDVcMzA0IylcMjAzZgBcMzEzXDMxNCFcMjI2 XDMyNVwyMzJcMjAzZgBcMjEyXDMxMVwzMjZcMzA1XDMwNCMpXDIwM2EAXDMxM1wzMTQhXDIyNlwz MjdcMjMyXDIwM2EAXDIxMlwzMTFcMzMwXDMwNVwzMDQjKVwyMDRmAFwzMzEgXDIwMnIAXDMzMiBc MjAzcABcMzMzIFwyMDJyAFwzMzQgEQtcMjA0fQBcMzA2XDMwN1wzMzVcbiNcMjEwCSpcMjA3IiBb Y2FzZS1mb2xkLXNlYXJjaCByZXN1bHQgdmhkbC1tb2RlLXN5bnRheC10YWJsZSB2aGRsLXVuZGVy c2NvcmUtaXMtcGFydC1vZi13b3JkIHQgbmlsIG1vZGlmeS1zeW50YXgtZW50cnkgOTUgInciIHJl LXNlYXJjaC1iYWNrd2FyZCAiXlxcKGNvbmZpZ3VyYXRpb25cXHxlbmRcXClcXD4iIG1hdGNoLXN0 cmluZyAxICJDT05GSUdVUkFUSU9OIiB2aGRsLWRlY2lzaW9uLXF1ZXJ5ICJmb3IiICIoYilsb2Nr IG9yIChjKW9tcG9uZW50IGNvbmZpZ3VyYXRpb24/IiA5OSB2aGRsLXRlbXBsYXRlLWNvbXBvbmVu dC1jb25mIHZoZGwtdGVtcGxhdGUtYmxvY2stY29uZmlndXJhdGlvbiAiXlxcKGFyY2hpdGVjdHVy ZVxcfGVudGl0eVxcfGJlZ2luXFx8ZW5kXFwpXFw+IiAiQVJDSElURUNUVVJFIiAiXlxccy0qXFwo YXJjaGl0ZWN0dXJlXFx8YmVnaW5cXHxlbmRcXClcXD4iICJCRUdJTiIgIl5cXHMtKlxcKGZ1bmN0 aW9uXFx8cHJvY2VkdXJlXFwpXFw+IiB2aGRsLXRlbXBsYXRlLWNvbmZpZ3VyYXRpb24tc3BlYyB2 aGRsLXNlcXVlbnRpYWwtc3RhdGVtZW50LXAgdmhkbC10ZW1wbGF0ZS1mb3ItbG9vcCB2aGRsLXRl bXBsYXRlLWZvci1nZW5lcmF0ZSAiXyJdIDQgKCMkIC4gMTg2MzY2KSBuaWxdKQojQDI0IEluc2Vy dCBhIGZvci1nZW5lcmF0ZS4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1mb3ItZ2VuZXJhdGUg I1tuaWwgIlwzMDUgYFwzMDZcMjExXDIxMRgZGhscXDMwN1wzMTAhXDIxMFwzMTEgEAtiXDIxMFwz MTJcMzEzXDMwNlwzMTQLCCVcMjExElwyMDU0AAhiXDIxMFwzMTJcMzE1IVwyMTBcMzA3XDMxNiFc MjEwXDMxMlwzMTchXDIxMFwzMjBcZlxuXCItXDIwNyIgW3Bvc2l0aW9uIHN0cmluZyBsYWJlbCBz dGFydCBtYXJnaW4gY3VycmVudC1pbmRlbnRhdGlvbiBuaWwgdmhkbC1pbnNlcnQta2V5d29yZCAi OiBGT1IgIiBwb2ludC1tYXJrZXIgdmhkbC10ZW1wbGF0ZS1maWVsZCAibGFiZWwiIHQgImxvb3Ag dmFyaWFibGUiICIgSU4gIiAicmFuZ2UiIHZoZGwtdGVtcGxhdGUtZ2VuZXJhdGUtYm9keV0gNiAo IyQgLiAxODc1ODIpIG5pbF0pCiNAMjAgSW5zZXJ0IGEgZm9yIGxvb3AuHwooZGVmYWxpYXMgJ3Zo ZGwtdGVtcGxhdGUtZm9yLWxvb3AgI1tuaWwgIlwzMDYgYFwzMDdcMjExGBkaG1xmXDMxMD1cMjA0 FgBcMzExXDMxMiFcMjEwXDIwMjEAXDMxMVwzMTMhXDIxMFxuYlwyMTBcMzE0XDMxNVwzMDdcMzE2 I1wyMTERXDIwNCsAXDMxN1wzMjAhXDIxMFwzMjF2XDIxMFwzMjF1XDIxMFwzMTRcMzIyXDMwN1wz MTZcbmAlXDIxMRBcMjA1cQBcMzExXDMyMyFcMjEwXDMxNFwzMjQhXDIxMFwzMTFcMzI1IVwyMTAL alwyMTBcMzExXDMyNiFcMjEwCVwyMDNdAFwzMjcJXDMzMFwyNjEDXDIxMFwyMDJpAFwzMzBjXDIx MA1cMjAzaQBcMzMxCFwyNjECXDIxMFwzMzJ5XDIxMAsOG1xcaixcMjA3IiBbaW5kZXggbGFiZWwg c3RhcnQgbWFyZ2luIHZoZGwtb3B0aW9uYWwtbGFiZWxzIHZoZGwtc2VsZi1pbnNlcnQtY29tbWVu dHMgY3VycmVudC1pbmRlbnRhdGlvbiBuaWwgYWxsIHZoZGwtaW5zZXJ0LWtleXdvcmQgIkZPUiAi ICI6IEZPUiAiIHZoZGwtdGVtcGxhdGUtZmllbGQgIltsYWJlbF0iIHQgZGVsZXRlLWNoYXIgMiAx ICJsb29wIHZhcmlhYmxlIiAiIElOICIgInJhbmdlIiAiIExPT1BcblxuIiAiRU5EIExPT1AiICIg IiAiOyIgIiAgLS0gIiAtMSB2aGRsLWJhc2ljLW9mZnNldF0gNyAoIyQgLiAxODgwMTApIG5pbF0p CiNAMjggSW5zZXJ0IGEgVkhETCBmaWxlIGZvb3Rlci4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0 ZS1mb290ZXIgI1tuaWwgIghcMzAxXDIzMj9cMjA1EgBcMjEyZGJcMjEwXDMwMmNcMjEwXDMwMwgh KVwyMDciIFt2aGRsLWZpbGUtZm9vdGVyICIiICJcbiIgdmhkbC1pbnNlcnQtc3RyaW5nLW9yLWZp bGVdIDIgKCMkIC4gMTg4Njc2KSBuaWxdKQojQDQwIEluc2VydCBhIGZ1bmN0aW9uIGRlY2xhcmF0 aW9uIG9yIGJvZHkuHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtZnVuY3Rpb24gI1soJm9wdGlv bmFsIGtpbmQpICJcMzA2IGBcMzA3GBkaXDMxMFwzMTEhXDIxMFwzMTJcMzEzXDMwN1wzMTQJYCVc MjExEFwyMDV3AFwzMTVcMzE0IVwyMTALXDIwMyUAXDMxNglgXDMxNyNcMjEwXDMwN39cMjEwXDMy MGNcMjEwXG5cZlxcalwyMTBcMzEwXDMyMSFcMjEwXDMxMlwzMjIhXDIxMA1cMjAzQgANXDMyMz1c MjAySABcMzI0XDMwN1wzMjVcIlwzMjY9XDIwM3UAXDMxMFwzMjchXDIxMFwzMzBcMzMxHh1cMzMx Dh5APVwyMDZmAA4dDh5cMjExHh9BQCk+KT9cMjA1bABcMzMyCFxuI1wyMTBcMzMzIFwyMDJ3AFwz MzRjK1wyMDciIFtuYW1lIHN0YXJ0IG1hcmdpbiB2aGRsLWF1dG8tYWxpZ24gdmhkbC1iYXNpYy1v ZmZzZXQga2luZCBjdXJyZW50LWluZGVudGF0aW9uIG5pbCB2aGRsLWluc2VydC1rZXl3b3JkICJG VU5DVElPTiAiIHZoZGwtdGVtcGxhdGUtZmllbGQgIm5hbWUiIHQgdmhkbC10ZW1wbGF0ZS1hcmd1 bWVudC1saXN0IHZoZGwtYWxpZ24tbm9pbmRlbnQtcmVnaW9uIDEgIlxuIiAiUkVUVVJOICIgInR5 cGUiIGJvZHkgdmhkbC1kZWNpc2lvbi1xdWVyeSAiKGQpZWNsYXJhdGlvbiBvciAoYilvZHk/IiA5 OCAiIElTIiB2aGRsLXRlbXBsYXRlLWJlZ2luLWVuZCA4NyAiRlVOQ1RJT04iIHZoZGwtY29tbWVu dC1ibG9jayAiOyIgc3RhbmRhcmQgdmhkbC1zdGFuZGFyZCB4XSA2ICgjJCAuIDE4ODg3Mikgbmls XSkKI0AzMiBJbnNlcnQgYSBmdW5jdGlvbiBkZWNsYXJhdGlvbi4fCihkZWZhbGlhcyAndmhkbC10 ZW1wbGF0ZS1mdW5jdGlvbi1kZWNsICNbbmlsICJcMzAwXDMwMSFcMjA3IiBbdmhkbC10ZW1wbGF0 ZS1mdW5jdGlvbiBkZWNsXSAyICgjJCAuIDE4OTY0NykgbmlsXSkKI0AzMiBJbnNlcnQgYSBmdW5j dGlvbiBkZWNsYXJhdGlvbi4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1mdW5jdGlvbi1ib2R5 ICNbbmlsICJcMzAwXDMwMSFcMjA3IiBbdmhkbC10ZW1wbGF0ZS1mdW5jdGlvbiBib2R5XSAyICgj JCAuIDE4OTc5NykgbmlsXSkKI0AyOSBJbnNlcnQgYSBnZW5lcmF0aW9uIHNjaGVtZS4fCihkZWZh bGlhcyAndmhkbC10ZW1wbGF0ZS1nZW5lcmF0ZSAjW25pbCAiXDMwMFwzMDFcMzAyXDMwMyNcMzA0 PVwyMDMNAFwzMDUgXDIwN1wzMDYgXDIwNyIgW3ZoZGwtZGVjaXNpb24tcXVlcnkgbmlsICIoZilv ciBvciAoaSlmPyIgdCAxMDUgdmhkbC10ZW1wbGF0ZS1pZi1nZW5lcmF0ZSB2aGRsLXRlbXBsYXRl LWZvci1nZW5lcmF0ZV0gNCAoIyQgLiAxODk5NDcpIG5pbF0pCiNANzMgSW5zZXJ0IGdlbmVyaWMg ZGVjbGFyYXRpb24sIG9yIGdlbmVyaWMgbWFwIGluIGluc3RhbnRpYXRpb24gc3RhdGVtZW50cy4f CihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1nZW5lcmljICNbbmlsICJgXDMwNRgZXDMwNhpcMzA3 XDMxMFwzMTELI1wyMTBcMjEyXDMxMlwzMTNcMzA2XDMwNSMpXDIwMyUAXDMxNFwzMTUhXDIyNlwz MTZcMjMyXDIwMyUAXDMxN1wzMDYhXDIwMkcAXDIxMlwzMjB5XDIxMFwzMjFcMzIyISlcMjA0OQBc MzIzIEBAXDMyNFwyMzJcMjAzQwBcMzI1XDMyNiFcMjEwXDMyNwkhXDIwMkcAXDMxN1wzMDZcMzA1 XCISXGZcMjA0UgBcMzA3XDMxMFwzMzALI1wyMTBcbitcMjA3IiBbY2FzZS1mb2xkLXNlYXJjaCBz dGFydCByZXN1bHQgdmhkbC1tb2RlLXN5bnRheC10YWJsZSB2aGRsLXVuZGVyc2NvcmUtaXMtcGFy dC1vZi13b3JkIHQgbmlsIG1vZGlmeS1zeW50YXgtZW50cnkgOTUgInciIHJlLXNlYXJjaC1iYWNr d2FyZCAiXlxcKGVudGl0eVxcfGVuZFxcKVxcPiIgbWF0Y2gtc3RyaW5nIDEgIkVOVElUWSIgdmhk bC10ZW1wbGF0ZS1nZW5lcmljLWxpc3QgMCBsb29raW5nLWF0ICJeXFxzLSpcXHcrXFxzLSo6XFxz LSpcXHcrIiB2aGRsLWdldC1zeW50YWN0aWMtY29udGV4dCBzdGF0ZW1lbnQtY29udCB2aGRsLWlu c2VydC1rZXl3b3JkICJHRU5FUklDICIgdmhkbC10ZW1wbGF0ZS1tYXAgIl8iXSA0ICgjJCAuIDE5 MDE5NCkgbmlsXSkKI0A0NSBJbnNlcnQgZ3JvdXAgb3IgZ3JvdXAgdGVtcGxhdGUgZGVjbGFyYXRp b24uHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtZ3JvdXAgI1tuaWwgImAYXDMwMVwzMDJcMzAz XDMwNCNcMzA1PVwyMDMRAFwzMDYgXDIwMhMAXDMwNyApXDIwNyIgW3N0YXJ0IHZoZGwtZGVjaXNp b24tcXVlcnkgImdyb3VwIiAiKGQpZWNsYXJhdGlvbiBvciAodCllbXBsYXRlIGRlY2xhcmF0aW9u PyIgdCAxMTYgdmhkbC10ZW1wbGF0ZS1ncm91cC10ZW1wbGF0ZSB2aGRsLXRlbXBsYXRlLWdyb3Vw LWRlY2xdIDQgKCMkIC4gMTkwOTEwKSBuaWxdKQojQDI3IEluc2VydCBncm91cCBkZWNsYXJhdGlv bi4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1ncm91cC1kZWNsICNbbmlsICJgGFwzMDFcMzAy IVwyMTBcMzAzXDMwNFwzMDVcMzA2CGAlXDIwNRwAXDMwM1wzMDdcMzEwXCJcMjEwXDMwM1wzMTFc MzEyXCJcMjEwXDMxMyApXDIwNyIgW3N0YXJ0IHZoZGwtaW5zZXJ0LWtleXdvcmQgIkdST1VQICIg dmhkbC10ZW1wbGF0ZS1maWVsZCAibmFtZSIgIiA6ICIgdCAidGVtcGxhdGUgbmFtZSIgIiAoIiAi Y29uc3RpdHVlbnQgbGlzdCIgIik7IiB2aGRsLWNvbW1lbnQtaW5zZXJ0LWlubGluZV0gNiAoIyQg LiAxOTEyMTIpIG5pbF0pCiNAMzYgSW5zZXJ0IGdyb3VwIHRlbXBsYXRlIGRlY2xhcmF0aW9uLh8K KGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWdyb3VwLXRlbXBsYXRlICNbbmlsICJgGFwzMDFcMzAy IVwyMTBcMzAzXDMwNFwzMDVcMzA2CGAlXDIwNRsAXDMwMVwzMDchXDIxMFwzMDNcMzEwXDMxMVwi XDIxMFwzMTIgKVwyMDciIFtzdGFydCB2aGRsLWluc2VydC1rZXl3b3JkICJHUk9VUCAiIHZoZGwt dGVtcGxhdGUtZmllbGQgInRlbXBsYXRlIG5hbWUiIG5pbCB0ICIgSVMgKCIgImVudGl0eSBjbGFz cyBsaXN0IiAiKTsiIHZoZGwtY29tbWVudC1pbnNlcnQtaW5saW5lXSA2ICgjJCAuIDE5MTU0MSkg bmlsXSkKI0AyOCBJbnNlcnQgYSBWSERMIGZpbGUgaGVhZGVyLh8KKGRlZmFsaWFzICd2aGRsLXRl bXBsYXRlLWhlYWRlciAjW25pbCAiCFwzMDZcMjMyP1wyMDV8AVwzMDdcMzEwCVxuXCJAXDIwNhEA XDMwNlwzMTFcMzEwCVxuXCI4XDIwNhsAXDMwNlwzMTIbHB0eLlwzMTIeL1wzMTNcMzE0XDMxNQ4w I1wyMTBcMjEyXDIxNH5cMjEwZWJcMjEwXDMxNgghXDIxMGATZQt9XDIxMGViXDIxMFwzMTdcMzIw XDMxMlwzMDcjXDIwM1AAXDMyMVxmXDMwN1wyMTEjXDIxMFwyMDI/AGViXDIxMFwzMTdcMzIyXDMx MlwzMDcjXDIwM2UAXDMyMVwzMjMgXDMwN1wyMTEjXDIxMFwyMDJTAGViXDIxMFwzMTdcMzI0XDMx MlwzMDcjXDIwM1wyMTEAXDMyMVwzMDZcMzA3XDIxMSNcMjEwXDMyNSBjXDIxMA4xXDIwM2gAXDMy Ng4xXDMyN1wyNjEDXDIxMFwyMDJoAGViXDIxMFwzMTdcMzMwXDMxMlwzMDcjXDIwM1wyMzYAXDMy MVwzMzEgXDMwN1wyMTEjXDIxMFwyMDJcMjE0AGViXDIxMFwzMTdcMzMyXDMxMlwzMDcjXDIwM1wy NjIAXDMyMQ1cMzA3XDIxMSNcMjEwXDIwMlwyNDEAZWJcMjEwXDMxN1wzMzNcMzEyXDMwNyNcMjAz XDMwNwBcMzIxDjJcMzA3XDIxMSNcMjEwXDIwMlwyNjUAZWJcMjEwXDMxN1wzMzRcMzEyXDMwNyNc MjAzXDMzNABcMzIxDjNcMzA3XDIxMSNcMjEwXDIwMlwzMTIAZWJcMjEwXDMxN1wzMzVcMzEyXDMw NyNcMjAzXDM2MABcMzIxXDMzNlwzMTJcMzA3I1wyMTBcMjAyXDMzNwBlYlwyMTBcMzE3XDMzN1wz MTJcMzA3I1wyMDMHAVwzMjFcMzA2XDMwN1wyMTEjXDIxMFwzNDAgXDIxMFwyMDJcMzYzAGViXDIx MFwzMTIeNFwzNDFcMzQyXDMxMlwzMDcjXDIwMygBXDM0M1wzNDRcMzQ1IVwzNDZQIRY0XDMyMQ40 XDMwN1wyMTEjXDIxMFwyMDINAStlYlwyMTBcMzE3XDM0N1wzMTJcMzA3I1wyMDM6AVwzMjFcMzA2 XDMwN1wyMTEjXDIxMA1cMjAzRAENXDMwNlwyMzJcMjAzSAFcMzUwXDM1MSFcMjEwXGZcMjAzUgFc ZlwzMDZcMjMyXDIwM1YBXDM1MFwzNTIhXDIxMA4yXDMwNlwyMzJcMjAzYQFcMzUwXDM1MyFcMjEw DjNcMzA2XDIzMlwyMDVrAVwzNTBcMzU0IRYvDjVcMjA0eQFcMzEzXDMxNFwzNTUOMCNcMjEwDi8t XDIwNyIgW3ZoZGwtZmlsZS1oZWFkZXIgdmhkbC1wcm9qZWN0LWFsaXN0IHZoZGwtcHJvamVjdCBl b3QgcHJvamVjdC1kZXNjIHByb2plY3QtbmFtZSAiIiB0IGFnZXQgMiBuaWwgbW9kaWZ5LXN5bnRh eC1lbnRyeSA5NSAidyIgdmhkbC1pbnNlcnQtc3RyaW5nLW9yLWZpbGUgc2VhcmNoLWZvcndhcmQg Ijxwcm9qZWN0ZGVzYz4iIHJlcGxhY2UtbWF0Y2ggIjxmaWxlbmFtZT4iIGJ1ZmZlci1uYW1lICI8 YXV0aG9yPiIgdXNlci1mdWxsLW5hbWUgIiAgPCIgIj4iICI8bG9naW4+IiB1c2VyLWxvZ2luLW5h bWUgIjxwcm9qZWN0PiIgIjxjb21wYW55PiIgIjxwbGF0Zm9ybT4iICI8UkNTPiIgIiQiICI8ZGF0 ZT4iIHZoZGwtdGVtcGxhdGUtaW5zZXJ0LWRhdGUgcmUtc2VhcmNoLWZvcndhcmQgIjxcXChcXChc XHdcXHxcXHNfXFwpKlxcKSBzdHJpbmc+IiByZWFkLXN0cmluZyBtYXRjaC1zdHJpbmcgMSAiOiAi ICI8Y3Vyc29yPiIgbWVzc2FnZSAiWW91IGNhbiBzcGVjaWZ5IGEgcHJvamVjdCB0aXRsZSBpbiBj dXN0b20gdmFyaWFibGUgYHZoZGwtcHJvamVjdC1hbGlzdCciICJZb3UgY2FuIHNwZWNpZnkgYSBw cm9qZWN0IGRlc2NyaXB0aW9uIGluIGN1c3RvbSB2YXJpYWJsZSBgdmhkbC1wcm9qZWN0LWFsaXN0 JyIgIllvdSBjYW4gc3BlY2lmeSBhIGNvbXBhbnkgbmFtZSBpbiBjdXN0b20gdmFyaWFibGUgYHZo ZGwtY29tcGFueS1uYW1lJyIgIllvdSBjYW4gc3BlY2lmeSBhIHBsYXRmb3JtIGluIGN1c3RvbSB2 YXJpYWJsZSBgdmhkbC1wbGF0Zm9ybS1zcGVjJyIgIl8iIGNhc2UtZm9sZC1zZWFyY2ggcmVzdWx0 IHZoZGwtbW9kZS1zeW50YXgtdGFibGUgdXNlci1tYWlsLWFkZHJlc3MgdmhkbC1jb21wYW55LW5h bWUgdmhkbC1wbGF0Zm9ybS1zcGVjIHN0cmluZyB2aGRsLXVuZGVyc2NvcmUtaXMtcGFydC1vZi13 b3JkXSA2ICgjJCAuIDE5MTg3MykgbmlsXSkKI0A2MyBJbnNlcnQgYSBzZXF1ZW50aWFsIGlmIHN0 YXRlbWVudCBvciBhbiBpZi1nZW5lcmF0ZSBzdGF0ZW1lbnQuHwooZGVmYWxpYXMgJ3ZoZGwtdGVt cGxhdGUtaWYgI1tuaWwgIlwzMDMgXDIwMwgAXDMwNCBcMjA3XDMwNRhcMzA1CUA9XDIwNhkACAlc MjExGkFAKT4pXDIwMyoAXDMwNlwzMDdcMzEwXDMxMSNcMzEyPVwyMDMqAFwzMTMgXDIwN1wzMTQg XDIwNyIgW3N0YW5kYXJkIHZoZGwtc3RhbmRhcmQgeCB2aGRsLXNlcXVlbnRpYWwtc3RhdGVtZW50 LXAgdmhkbC10ZW1wbGF0ZS1pZi10aGVuIGFtcyB2aGRsLWRlY2lzaW9uLXF1ZXJ5ICJpZiIgIihn KWVuZXJhdGUgb3IgKHUpc2U/IiB0IDExNyB2aGRsLXRlbXBsYXRlLWlmLXVzZSB2aGRsLXRlbXBs YXRlLWlmLWdlbmVyYXRlXSA0ICgjJCAuIDE5Mzg4OSkgbmlsXSkKI0AyNCBJbnNlcnQgYW4gaWYt Z2VuZXJhdGUuHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtaWYtZ2VuZXJhdGUgI1tuaWwgIlwz MDYgYFwzMDdcMjExXDIxMRgZGhscXDMxMFwzMTEhXDIxMFwzMTIgEAtiXDIxMFwzMTNcMzE0XDMw N1wzMTULCCVcMjExElwyMDU6AAhiXDIxMA1cMjAzKwBcMzE2Y1wyMTBcMzEzXDMxNyFcMjEwDVwy MDM2AFwzMjBjXDIxMFwzMjFcZlxuXCItXDIwNyIgW3Bvc2l0aW9uIHN0cmluZyBsYWJlbCBzdGFy dCBtYXJnaW4gdmhkbC1jb25kaXRpb25zLWluLXBhcmVudGhlc2lzIGN1cnJlbnQtaW5kZW50YXRp b24gbmlsIHZoZGwtaW5zZXJ0LWtleXdvcmQgIjogSUYgIiBwb2ludC1tYXJrZXIgdmhkbC10ZW1w bGF0ZS1maWVsZCAibGFiZWwiIHQgIigiICJjb25kaXRpb24iICIpIiB2aGRsLXRlbXBsYXRlLWdl bmVyYXRlLWJvZHldIDYgKCMkIC4gMTk0MzAwKSBuaWxdKQojQDM1IEluc2VydCBhIHNlcXVlbnRp YWwgaWYgc3RhdGVtZW50Lh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWlmLXRoZW4tdXNlICNb KGtpbmQpICJcMzA2IGBcMzA3GBkaC1wzMTA9XDIwMyMAXDMxMRxcMzExDUA9XDIwNh8AXGYNXDIx MR4eQUApPilcMjAzKgBcMzEyXDMxMyFcMjEwXDIwMkUAXDMxMlwzMTQhXDIxMAliXDIxMFwzMTVc MzE2XDMwN1wzMTcjXDIxMRBcMjA0PwBcMzIwXDMyMSFcMjEwXDMyMnZcMjEwXDMyMnVcMjEwDh9c MjAzTQBcMzIzY1wyMTBcMzE1XDMyNFwzMDdcMzE3CWAlXDIwNVwyMTQADh9cMjAzXwBcMzI1Y1wy MTBcMzEyXDMyNg4gXDMyNz1cMjAzbABcMzMwXDIwMm0AXDMzMVwzMzJRIVwyMTBcbmpcMjEwXDMx MlwzMzMhXDIxMAhcMjAzXDIwMQBcMzI2CFwyNjECXDIxMFwzMzRjXDIxMFwzMzV5XDIxMFxuDiFc XGorXDIwNyIgW2xhYmVsIHN0YXJ0IG1hcmdpbiB2aGRsLW9wdGlvbmFsLWxhYmVscyBzdGFuZGFy ZCB2aGRsLXN0YW5kYXJkIGN1cnJlbnQtaW5kZW50YXRpb24gbmlsIGFsbCA4NyB2aGRsLWluc2Vy dC1rZXl3b3JkICJJRiAiICI6IElGICIgdmhkbC10ZW1wbGF0ZS1maWVsZCAiW2xhYmVsXSIgdCBk ZWxldGUtY2hhciAyIDEgIigiICJjb25kaXRpb24iICIpIiAiICIgdGhlbiAiVEhFTiIgIlVTRSIg IlxuXG4iICJFTkQgSUYiICI7IiAtMSB4IHZoZGwtY29uZGl0aW9ucy1pbi1wYXJlbnRoZXNpcyBr aW5kIHZoZGwtYmFzaWMtb2Zmc2V0XSA3ICgjJCAuIDE5NDc1MikgbmlsXSkKI0AzNSBJbnNlcnQg YSBzZXF1ZW50aWFsIGlmIHN0YXRlbWVudC4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1pZi10 aGVuICNbbmlsICJcMzAwXDMwMSFcMjA3IiBbdmhkbC10ZW1wbGF0ZS1pZi10aGVuLXVzZSB0aGVu XSAyICgjJCAuIDE5NTUwMykgbmlsXSkKI0AzNyBJbnNlcnQgYSBzaW11bHRhbmVvdXMgaWYgc3Rh dGVtZW50Lh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWlmLXVzZSAjW25pbCAiXDMwMFwzMDEh XDIwNyIgW3ZoZGwtdGVtcGxhdGUtaWYtdGhlbi11c2UgdXNlXSAyICgjJCAuIDE5NTY1Mykgbmls XSkKI0A0NSBJbnNlcnQgYSBjb21wb25lbnQgaW5zdGFudGlhdGlvbiBzdGF0ZW1lbnQuHwooZGVm YWxpYXMgJ3ZoZGwtdGVtcGxhdGUtaW5zdGFuY2UgI1tuaWwgIlwzMDAgXDIwNyIgW3ZoZGwtdGVt cGxhdGUtY29tcG9uZW50LWluc3RdIDEgKCMkIC4gMTk1ODAzKSBuaWxdKQojQDMzIEluc2VydCBh IGxpYnJhcnkgc3BlY2lmaWNhdGlvbi4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1saWJyYXJ5 ICNbbmlsICJcMzA0IGBcMzA1XDIxMRgZGhtcMzA2XDMwNyFcMjEwXDMxMFwzMTFcMzA1XDMxMlxu YCVcMjExEVwyMDVLAFwzMTNjXDIxMFwzMTRcMzE1CVwiP1wyMDVLAGAQXDMxNmNcMjEwC2pcMjEw XDMwNlwzMTchXDIxMAljXDIxMFwzMDZcMzIwIVwyMTBcMzIxXDMyMiFcMjEwXDMxMFwzMjMhXDIw M0YAXDMyMnVcMjAySwAIYFwzMjJcXHwsXDIwNyIgW2VuZC1wb3MgbmFtZSBzdGFydCBtYXJnaW4g Y3VycmVudC1pbmRlbnRhdGlvbiBuaWwgdmhkbC1pbnNlcnQta2V5d29yZCAiTElCUkFSWSAiIHZo ZGwtdGVtcGxhdGUtZmllbGQgIm5hbWVzIiB0ICI7IiBzdHJpbmctbWF0Y2ggIiwiICJcbiIgIlVT RSAiICIuLkFMTDsiIGJhY2t3YXJkLWNoYXIgNSAicGFja2FnZSBuYW1lIl0gNiAoIyQgLiAxOTU5 NTgpIG5pbF0pCiNAMTcgSW5zZXJ0IGEgbGltaXQuHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUt bGltaXQgI1tuaWwgImAYXDMwMVwzMDIhXDIxMFwzMDNcMzA0XDMwNVwzMDYIYCVcMjA1HABcMzAz XDMwNyFcMjEwXDMwMVwzMTAhXDIxMFwzMDNcMzExXDMxMlwiKVwyMDciIFtzdGFydCB2aGRsLWlu c2VydC1rZXl3b3JkICJMSU1JVCAiIHZoZGwtdGVtcGxhdGUtZmllbGQgInF1YW50aXR5IG5hbWVz IHwgT1RIRVJTIHwgQUxMIiAiIDogIiB0ICJ0eXBlIiAiIFdJVEggIiAicmVhbCBleHByZXNzaW9u IiAiOyJdIDYgKCMkIC4gMTk2NDM3KSBuaWxdKQojQDE2IEluc2VydCBhIGxvb3AuHwooZGVmYWxp YXMgJ3ZoZGwtdGVtcGxhdGUtbG9vcCAjW25pbCAiXDMwMVwzMDJcMzAzXDMwNCNcMjExGFwzMDU9 XDIwMxEAXDMwNiBcMjAyHgAIXDMwNz1cMjAzHABcMzEwIFwyMDIeAFwzMTEgKVwyMDciIFtjaGFy IHZoZGwtZGVjaXNpb24tcXVlcnkgbmlsICIodyloaWxlLCAoZilvciwgb3IgKGIpYXJlPyIgdCAx MTkgdmhkbC10ZW1wbGF0ZS13aGlsZS1sb29wIDEwMiB2aGRsLXRlbXBsYXRlLWZvci1sb29wIHZo ZGwtdGVtcGxhdGUtYmFyZS1sb29wXSA1ICgjJCAuIDE5Njc0MSkgbmlsXSkKI0AxNiBJbnNlcnQg YSBsb29wLh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWJhcmUtbG9vcCAjW25pbCAiXDMwNSBg XDMwNhgZGgtcMzA3PVwyMDQUAFwzMTBcMzExIVwyMTBcMjAyMABcMzEwXDMxMiFcMjEwCWJcMjEw XDMxM1wzMTRcMzA2XDMxNSNcMjExEFwyMDQpAFwzMTZcMzE3IVwyMTBcMzIwdlwyMTBcMzE2XDMy MCFcMjEwXDMyMWNcMjEwXG5qXDIxMFwzMTBcMzIyIVwyMTAIXDIwM0UAXDMyMwhcMzI0UVwyMDJG AFwzMjRjXDIxMFwzMjV5XDIxMFxuXGZcXGorXDIwNyIgW2xhYmVsIHN0YXJ0IG1hcmdpbiB2aGRs LW9wdGlvbmFsLWxhYmVscyB2aGRsLWJhc2ljLW9mZnNldCBjdXJyZW50LWluZGVudGF0aW9uIG5p bCBhbGwgdmhkbC1pbnNlcnQta2V5d29yZCAiTE9PUCAiICI6IExPT1AgIiB2aGRsLXRlbXBsYXRl LWZpZWxkICJbbGFiZWxdIiB0IGRlbGV0ZS1jaGFyIDIgMSAiXG5cbiIgIkVORCBMT09QIiAiICIg IjsiIC0xXSA1ICgjJCAuIDE5NzA0MikgbmlsXSkKI0A1MSBJbnNlcnQgYSBtYXAgc3BlY2lmaWNh dGlvbiB3aXRoIGFzc29jaWF0aW9uIGxpc3QuHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtbWFw ICNbKCZvcHRpb25hbCBzdGFydCBvcHRpb25hbCBzZWNvbmRhcnkpICIIXDIwNgUAYFwzMDZcMjEx GRoYXDMwN1wzMTAhXDIxMAtcMjA0RQBcMzExXGZcMjA1GABcMzEyXDMxM1xmXDIwNR4AXDMxNFFc MzE1DT9cMjA2JgBcZg0/XDIwNSwACGAlXDIwMzUAXDMxNlwyMDJcMzA2AFxmXDIwM0EADVwyMDNB AAhgfFwyMTBcMzA2XDIwMlwzMDYADhlcMjAzTwBpElwyMDJbAFwzMTcgDhpcXBJcMzIwY1wyMTBc bmpcMjEwXDMxMVxmXDIwNWEAXDMxMlwzMjFcZlwyMDVnAFwzMTRRXDMyMg0/XDIwNm8AXGYNP1wy MDV1AAhgJVwyMDNcMjcxAFwzMTFcMzIzXDMyNFwiXDIxMGARXDMyMGNcMjEwXG5qXDIxMFwzMTFc MzI1XDMyMlwzMTYjXDIwM1wyMzcAXDMxMVwzMjNcMzI0XCJcMjEwYBFcMzIwY1wyMTBcbmpcMjEw XDIwMlwyMDcACWB8XDIxMFwzMjZcMzI3IVwyMTBcMzE1Y1wyMTAOG1wyMDNcMjY1AFwzMzAIYFwz MjcjXDIxMFwzMTZcMjAyXDMwNgBcZlwyMDNcMzA1AA1cMjAzXDMwNQAIYHxcMjEwXDMwNitcMjA3 IiBbc3RhcnQgZW5kLXBvcyBtYXJnaW4gdmhkbC1hc3NvY2lhdGlvbi1saXN0LXdpdGgtZm9ybWFs cyBvcHRpb25hbCBzZWNvbmRhcnkgbmlsIHZoZGwtaW5zZXJ0LWtleXdvcmQgIk1BUCAoIiB2aGRs LXRlbXBsYXRlLWZpZWxkICJbIiAiYXNzb2NpYXRpb24gbGlzdCIgIl0iICIpIiB0IGN1cnJlbnQt aW5kZW50YXRpb24gIlxuIiAiZm9ybWFsIiAiID0+ICIgImFjdHVhbCIgIiwiICJbZm9ybWFsXSIg YmFja3dhcmQtZGVsZXRlLWNoYXIgMSB2aGRsLWFsaWduLW5vaW5kZW50LXJlZ2lvbiB2aGRsLWFy Z3VtZW50LWxpc3QtaW5kZW50IHZoZGwtYmFzaWMtb2Zmc2V0IHZoZGwtYXV0by1hbGlnbl0gNiAo IyQgLiAxOTc1NDApIG5pbF0pCiNAMzAgQWN0dWFsaXplIG1vZGlmaWNhdGlvbiBkYXRlLh8KKGRl ZmFsaWFzICd2aGRsLXRlbXBsYXRlLW1vZGlmeSAjWygmb3B0aW9uYWwgbm9lcnJvcikgIlwzMDYY XDMwNxlcMzEwXDMxMVwzMTJcbiNcMjEwXDIxMmViXDIxMFwzMTMLXDMwN1wzMDYjXDIwMx4AXDMx NCBcMjEwXDMxNSBcMjAyKQBcZj9cMjA1KQBcMzE2XDMxNwtcMzIwUSEpEQ1cMjA0NQBcMzEwXDMx MVwzMjFcbiNcMjEwCSpcMjA3IiBbY2FzZS1mb2xkLXNlYXJjaCByZXN1bHQgdmhkbC1tb2RlLXN5 bnRheC10YWJsZSB2aGRsLW1vZGlmeS1kYXRlLXByZWZpeC1zdHJpbmcgbm9lcnJvciB2aGRsLXVu ZGVyc2NvcmUtaXMtcGFydC1vZi13b3JkIHQgbmlsIG1vZGlmeS1zeW50YXgtZW50cnkgOTUgInci IHJlLXNlYXJjaC1mb3J3YXJkIGtpbGwtbGluZSB2aGRsLXRlbXBsYXRlLWluc2VydC1kYXRlIGVy cm9yICJNb2RpZmljYXRpb24gZGF0ZSBwcmVmaXggc3RyaW5nIFwiIiAiXCIgbm90IGZvdW5kIiAi XyJdIDQgKCMkIC4gMTk4NDk4KSBuaWxdKQojQDUxIENhbGwgYHZoZGwtdGVtcGxhdGUtbW9kaWZ5 JyB3aXRoIE5PRVJST1Igbm9uLW5pbC4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1tb2RpZnkt bm9lcnJvciAjW25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwtdGVtcGxhdGUtbW9kaWZ5IHRdIDIg KCMkIC4gMTk5MDE4KV0pCiNAMzAgSW5zZXJ0IGEgbmF0dXJlIGRlY2xhcmF0aW9uLh8KKGRlZmFs aWFzICd2aGRsLXRlbXBsYXRlLW5hdHVyZSAjW25pbCAiYFwzMDVcMjExXDIxMRgZGhtcMzA2XDMw NyFcMjEwXDMxMFwzMTFcMzA1XDMxMgtgJVwyMTESXDIwNVwyMDQAXDMwNlwzMTMhXDIxMFwzMTBc MzE0IVwyMDYjAFwzMTVcMjI2XDIxMRxcMzE1XDIzMlwyMDMxAFwzMTZjXDIxMFwyMDJtAFxmXDMx N1wyMzJcMjAzQwBcMzIwXDMyMSFcMjEwXDMyMlwzMjNcMzEyXCJcMjEwXDIwMm0AXGZcMzI0XDIz MlwyMDNZAFwzMjUgEVwzMjBcMzIxIVwyMTBcMzI2XDMyM1xuXDMxMiNcMjEwXDIwMm0AXDMwNlwz MjchXDIxMFwzMTBcMzMwIVwyMTBcMzA2XDMzMSFcMjEwXDMxMFwzMzIhXDIxMFwzMDZcMzMzIVwy MTAJXDIwM3oAXDMyNSAQCWJcMjEwXDMwNX9cMjEwXDMzNCBcMjEwCFwyMDVcMjAzAAhiKSxcMjA3 IiBbZW5kLXBvcyBtaWQtcG9zIG5hbWUgc3RhcnQgZGVmaW5pdGlvbiBuaWwgdmhkbC1pbnNlcnQt a2V5d29yZCAiTkFUVVJFICIgdmhkbC10ZW1wbGF0ZS1maWVsZCAibmFtZSIgdCAiIElTICIgImFj cm9zcyB0eXBlIHwgQVJSQVkgfCBSRUNPUkQiICIiICI7IiAiQVJSQVkiIGtpbGwtd29yZCAtMSB2 aGRsLXRlbXBsYXRlLWFycmF5IG5hdHVyZSAiUkVDT1JEIiBwb2ludC1tYXJrZXIgdmhkbC10ZW1w bGF0ZS1yZWNvcmQgIiBBQ1JPU1MgIiAidGhyb3VnaCB0eXBlIiAiIFRIUk9VR0ggIiAicmVmZXJl bmNlIG5hbWUiICIgUkVGRVJFTkNFOyIgdmhkbC1jb21tZW50LWluc2VydC1pbmxpbmVdIDcgKCMk IC4gMTk5MTc5KSBuaWxdKQojQDI2IEluc2VydCBhIG5leHQgc3RhdGVtZW50Lh8KKGRlZmFsaWFz ICd2aGRsLXRlbXBsYXRlLW5leHQgI1tuaWwgIlwzMDJcMzAzIVwyMTBcMzA0XDMwNVwzMDZcMzA3 I1wyMDQQAFwzMTBcMzExIVwyMTBgGFwzMDJcMzEyIVwyMTAJXDIwMx0AXDMxM2NcMjEwXDMwNFwz MTRcMzA2XDMwNyNcMjAzLwAJXDIwMzMAXDMxNWNcMjEwXDIwMjMACGB8XDIxMFwzMTZjKVwyMDci IFtwb3NpdGlvbiB2aGRsLWNvbmRpdGlvbnMtaW4tcGFyZW50aGVzaXMgdmhkbC1pbnNlcnQta2V5 d29yZCAiTkVYVCAiIHZoZGwtdGVtcGxhdGUtZmllbGQgIltsb29wIGxhYmVsXSIgbmlsIHQgZGVs ZXRlLWNoYXIgLTEgIiBXSEVOICIgIigiICJbY29uZGl0aW9uXSIgIikiICI7Il0gNCAoIyQgLiAx OTk5NzgpIG5pbF0pCiNAMjkgSW5zZXJ0IGFuIG90aGVycyBhZ2dyZWdhdGUuHwooZGVmYWxpYXMg J3ZoZGwtdGVtcGxhdGUtb3RoZXJzICNbbmlsICJcMzAwXDMwMSFcMjEwXDMwMlwzMDMhXDIwNyIg W3ZoZGwtaW5zZXJ0LWtleXdvcmQgIihPVEhFUlMgPT4gJycpIiBiYWNrd2FyZC1jaGFyIDJdIDIg KCMkIC4gMjAwMzczKSBuaWxdKQojQDQxIEluc2VydCBhIHBhY2thZ2Ugc3BlY2lmaWNhdGlvbiBv ciBib2R5Lh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXBhY2thZ2UgI1soJm9wdGlvbmFsIGtp bmQpICJcMzA2IGBcMzA3XDIxMVwyMTEYGRobHFwzMTBcMzExIVwyMTANXDIwMxkADVwzMDE9XDIw Mh8AXDMxMlwzMDdcMzEzXCJcMzE0PVwyMTERXDIwMygAXDMxMFwzMTUhXDIxMFwzMTZcMzE3XDMw N1wzMjALYCVcMjExElwyMDVcMjE1AFwzMTBcMzIxIVwyMTAOGVwzMjI+XDIwM0IAXDMyM2NcMjEw XGYOGlxcalwyMTBgEFwzMjNjXDIxMA4ZXDMyND5cMjAzVwBcMzIzY1wyMTBcZmpcMjEwXDMxMFwz MjUhXDIxMFwzMjYeG1wzMjYOHEA9XDIwNnQADhsOHFwyMTEeHUFAKT4pXDIwNFwyMDIAXDMxMFwz MTEJXDIwNX8AXDMxNVAhXDIxMFxuXDIwNlwyMDcAXDMyN1wzMzBcMjYxAlwyMTAIYi1cMjA3IiBb cG9zaXRpb24gYm9keSBuYW1lIHN0YXJ0IG1hcmdpbiBraW5kIGN1cnJlbnQtaW5kZW50YXRpb24g bmlsIHZoZGwtaW5zZXJ0LWtleXdvcmQgIlBBQ0tBR0UgIiB2aGRsLWRlY2lzaW9uLXF1ZXJ5ICIo ZCllY2xhcmF0aW9uIG9yIChiKW9keT8iIDk4ICJCT0RZICIgdmhkbC10ZW1wbGF0ZS1maWVsZCAi bmFtZSIgdCAiIElTXG4iICh1bml0IGFsbCkgIlxuIiAodW5pdCBhbGwpICJFTkQgIiA4NyAiIiAi OyIgdmhkbC1pbnNlcnQtZW1wdHktbGluZXMgdmhkbC1iYXNpYy1vZmZzZXQgc3RhbmRhcmQgdmhk bC1zdGFuZGFyZCB4XSA3ICgjJCAuIDIwMDU1MSkgbmlsXSkKI0AzMyBJbnNlcnQgYSBwYWNrYWdl IHNwZWNpZmljYXRpb24uHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtcGFja2FnZS1kZWNsICNb bmlsICJcMzAwXDMwMSFcMjA3IiBbdmhkbC10ZW1wbGF0ZS1wYWNrYWdlIGRlY2xdIDIgKCMkIC4g MjAxMzA4KSBuaWxdKQojQDI0IEluc2VydCBhIHBhY2thZ2UgYm9keS4fCihkZWZhbGlhcyAndmhk bC10ZW1wbGF0ZS1wYWNrYWdlLWJvZHkgI1tuaWwgIlwzMDBcMzAxIVwyMDciIFt2aGRsLXRlbXBs YXRlLXBhY2thZ2UgYm9keV0gMiAoIyQgLiAyMDE0NTcpIG5pbF0pCiNANjkgSW5zZXJ0IGEgcG9y dCBkZWNsYXJhdGlvbiwgb3IgcG9ydCBtYXAgaW4gaW5zdGFudGlhdGlvbiBzdGF0ZW1lbnRzLh8K KGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXBvcnQgI1tuaWwgImBcMzA1GBlcMzA2GlwzMDdcMzEw XDMxMQsjXDIxMFwyMTJcMzEyXDMxM1wzMDZcMzA1IylcMjAzJQBcMzE0XDMxNSFcMjI2XDMxNlwy MzJcMjAzJQBcMzE3XDMwNiFcMjAyRgBcMjEyXDMyMHlcMjEwXDMyMVwzMjIhKVwyMDQ5AFwzMjMg QEBcMzI0XDIzMlwyMDNDAFwzMjVcMzI2IVwyMTBcMzI3CSFcMjAyRgBcMzE3XDMwNiESXGZcMjA0 UQBcMzA3XDMxMFwzMzALI1wyMTBcbitcMjA3IiBbY2FzZS1mb2xkLXNlYXJjaCBzdGFydCByZXN1 bHQgdmhkbC1tb2RlLXN5bnRheC10YWJsZSB2aGRsLXVuZGVyc2NvcmUtaXMtcGFydC1vZi13b3Jk IHQgbmlsIG1vZGlmeS1zeW50YXgtZW50cnkgOTUgInciIHJlLXNlYXJjaC1iYWNrd2FyZCAiXlxc KGVudGl0eVxcfGVuZFxcKVxcPiIgbWF0Y2gtc3RyaW5nIDEgIkVOVElUWSIgdmhkbC10ZW1wbGF0 ZS1wb3J0LWxpc3QgMCBsb29raW5nLWF0ICJeXFxzLSpcXHcrXFxzLSo6XFxzLSpcXHcrIiB2aGRs LWdldC1zeW50YWN0aWMtY29udGV4dCBzdGF0ZW1lbnQtY29udCB2aGRsLWluc2VydC1rZXl3b3Jk ICJQT1JUICIgdmhkbC10ZW1wbGF0ZS1tYXAgIl8iXSA0ICgjJCAuIDIwMTU5NykgbmlsXSkKI0Ay MiBJbnNlcnQgYSBwcm9jZWR1cmFsLh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXByb2NlZHVy YWwgI1tuaWwgIlwzMDYgYFwzMDdcMzEwGBkaG1wzMTFcMzEyIVwyMTBcZlwzMTM+XDIwMzAAXG5i XDIxMFwzMTRjXDIxMFxuYlwyMTBcMzE1XDMxNlwzMTBcMzA3I1wyMTEQXDIwNCoAXDMxN1wzMjAh XDIxMFwzMjF2XDIxMFwzMjF1XDIxMFwzMjIdXDMyMg4XQD1cMjA2RAANDhdcMjExHhhBQCk+KVwy MDRMAFwzMTFcMzIzIVwyMTBcMzI0XDMyNQgLI1wyMTBcMzI2ICxcMjA3IiBbbGFiZWwgY2FzZS1m b2xkLXNlYXJjaCBzdGFydCBtYXJnaW4gdmhkbC1vcHRpb25hbC1sYWJlbHMgc3RhbmRhcmQgY3Vy cmVudC1pbmRlbnRhdGlvbiB0IG5pbCB2aGRsLWluc2VydC1rZXl3b3JkICJQUk9DRURVUkFMICIg KHByb2Nlc3MgYWxsKSAiOiAiIHZoZGwtdGVtcGxhdGUtZmllbGQgIltsYWJlbF0iIGRlbGV0ZS1j aGFyIDIgMSA4NyAiSVMiIHZoZGwtdGVtcGxhdGUtYmVnaW4tZW5kICJQUk9DRURVUkFMIiB2aGRs LWNvbW1lbnQtYmxvY2sgdmhkbC1zdGFuZGFyZCB4XSA1ICgjJCAuIDIwMjI5NSkgbmlsXSkKI0A0 MSBJbnNlcnQgYSBwcm9jZWR1cmUgZGVjbGFyYXRpb24gb3IgYm9keS4fCihkZWZhbGlhcyAndmhk bC10ZW1wbGF0ZS1wcm9jZWR1cmUgI1soJm9wdGlvbmFsIGtpbmQpICJcMzA2IGBcMzA3GBkaXDMx MFwzMTEhXDIxMFwzMTJcMzEzXDMwN1wzMTQJYCVcMjExEFwyMDVxAFwzMTUgXDIxMAtcMjAzJAAL XDMxNj1cMjAyKgBcMzE3XDMwN1wzMjBcIlwzMjE9XDIwM2IAXDMxMFwzMjIhXDIxMFxmXDIwMzsA XDMyMwlgXDMyNCNcMjEwXDMwN39cMjEwXDMyNVwzMjYdXDMyNg4aQD1cMjA2UwANDhpcMjExHhtB QCk+KT9cMjA1WQBcMzI3CFxuI1wyMTBcMzMwIFwyMDJxAFwzMzFjXDIxMFxmXDIwM28AXDMyMwlg XDMyNCNcMjEwXDMwN38rXDIwNyIgW25hbWUgc3RhcnQgbWFyZ2luIGtpbmQgdmhkbC1hdXRvLWFs aWduIHN0YW5kYXJkIGN1cnJlbnQtaW5kZW50YXRpb24gbmlsIHZoZGwtaW5zZXJ0LWtleXdvcmQg IlBST0NFRFVSRSAiIHZoZGwtdGVtcGxhdGUtZmllbGQgIm5hbWUiIHQgdmhkbC10ZW1wbGF0ZS1h cmd1bWVudC1saXN0IGJvZHkgdmhkbC1kZWNpc2lvbi1xdWVyeSAiKGQpZWNsYXJhdGlvbiBvciAo YilvZHk/IiA5OCAiIElTIiB2aGRsLWFsaWduLW5vaW5kZW50LXJlZ2lvbiAxIHZoZGwtdGVtcGxh dGUtYmVnaW4tZW5kIDg3ICJQUk9DRURVUkUiIHZoZGwtY29tbWVudC1ibG9jayAiOyIgdmhkbC1z dGFuZGFyZCB4XSA2ICgjJCAuIDIwMjg2NSkgbmlsXSkKI0AzMyBJbnNlcnQgYSBwcm9jZWR1cmUg ZGVjbGFyYXRpb24uHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtcHJvY2VkdXJlLWRlY2wgI1tu aWwgIlwzMDBcMzAxIVwyMDciIFt2aGRsLXRlbXBsYXRlLXByb2NlZHVyZSBkZWNsXSAyICgjJCAu IDIwMzU4NSkgbmlsXSkKI0AyNiBJbnNlcnQgYSBwcm9jZWR1cmUgYm9keS4fCihkZWZhbGlhcyAn dmhkbC10ZW1wbGF0ZS1wcm9jZWR1cmUtYm9keSAjW25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwt dGVtcGxhdGUtcHJvY2VkdXJlIGJvZHldIDIgKCMkIC4gMjAzNzM4KSBuaWxdKQojQDE5IEluc2Vy dCBhIHByb2Nlc3MuHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtcHJvY2VzcyAjWygmb3B0aW9u YWwga2luZCkgIlwzMDYgYFwzMDdcMzEwXDIxMVwyMTFcMjExXDIxMVwyMTEYGRobHB0eOh47HjwO PVwyMDNcIgAOPVwzMDQ9XDIwMikAXDMxMVwzMTJcMzEzXDMwNyNcMzE0PRRcMzE1XDMxNiFcMjEw Dj5cMzE3PlwyMDNUAA47YlwyMTBcMzIwY1wyMTAOO2JcMjEwXDMyMVwzMjJcMzEwXDMwNyNcMjEx FVwyMDROAFwzMjNcMzI0IVwyMTBcMzI1dlwyMTBcMzI1dVwyMTBcMzI2Y1wyMTBcZlwyMDRuAFwz MjFcMzI3XDMzMFwzMDcjXDIxMRNcMjA0XDI1MwBcMzMxE1wzMjNcMzMyIVwyMTBcMjAyXDI1MwAO P1wzMzFcMjMyXDIwNH4ADj9jXDIxMA4/XDIwNlwyMDUAXDMyMVwzMzMhXDIwNlwyMDUAXDMzNBIO QFwzMzU9XDIwM1wyNTAAXDMzNmNcMjEwDkFcMzMxXDIzMlwyMDRcMjQwAA5BY1wyMTAOQVwyMDZc MjQ3AFwzMjFcMzM3IVwyMDZcMjQ3AFwzNDARXDMzMGNcMjEwXDM0MR5CXDM0MQ5DQD1cMjA2XDMw MQAOQg5DXDIxMR5EQUApPilcMjA0XDMxMQBcMzE1XDM0MiFcMjEwXDM0M1wzNDQNDjwjXDIxMFxm XDIwM1wzMzEAXDM0NVxuCVwiEQ5FXDIwNVwyMDQBXDM0NiAQXDMxMB5GXDM0N1wzNTBcMzUxDkcj XDIxMFwzNTJcMzUzXDMxMFwzMDcjXDIwNXMBXDM1MlwzNTRcMzEwXDMwNyNcMjA1cwFcMzU1f1wy MTBvXDIwMwsBXDM1NmNcMjEwXDM1N3lcMjEwXDIwMg4BXDM1NmNcMjEwDjxqXDIxMFwzNjBjXDIx MFwzMjFcMzYxXDMxMFwzMDcjXDIwNFwiAVwzNjIgXDIwMnMBXDM1NmNcMjEwDjxqXDIxMFwzNjNj XDIxMFxmXDIwMzQBXDM2NFwyMDI1AVwzNjVcMzU2XDI2MQJcMjEwDjxqXDIxMFwzNjZjXDIxMFxm XDIwNEoBC2NcMjEwXDIwMmQBXG5cMzM2XDI2MQJcMjEwCVwyMDNYAQlcMzM2XDI2MQJcMjEwXDMy MVwzNjdcMzEwXDMwNyNcMjA0ZAFcMzIzXDMzMiFcMjEwXDM1NmNcMjEwDjxqXDIxMFwzNzBjXDIx MFwzMjFcMzY3XDMxMFwzMDcjFkYOSFwyMDRcMjAxAVwzNDdcMzUwXDM3MQ5HI1wyMTApCGIuCVwy MDciIFtmaW5hbC1wb3MgcmVzZXQgY2xvY2sgaW5wdXQtc2lnbmFscyBzZXEgbGFiZWwgY3VycmVu dC1pbmRlbnRhdGlvbiB0IG5pbCB2aGRsLWRlY2lzaW9uLXF1ZXJ5ICJwcm9jZXNzIiAiKGMpb21i aW5hdGlvbmFsIG9yIChzKWVxdWVudGlhbD8iIDExNSB2aGRsLWluc2VydC1rZXl3b3JkICJQUk9D RVNTICIgKHByb2Nlc3MgYWxsKSAiOiAiIHZoZGwtdGVtcGxhdGUtZmllbGQgIltsYWJlbF0iIGRl bGV0ZS1jaGFyIDIgMSAiKCIgIltzZW5zaXRpdml0eSBsaXN0XSIgIikiICIiIC0yICJjbG9jayBu YW1lIiAiPGNsb2NrPiIgYXN5bmMgIiwgIiAicmVzZXQgbmFtZSIgIjxyZXNldD4iIDg3ICIgSVMi IHZoZGwtdGVtcGxhdGUtYmVnaW4tZW5kICJQUk9DRVNTIiB2aGRsLXRlbXBsYXRlLXNlcS1wcm9j ZXNzIHBvaW50LW1hcmtlciBtb2RpZnktc3ludGF4LWVudHJ5IDk1ICJ3IiByZS1zZWFyY2gtYmFj a3dhcmQgIlxcPGJlZ2luXFw+IiAiXFw8cHJvY2Vzc1xcPiIgMCAiXG4iIC0xICItLSBwdXJwb3Nl OiAiICJbZGVzY3JpcHRpb25dIiB2aGRsLWxpbmUta2lsbC1lbnRpcmUgIi0tIHR5cGUgICA6ICIg InNlcXVlbnRpYWwiICJjb21iaW5hdGlvbmFsIiAiLS0gaW5wdXRzIDogIiAiW3NpZ25hbCBuYW1l c10iICItLSBvdXRwdXRzOiAiICJfIiBjYXNlLWZvbGQtc2VhcmNoIHN0YXJ0IG1hcmdpbiBraW5k IHZoZGwtb3B0aW9uYWwtbGFiZWxzIHZoZGwtY2xvY2stbmFtZSB2aGRsLXJlc2V0LWtpbmQgdmhk bC1yZXNldC1uYW1lIHN0YW5kYXJkIHZoZGwtc3RhbmRhcmQgeCB2aGRsLXByb21wdC1mb3ItY29t bWVudHMgcmVzdWx0IHZoZGwtbW9kZS1zeW50YXgtdGFibGUgdmhkbC11bmRlcnNjb3JlLWlzLXBh cnQtb2Ytd29yZF0gMTAgKCMkIC4gMjAzODg0KSBuaWxdKQojQDMzIEluc2VydCBhIGNvbWJpbmF0 aW9uYWwgcHJvY2Vzcy4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1wcm9jZXNzLWNvbWIgI1tu aWwgIlwzMDBcMzAxIVwyMDciIFt2aGRsLXRlbXBsYXRlLXByb2Nlc3MgY29tYl0gMiAoIyQgLiAy MDU4MTApIG5pbF0pCiNAMzAgSW5zZXJ0IGEgc2VxdWVudGlhbCBwcm9jZXNzLh8KKGRlZmFsaWFz ICd2aGRsLXRlbXBsYXRlLXByb2Nlc3Mtc2VxICNbbmlsICJcMzAwXDMwMSFcMjA3IiBbdmhkbC10 ZW1wbGF0ZS1wcm9jZXNzIHNlcV0gMiAoIyQgLiAyMDU5NTkpIG5pbF0pCiNAMzIgSW5zZXJ0IGEg cXVhbnRpdHkgZGVjbGFyYXRpb24uHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtcXVhbnRpdHkg I1tuaWwgIlwzMDIgXDIwMykAYBhcMzAzXDMwNCFcMjEwXDMwNVwzMDZcMzA3XDMxMAhgJVwyMDUn AFwzMTFjXDIxMFwzMDVcMzEyXDMxM1wzMTAjXDIxMFwzMDVcMzE0IVwyMTBcMzE1Y1wyMTBcMzE2 IClcMjA3XDMxN1wzMjBcMzIxXDMxMCNcMjExGVwzMjI9XDIwMzoAXDMyMyBcMjAyVAAJXDMyND1c MjAzRQBcMzI1IFwyMDJUAAlcMzI2PVwyMDNQAFwzMjcgXDIwMlQAXDMzMGBgXCIpXDIwNyIgW3N0 YXJ0IGNoYXIgdmhkbC1pbi1hcmd1bWVudC1saXN0LXAgdmhkbC1pbnNlcnQta2V5d29yZCAiUVVB TlRJVFkgIiB2aGRsLXRlbXBsYXRlLWZpZWxkICJuYW1lcyIgbmlsIHQgIiA6ICIgIltJTiB8IE9V VF0iICIgIiAidHlwZSIgIjsiIHZoZGwtY29tbWVudC1pbnNlcnQtaW5saW5lIHZoZGwtZGVjaXNp b24tcXVlcnkgInF1YW50aXR5IiAiKGYpcmVlLCAoYilyYW5jaCwgb3IgKHMpb3VyY2UgcXVhbnRp dHk/IiAxMDIgdmhkbC10ZW1wbGF0ZS1xdWFudGl0eS1mcmVlIDk4IHZoZGwtdGVtcGxhdGUtcXVh bnRpdHktYnJhbmNoIDExNSB2aGRsLXRlbXBsYXRlLXF1YW50aXR5LXNvdXJjZSB2aGRsLXRlbXBs YXRlLXVuZG9dIDcgKCMkIC4gMjA2MTAzKSBuaWxdKQojQDM3IEluc2VydCBhIGZyZWUgcXVhbnRp dHkgZGVjbGFyYXRpb24uHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtcXVhbnRpdHktZnJlZSAj W25pbCAiXDMwMVwzMDIhXDIxMFwzMDNcMzA0IVwyMTBcMzA1Y1wyMTBcMzAzXDMwNiFcMjEwYBhc MzA3Y1wyMTBcMzAzXDMxMFwzMTFcMzEyI1wyMDQgAAhgfFwyMTBcMzEzY1wyMTBcMzE0IClcMjA3 IiBbcG9zaXRpb24gdmhkbC1pbnNlcnQta2V5d29yZCAiUVVBTlRJVFkgIiB2aGRsLXRlbXBsYXRl LWZpZWxkICJuYW1lcyIgIiA6ICIgInR5cGUiICIgOj0gIiAiW2luaXRpYWxpemF0aW9uXSIgbmls IHQgIjsiIHZoZGwtY29tbWVudC1pbnNlcnQtaW5saW5lXSA0ICgjJCAuIDIwNjc3NikgbmlsXSkK I0AzOSBJbnNlcnQgYSBicmFuY2ggcXVhbnRpdHkgZGVjbGFyYXRpb24uHwooZGVmYWxpYXMgJ3Zo ZGwtdGVtcGxhdGUtcXVhbnRpdHktYnJhbmNoICNbbmlsICJcMzAxGFwzMDJcMzAzIVwyMTBcMzA0 XDMwNVwzMDZcMzA3I1wyMDMSAFwzMDJcMzEwIVwyMTBcMzA0XDMxMVwzMDZcMzA3I1wyMDMeAFwz MDJcMzEyIVwyMTBcMzA0XDMxMyFcMjEwYBBcMzAyXDMxNCFcMjEwXDMwNFwzMTVcMzAxXDMwNyNc MjA0NAAIYHxcMjEwXDMxNmNcMjEwXDMxNyApXDIwNyIgW3Bvc2l0aW9uIG5pbCB2aGRsLWluc2Vy dC1rZXl3b3JkICJRVUFOVElUWSAiIHZoZGwtdGVtcGxhdGUtZmllbGQgIlthY3Jvc3MgbmFtZXNd IiAiICIgdCAiQUNST1NTICIgIlt0aHJvdWdoIG5hbWVzXSIgIlRIUk9VR0ggIiAicGx1cyB0ZXJt aW5hbCBuYW1lIiAiIFRPICIgIlttaW51cyB0ZXJtaW5hbCBuYW1lXSIgIjsiIHZoZGwtY29tbWVu dC1pbnNlcnQtaW5saW5lXSA0ICgjJCAuIDIwNzE0MykgbmlsXSkKI0AzOSBJbnNlcnQgYSBzb3Vy Y2UgcXVhbnRpdHkgZGVjbGFyYXRpb24uHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtcXVhbnRp dHktc291cmNlICNbbmlsICJcMzAwXDMwMSFcMjEwXDMwMlwzMDMhXDIxMFwzMDRjXDIxMFwzMDJc MzA1XDMwNlwiXDIxMFwzMDdcMzEwXDMxMVwiXDMxMj1cMjAzJABcMzAwXDMxMyFcMjEwXDMwMlwz MTQhXDIxMFwyMDIxAFwzMDBcMzE1IVwyMTBcMzAyXDMxNlwzMTdcIlwyMTBcMzAyXDMyMCFcMjEw XDMyMWNcMjEwXDMyMiBcMjA3IiBbdmhkbC1pbnNlcnQta2V5d29yZCAiUVVBTlRJVFkgIiB2aGRs LXRlbXBsYXRlLWZpZWxkICJuYW1lcyIgIiA6ICIgInR5cGUiICIgIiB2aGRsLWRlY2lzaW9uLXF1 ZXJ5IG5pbCAiKHMpcGVjdHJ1bSBvciAobilvaXNlPyIgMTEwICJOT0lTRSAiICJwb3dlciBleHBy ZXNzaW9uIiAiU1BFQ1RSVU0gIiAibWFnbml0dWRlIGV4cHJlc3Npb24iICIsICIgInBoYXNlIGV4 cHJlc3Npb24iICI7IiB2aGRsLWNvbW1lbnQtaW5zZXJ0LWlubGluZV0gMyAoIyQgLiAyMDc2Mzgp IG5pbF0pCiNAMzUgSW5zZXJ0IGEgcmVjb3JkIHR5cGUgZGVjbGFyYXRpb24uHwooZGVmYWxpYXMg J3ZoZGwtdGVtcGxhdGUtcmVjb3JkICNbKGtpbmQgJm9wdGlvbmFsIG5hbWUgc2Vjb25kYXJ5KSAi aWBcMzA2GBkaXDMwN1wzMTAhXDIxMFxuC1xcalwyMTBcMzExXDMxMlwzMTNcZj8JYCVcMjA0HgBc ZlwyMDVcMjEyAAhcMjA0KgBcMzExXDMxNFwzMTNcMzA2I1wyMDNNAFwzMTVjXDIxMFwzMTENXDMx Nj1cMjAzOABcMzE3XDIwMjkAXDMyMFwzMjFcIlwyMTBcMzIyIFwyMTBcMzIzY1wyMTBcbgtcXGpc MjEwXDMxM1wyMTEQXDIwMh8AXDMyNFwzMjUhXDIxMFxualwyMTBcMzA3XDMyNiFcMjEwXDMyNx4b XDMyNw4cQD1cMjA2bgAOGw4cXDIxMR4dQUApPilcMjA0fQAOHlwyMDN9AFwzMzAOHlwyNjECXDIx MFwzMjFjXDIxMA4fXDIwNVwyMTIAXDMzMQlgXDMzMiMrXDIwNyIgW2ZpcnN0IHN0YXJ0IG1hcmdp biB2aGRsLWJhc2ljLW9mZnNldCBzZWNvbmRhcnkga2luZCB0IHZoZGwtaW5zZXJ0LWtleXdvcmQg IlJFQ09SRFxuIiB2aGRsLXRlbXBsYXRlLWZpZWxkICJlbGVtZW50IG5hbWVzIiBuaWwgIltlbGVt ZW50IG5hbWVzXSIgIiA6ICIgdHlwZSAidHlwZSIgIm5hdHVyZSIgIjsiIHZoZGwtY29tbWVudC1p bnNlcnQtaW5saW5lICJcbiIga2lsbC1saW5lIDAgIkVORCBSRUNPUkQiIDg3ICIgIiB2aGRsLWFs aWduLW5vaW5kZW50LXJlZ2lvbiAxIHN0YW5kYXJkIHZoZGwtc3RhbmRhcmQgeCBuYW1lIHZoZGwt YXV0by1hbGlnbl0gNyAoIyQgLiAyMDgxNzYpIG5pbF0pCiNAMjggSW5zZXJ0IGEgcmVwb3J0IHN0 YXRlbWVudC4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1yZXBvcnQgI1tuaWwgImAYXDMwMVwz MDIhXDIxMFwzMDNcMzA0XDMwNVwzMDYIYFwzMDYmBlwzMDdcMjMyXDIwMxoAXDMxMFwzMTEhXDIw Mi4AYBBcMzAxXDMxMiFcMjEwXDMwM1wzMTNcMzA1XDMwNiNcMjA0LAAIYHxcMjEwXDMxNGMpXDIw NyIgW3N0YXJ0IHZoZGwtaW5zZXJ0LWtleXdvcmQgIlJFUE9SVCAiIHZoZGwtdGVtcGxhdGUtZmll bGQgInN0cmluZyBleHByZXNzaW9uIiBuaWwgdCAiXCJcIiIgYmFja3dhcmQtZGVsZXRlLWNoYXIg MiAiIFNFVkVSSVRZICIgIltOT1RFIHwgV0FSTklORyB8IEVSUk9SIHwgRkFJTFVSRV0iICI7Il0g NyAoIyQgLiAyMDg5NDQpIG5pbF0pCiNAMjggSW5zZXJ0IGEgcmV0dXJuIHN0YXRlbWVudC4fCihk ZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1yZXR1cm4gI1tuaWwgIlwzMDBcMzAxIVwyMTBcMzAyXDMw M1wzMDRcMzA1I1wyMDQQAFwzMDZcMzA3IVwyMTBcMzEwY1wyMDciIFt2aGRsLWluc2VydC1rZXl3 b3JkICJSRVRVUk4gIiB2aGRsLXRlbXBsYXRlLWZpZWxkICJbZXhwcmVzc2lvbl0iIG5pbCB0IGRl bGV0ZS1jaGFyIC0xICI7Il0gNCAoIyQgLiAyMDkzMzEpIG5pbF0pCiNAMzggSW5zZXJ0IGEgc2Vs ZWN0ZWQgc2lnbmFsIGFzc2lnbm1lbnQuHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtc2VsZWN0 ZWQtc2lnbmFsLWFzc3QgI1tuaWwgIlwzMDYgYFwzMDcYGRpgG1wzMTBcMzExIVwyMTALYlwyMTAp XDMxMFwzMTIhXDIxMFwzMTNcMzE0XDMxNVwzMDcJYFwzMTZcXCVcMjA1XDIyNQBcMzE3dlwyMTBc MzIwXDMxNyFcMjEwXDMyMWNcMjEwXG5cZlxcalwyMTBcMzEzXDMyMlwzMjNcIlwyMTBcMzIxY1wy MTBcblxmXFxqXDIxMFwzMTNcMzI0IVwyMTBcMzEwXDMyNSFcMjEwXDMxM1wzMjZcMzI3XCJcMjEw XDMyMWNcMjEwXG5cZlxcalwyMTAIXDIwM34AXDMxM1wzMzBcMzE1XDMwNyNcMjAzfgBcMzEwXDMy NSFcMjEwXDMxM1wzMzFcMzI3XDMwNyNcMjExEFwyMDN3AFwzMjFjXDIxMFxuXGZcXGpcMjEwXDIw MlIAXDMxMFwzMzIhXDIxMFwyMDJSAAhcMjAzXDIxMQBcMzMzIFwyMTBcMzIwXDMzNCFcMjEwXDMz NWNcMjEwDVwyMDVcMjI1AFwzMzYJYFwzMTcjK1wyMDciIFtjaG9pY2VzIHN0YXJ0IG1hcmdpbiBw b3NpdGlvbiB2aGRsLWJhc2ljLW9mZnNldCB2aGRsLWF1dG8tYWxpZ24gY3VycmVudC1pbmRlbnRh dGlvbiB0IHZoZGwtaW5zZXJ0LWtleXdvcmQgIiBTRUxFQ1QgIiAiV0lUSCAiIHZoZGwtdGVtcGxh dGUtZmllbGQgInNlbGVjdG9yIGV4cHJlc3Npb24iIG5pbCA3IDEgZGVsZXRlLWNoYXIgIlxuIiAi dGFyZ2V0IHNpZ25hbCIgIiA8PSAiICJ3YXZlZm9ybSIgIiBXSEVOICIgImNob2ljZXMiICIsIiAi W3dhdmVmb3JtXSIgIltjaG9pY2VzXSIgIk9USEVSUyIgZml4dXAtd2hpdGVzcGFjZSAtMiAiOyIg dmhkbC1hbGlnbi1ub2luZGVudC1yZWdpb25dIDcgKCMkIC4gMjA5NTc3KSBuaWxdKQojQDMwIElu c2VydCBhIHNpZ25hbCBkZWNsYXJhdGlvbi4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1zaWdu YWwgI1tuaWwgImBcMzAzIBgZXDMwNFwzMDUhXDIxMFwzMDZcMzA3XDMxMFwzMTEJYCVcMjA1RwBc MzEyY1wyMTAIXDIwMyAAXDMwNlwzMTNcMzE0XDMxMSNcMjEwXDMwNlwzMTUhXDIxMAhcMjAzMABc MzE2Y1wyMTBcMzE3IFwyMDJHAGAaXDMyMGNcMjEwXDMwNlwzMjFcMzEwXDMxMSNcMjA0QQBcbmB8 XDIxMFwzMTZjXDIxMFwzMTcgKSpcMjA3IiBbaW4tYXJnbGlzdCBzdGFydCBwb3NpdGlvbiB2aGRs LWluLWFyZ3VtZW50LWxpc3QtcCB2aGRsLWluc2VydC1rZXl3b3JkICJTSUdOQUwgIiB2aGRsLXRl bXBsYXRlLWZpZWxkICJuYW1lcyIgbmlsIHQgIiA6ICIgIltJTiB8IE9VVCB8IElOT1VUXSIgIiAi ICJ0eXBlIiAiOyIgdmhkbC1jb21tZW50LWluc2VydC1pbmxpbmUgIiA6PSAiICJbaW5pdGlhbGl6 YXRpb25dIl0gNiAoIyQgLiAyMTA0NDIpIG5pbF0pCiNAMzMgSW5zZXJ0IGEgc3VibmF0dXJlIGRl Y2xhcmF0aW9uLh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXN1Ym5hdHVyZSAjW25pbCAiYFwz MDIYGVwzMDNcMzA0IVwyMTBcMzA1XDMwNlwzMDJcMzA3CWAlXDIwNV8AXDMwM1wzMTAhXDIxMFwz MDVcMzExXDMxMlwiXDIxMFwzMDVcMzEzXDMwMlwzMDcjXDIwMykAXDMxNGNcMjEwXDIwMi0AXDMx NVwzMTYhXDIxMGAQXDMwM1wzMTchXDIxMFwzMDVcMzIwXDMwMlwzMDdcMzAyXDIxMVwzMDcmBlwz MjFcMjMyXDIwM0gACGB8XDIxMFwyMDJaAFwzMDNcMzIyIVwyMTBcMzA1XDMyM1wzMDJcMjExXDIx MVwyMTFcMzA3JgZcMjEwXDMwM1wzMjQhXDIxMFwzMjVjXDIxMFwzMjYgKlwyMDciIFtwb3NpdGlv biBzdGFydCBuaWwgdmhkbC1pbnNlcnQta2V5d29yZCAiU1VCTkFUVVJFICIgdmhkbC10ZW1wbGF0 ZS1maWVsZCAibmFtZSIgdCAiIElTICIgIm5hdHVyZSIgIiAoIiAiW2luZGV4IHJhbmdlXSIgIiki IGRlbGV0ZS1jaGFyIC0yICIgVE9MRVJBTkNFICIgIltzdHJpbmcgZXhwcmVzc2lvbl0iICJcIlwi IiAiIEFDUk9TUyAiICJzdHJpbmcgZXhwcmVzc2lvbiIgIiBUSFJPVUdIIiAiOyIgdmhkbC1jb21t ZW50LWluc2VydC1pbmxpbmVdIDcgKCMkIC4gMjEwOTM2KSBuaWxdKQojQDI3IEluc2VydCBhIHN1 YnByb2dyYW0gYm9keS4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1zdWJwcm9ncmFtLWJvZHkg I1tuaWwgIlwzMDBcMzAxXDMwMlwzMDMjXDMwND1cMjAzDQBcMzA1IFwyMDdcMzA2IFwyMDciIFt2 aGRsLWRlY2lzaW9uLXF1ZXJ5IG5pbCAiKHApcm9jZWR1cmUgb3IgKGYpdW5jdGlvbj8iIHQgMTAy IHZoZGwtdGVtcGxhdGUtZnVuY3Rpb24tYm9keSB2aGRsLXRlbXBsYXRlLXByb2NlZHVyZS1ib2R5 XSA0ICgjJCAuIDIxMTU3MykgbmlsXSkKI0AzNCBJbnNlcnQgYSBzdWJwcm9ncmFtIGRlY2xhcmF0 aW9uLh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXN1YnByb2dyYW0tZGVjbCAjW25pbCAiXDMw MFwzMDFcMzAyXDMwMyNcMzA0PVwyMDMNAFwzMDUgXDIwN1wzMDYgXDIwNyIgW3ZoZGwtZGVjaXNp b24tcXVlcnkgbmlsICIocClyb2NlZHVyZSBvciAoZil1bmN0aW9uPyIgdCAxMDIgdmhkbC10ZW1w bGF0ZS1mdW5jdGlvbi1kZWNsIHZoZGwtdGVtcGxhdGUtcHJvY2VkdXJlLWRlY2xdIDQgKCMkIC4g MjExODQxKSBuaWxdKQojQDMxIEluc2VydCBhIHN1YnR5cGUgZGVjbGFyYXRpb24uHwooZGVmYWxp YXMgJ3ZoZGwtdGVtcGxhdGUtc3VidHlwZSAjW25pbCAiYBhcMzAxXDMwMiFcMjEwXDMwM1wzMDRc MzA1XDMwNghgJVwyMDUqAFwzMDFcMzA3IVwyMTBcMzAzXDMxMFwzMTFcIlwyMTBcMzAzXDMxMlwz MDVcMzA2I1wyMDQlAFwzMTNcMzE0IVwyMTBcMzE1Y1wyMTBcMzE2IClcMjA3IiBbc3RhcnQgdmhk bC1pbnNlcnQta2V5d29yZCAiU1VCVFlQRSAiIHZoZGwtdGVtcGxhdGUtZmllbGQgIm5hbWUiIG5p bCB0ICIgSVMgIiAidHlwZSIgIiAiICJbUkFOR0UgdmFsdWUgcmFuZ2UgfCAoIGluZGV4IHJhbmdl ICldIiBkZWxldGUtY2hhciAtMSAiOyIgdmhkbC1jb21tZW50LWluc2VydC1pbmxpbmVdIDYgKCMk IC4gMjEyMTE2KSBuaWxdKQojQDMyIEluc2VydCBhIHRlcm1pbmFsIGRlY2xhcmF0aW9uLh8KKGRl ZmFsaWFzICd2aGRsLXRlbXBsYXRlLXRlcm1pbmFsICNbbmlsICJgGFwzMDFcMzAyIVwyMTBcMzAz XDMwNFwzMDVcMzA2CGAlXDIwNRwAXDMwN2NcMjEwXDMwM1wzMTAhXDIxMFwzMTFjXDIxMFwzMTIg KVwyMDciIFtzdGFydCB2aGRsLWluc2VydC1rZXl3b3JkICJURVJNSU5BTCAiIHZoZGwtdGVtcGxh dGUtZmllbGQgIm5hbWVzIiBuaWwgdCAiIDogIiAibmF0dXJlIiAiOyIgdmhkbC1jb21tZW50LWlu c2VydC1pbmxpbmVdIDYgKCMkIC4gMjEyNTE4KSBuaWxdKQojQDI4IEluc2VydCBhIHR5cGUgZGVj bGFyYXRpb24uHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtdHlwZSAjW25pbCAiYFwzMDVcMjEx XDIxMRgZGhtcMzA2XDMwNyFcMjEwXDMxMFwzMTFcMzA1XDMxMgtgJVwyMTESXDIwNVwyMzQAXDMw NlwzMTMhXDIxMFwzMTBcMzE0XDMwNVwzMTIjXDIwNiUAXDMxNVwyMjZcMjExHFwzMTVcMjMyXDIw MzcAXDMxNlwzMTchXDIxMFwzMjBjXDIxMFwyMDJcMjA1AFxmXDMyMVwyMzJcMjAzSQBcMzIyXDMy MyFcMjEwXDMyNFwzMjVcMzEyXCJcMjEwXDIwMlwyMDUAXGZcMzI2XDIzMlwyMDNfAFwzMjcgEVwz MjJcMzIzIVwyMTBcMzMwXDMyNVxuXDMxMiNcMjEwXDIwMlwyMDUAXGZcMzMxXDIzMlwyMDNwAFwz MzJjXDIxMFwzMTBcMzMzXDMyMFwiXDIxMFwyMDJcMjA1AFxmXDMzNFwyMzJcMjAzXDIwMgBcMzA2 XDMzNSFcMjEwXDMxMFwzMzNcMzIwXCJcMjEwXDIwMlwyMDUAXDMyMGNcMjEwCVwyMDNcMjIyAFwz MjcgEAliXDIxMFwzMDV/XDIxMFwzMzYgXDIxMAhcMjA1XDIzMwAIYiksXDIwNyIgW2VuZC1wb3Mg bWlkLXBvcyBuYW1lIHN0YXJ0IGRlZmluaXRpb24gbmlsIHZoZGwtaW5zZXJ0LWtleXdvcmQgIlRZ UEUgIiB2aGRsLXRlbXBsYXRlLWZpZWxkICJuYW1lIiB0ICIgSVMgIiAiW3NjYWxhciB0eXBlIHwg QVJSQVkgfCBSRUNPUkQgfCBBQ0NFU1MgfCBGSUxFXSIgIiIgYmFja3dhcmQtZGVsZXRlLWNoYXIg NCAiOyIgIkFSUkFZIiBraWxsLXdvcmQgLTEgdmhkbC10ZW1wbGF0ZS1hcnJheSB0eXBlICJSRUNP UkQiIHBvaW50LW1hcmtlciB2aGRsLXRlbXBsYXRlLXJlY29yZCAiQUNDRVNTIiAiICIgInR5cGUi ICJGSUxFIiAiIE9GICIgdmhkbC1jb21tZW50LWluc2VydC1pbmxpbmVdIDcgKCMkIC4gMjEyODIx KSBuaWxdKQojQDIyIEluc2VydCBhIHVzZSBjbGF1c2UuHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxh dGUtdXNlICNbbmlsICJgXDMwNRgZXDMwNhpcMzA3XDMxMFwzMTELI1wyMTBcMzEyXDMxMyFcMjEw XDIxMlwzMTR5XDIxMFwzMTVcMzE2ISlcMjA1OABcMzEyXDMxNyFcMjEwXDMyMFwzMjEhXDIxMFwz MjJcMzIzXDMwNlwzMDUJYFwzMjFcXCVcMjA1OABcMzI0dVwyMTBcMzIyXDMyNSFcMjEwXDMyNnUS XGZcMjA0QwBcMzA3XDMxMFwzMjcLI1wyMTBcbitcMjA3IiBbY2FzZS1mb2xkLXNlYXJjaCBzdGFy dCByZXN1bHQgdmhkbC1tb2RlLXN5bnRheC10YWJsZSB2aGRsLXVuZGVyc2NvcmUtaXMtcGFydC1v Zi13b3JkIHQgbmlsIG1vZGlmeS1zeW50YXgtZW50cnkgOTUgInciIHZoZGwtaW5zZXJ0LWtleXdv cmQgIlVTRSAiIDAgbG9va2luZy1hdCAiXlxccy0qdXNlXFw+IiAiLi5BTEw7IiBiYWNrd2FyZC1j aGFyIDYgdmhkbC10ZW1wbGF0ZS1maWVsZCAibGlicmFyeSBuYW1lIiAxICJwYWNrYWdlIG5hbWUi IDUgIl8iXSA3ICgjJCAuIDIxMzcwNikgbmlsXSkKI0AzMiBJbnNlcnQgYSB2YXJpYWJsZSBkZWNs YXJhdGlvbi4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS12YXJpYWJsZSAjW25pbCAiYFwzMDZc MzA3IBgZGlwzMTAbXDMxMVwzMTJcMzEzXGYjXDIxMFwyMTJcMzE0XDMxNVwzMTBcMzA2I1wyMDUg AFwzMTZcMzE3IVwyMTBcMzIwXDMyMSE/KVwyMDQwAFwyMTJcMzE2XDMxNyFcMjEwXDMyMFwzMjIh KVwyMDM2AFwzMjNcMzI0IVwyMDI5AFwzMjNcMzI1IRMNXDIwNEQAXDMxMVwzMTJcMzI2XGYjXDIx MClcMzI3XDMzMFwzMTBcMzA2XG5gJVwyMDVcMjA1AFwzMzFjXDIxMAhcMjAzXFwAXDMyN1wzMzJc MzMzXDMwNiNcMjEwXDMyN1wzMzQhXDIxMAhcMjAzbABcMzM1Y1wyMTBcMzM2IFwyMDJcMjA1AGAe IVwzMzdjXDIxMFwzMjdcMzQwXDMxMFwzMDYjXDIwNH8ADiFgfFwyMTBcMzM1Y1wyMTBcMzM2ICkr XDIwNyIgW2luLWFyZ2xpc3QgY2FzZS1mb2xkLXNlYXJjaCBzdGFydCByZXN1bHQgdmhkbC1tb2Rl LXN5bnRheC10YWJsZSB2aGRsLXVuZGVyc2NvcmUtaXMtcGFydC1vZi13b3JkIHQgdmhkbC1pbi1h cmd1bWVudC1saXN0LXAgbmlsIG1vZGlmeS1zeW50YXgtZW50cnkgOTUgInciIHJlLXNlYXJjaC1i YWNrd2FyZCAiXFw8ZnVuY3Rpb25cXHxwcm9jZWR1cmVcXHxwcm9jZXNzXFx8cHJvY2VkdXJhbFxc fGVuZFxcPiIgYmFja3dhcmQtd29yZCAxIGxvb2tpbmctYXQgIlxcPGVuZFxcPiIgIlxcPHNoYXJl ZFxcPiIgdmhkbC1pbnNlcnQta2V5d29yZCAiVkFSSUFCTEUgIiAiU0hBUkVEIFZBUklBQkxFICIg Il8iIHZoZGwtdGVtcGxhdGUtZmllbGQgIm5hbWVzIiAiIDogIiAiW0lOIHwgT1VUIHwgSU5PVVRd IiAiICIgInR5cGUiICI7IiB2aGRsLWNvbW1lbnQtaW5zZXJ0LWlubGluZSAiIDo9ICIgIltpbml0 aWFsaXphdGlvbl0iIHBvc2l0aW9uXSA2ICgjJCAuIDIxNDI0MSkgbmlsXSkKI0AyNiBJbnNlcnQg YSB3YWl0IHN0YXRlbWVudC4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS13YWl0ICNbbmlsICJc MzAwXDMwMSFcMjEwXDMwMlwzMDNcMzA0XDMwNSNcMjA0EABcMzA2XDMwNyFcMjEwXDMxMGNcMjA3 IiBbdmhkbC1pbnNlcnQta2V5d29yZCAiV0FJVCAiIHZoZGwtdGVtcGxhdGUtZmllbGQgIltPTiBz ZW5zaXRpdml0eSBsaXN0XSBbVU5USUwgY29uZGl0aW9uXSBbRk9SIHRpbWUgZXhwcmVzc2lvbl0i IG5pbCB0IGRlbGV0ZS1jaGFyIC0xICI7Il0gNCAoIyQgLiAyMTUxNjgpIG5pbF0pCiNANDYgSW5k ZW50IGNvcnJlY3RseSBpZiB3aXRoaW4gYSBjYXNlIHN0YXRlbWVudC4fCihkZWZhbGlhcyAndmhk bC10ZW1wbGF0ZS13aGVuICNbbmlsICJgXDMwNlwzMDcYGRpcMzA3G1wzMTBcMzExXDMxMlxmI1wy MTBpXDMxMyBVXDIwMzMAXDMxNFwzMTVcMzA3XDMwNiNcMjAzMwBcMzE2XDMxNyFcMjAzMwBcMzEz IBBcbmJcMjEwXDMyMCBcMjEwCA1cXGpcMjAyNQBcbmITDhRcMjA0QQBcMzEwXDMxMVwzMjFcZiNc MjEwKVwzMjJcMzIzIStcMjA3IiBbbWFyZ2luIGNhc2UtZm9sZC1zZWFyY2ggcG9zaXRpb24gcmVz dWx0IHZoZGwtbW9kZS1zeW50YXgtdGFibGUgdmhkbC1iYXNpYy1vZmZzZXQgdCBuaWwgbW9kaWZ5 LXN5bnRheC1lbnRyeSA5NSAidyIgY3VycmVudC1pbmRlbnRhdGlvbiByZS1zZWFyY2gtZm9yd2Fy ZCAiXFw8ZW5kXFw+IiBsb29raW5nLWF0ICJcXHMtKlxcPGNhc2VcXD4iIGRlbGV0ZS1ob3Jpem9u dGFsLXNwYWNlICJfIiB2aGRsLWluc2VydC1rZXl3b3JkICJXSEVOICIgdmhkbC11bmRlcnNjb3Jl LWlzLXBhcnQtb2Ytd29yZF0gNCAoIyQgLiAyMTU0NTcpIG5pbF0pCiNAMjIgSW5zZXJ0IGEgd2hp bGUgbG9vcC4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS13aGlsZS1sb29wICNbbmlsICJcMzA2 IBhgGVwzMDcaC1wzMTA9XDIwNBQAXDMxMVwzMTIhXDIxMFwyMDIvAFwzMTFcMzEzIVwyMTAJYlwy MTBcMzE0XDMxNVwzMDdcMzE2I1wyMTESXDIwNCkAXDMxN1wzMjAhXDIxMFwzMjF2XDIxMFwzMjF1 XDIxMFxmXDIwMzYAXDMyMmNcMjEwXDMxNFwzMjNcMzA3XDMxNglgJVwyMDVnAFxmXDIwM0cAXDMy NGNcMjEwXDMxMVwzMjUhXDIxMAhqXDIxMFwzMTFcMzI2IVwyMTBcblwyMDNdAFwzMjdcblwzMzBR XDIwMl4AXDMzMGNcMjEwXDMzMXlcMjEwCA1cXGorXDIwNyIgW21hcmdpbiBzdGFydCBsYWJlbCB2 aGRsLW9wdGlvbmFsLWxhYmVscyB2aGRsLWNvbmRpdGlvbnMtaW4tcGFyZW50aGVzaXMgdmhkbC1i YXNpYy1vZmZzZXQgY3VycmVudC1pbmRlbnRhdGlvbiBuaWwgYWxsIHZoZGwtaW5zZXJ0LWtleXdv cmQgIldISUxFICIgIjogV0hJTEUgIiB2aGRsLXRlbXBsYXRlLWZpZWxkICJbbGFiZWxdIiB0IGRl bGV0ZS1jaGFyIDIgMSAiKCIgImNvbmRpdGlvbiIgIikiICIgTE9PUFxuXG4iICJFTkQgTE9PUCIg IiAiICI7IiAtMV0gNyAoIyQgLiAyMTYwMTgpIG5pbF0pCiNANjAgSW5zZXJ0IGEgd2l0aCBzdGF0 ZW1lbnQgKGkuZS4gc2VsZWN0ZWQgc2lnbmFsIGFzc2lnbm1lbnQpLh8KKGRlZmFsaWFzICd2aGRs LXRlbXBsYXRlLXdpdGggI1tuaWwgIlwzMDQYXDMwNRlcMzA2XDMwN1wzMTBcbiNcMjEwXDIxMlwz MTFcMzEyIVwyMTBcMzEzXDMxNCFcMzE1XDIzMilcMjAzHQBcMzE2IFwyMDIgAFwzMTdcMzIwIREL XDIwNCsAXDMwNlwzMDdcMzIxXG4jXDIxMAkqXDIwNyIgW2Nhc2UtZm9sZC1zZWFyY2ggcmVzdWx0 IHZoZGwtbW9kZS1zeW50YXgtdGFibGUgdmhkbC11bmRlcnNjb3JlLWlzLXBhcnQtb2Ytd29yZCB0 IG5pbCBtb2RpZnktc3ludGF4LWVudHJ5IDk1ICJ3IiByZS1zZWFyY2gtYmFja3dhcmQgIlxcKFxc PGxpbWl0XFw+XFx8O1xcKSIgbWF0Y2gtc3RyaW5nIDEgIjsiIHZoZGwtdGVtcGxhdGUtc2VsZWN0 ZWQtc2lnbmFsLWFzc3QgdmhkbC1pbnNlcnQta2V5d29yZCAiV0lUSCAiICJfIl0gNCAoIyQgLiAy MTY2MzkpIG5pbF0pCiNANTYgSW5zZXJ0IGEgd2FpdCBzdGF0ZW1lbnQgZm9yIHJpc2luZy9mYWxs aW5nIGNsb2NrIGVkZ2UuHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtY2xvY2tlZC13YWl0ICNb bmlsICJgXDMwNhgZXDMwN1wzMTAhXDIxMFxuXDMxMVwyMzJcMjA0FQBcbmNcMjEwXG5cMjA2HABc MzEyXDMxM1wzMDZcMzE0CWAlXDIxMRBcMjA1RgBcMzE1Y1wyMTBcMzA3XDMxNiFcMjEwCGNcMjEw XDMxNwtcMjAzNABcZlwyMDI1AA1cMzIwXDI2MQNcMjEwXDMyMQtcMjAzQgBcMzIyXDIwMkMAXDMy M1wzMjRQISpcMjA3IiBbY2xvY2sgc3RhcnQgdmhkbC1jbG9jay1uYW1lIHZoZGwtY2xvY2stcmlz aW5nLWVkZ2UgdmhkbC1vbmUtc3RyaW5nIHZoZGwtemVyby1zdHJpbmcgbmlsIHZoZGwtaW5zZXJ0 LWtleXdvcmQgIldBSVQgVU5USUwgIiAiIiB2aGRsLXRlbXBsYXRlLWZpZWxkICJjbG9jayBuYW1l IiB0ICInZXZlbnQiICIgQU5EICIgIiA9ICIgIjsiIHZoZGwtY29tbWVudC1pbnNlcnQtaW5saW5l ICJyaXNpbmciICJmYWxsaW5nIiAiIGNsb2NrIGVkZ2UiXSA2ICgjJCAuIDIxNzEzMSkgbmlsXSkK I0A1NyBJbnNlcnQgYSB0ZW1wbGF0ZSBmb3IgdGhlIGJvZHkgb2YgYSBzZXF1ZW50aWFsIHByb2Nl c3MuHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtc2VxLXByb2Nlc3MgI1soY2xvY2sgcmVzZXQp ICJcMzA2IFwzMDcYGVwzMTBcMzExIVwyMTBcblwzMTI9XDIwM0YAC1wzMTNcZlwyMDMZAA1cMjAy GwAOJVwyNjEDXDIxMFwzMTBcMzE0IVwyMTBcMzE1XDMxNlxmXDIwMywAXDMxN1wyMDItAFwzMjBc MzIxUSFcMjEwXDMyMmNcMjEwCQ4mXFxqXDIxMGAQXDMyMmNcMjEwCWpcMjEwXDMxMFwzMjMhXDIx MA4nXDMyND1cMjAzYQAOKFwyMDNWAFwzMjVcMjAyVwBcMzI2XDMyNw4pXDMyMVwyNjEEXDIxMFwy MDJ8AA4pXDMzMFwyNjECXDIxMFwzMTBcMzMxIVwyMTAOKVwzMTMOKFwyMDN3AA1cMjAyeQAOJVwy NjEDXDIxMFwzMTBcMzE0IVwyMTBcMzE1DihcMjAzXDIxMgBcMzI1XDIwMlwyMTMAXDMyNlwzMzJQ IVwyMTBcMzIyY1wyMTAJDiZcXGpcMjEwXG5cMzMzPVwyMDMRAVwzMTBcMzExIVwyMTAOKlwzMzRc MjMyXDIwNFwyNjIADipjXDIxMA4qXDIwNlwyNzEAXDMzNVwzMzYhXDIwNlwyNzEAXDMzNxNcMzEz XGZcMjAzXDMwMwANXDIwMlwzMDUADiVcMjYxAlwyMTBcMzEwXDMxNCFcMjEwXDMxNVwzNDBcZlwy MDNcMzI2AFwzMTdcMjAyXDMyNwBcMzIwXDMyMVEhXDIxMFwzMjJjXDIxMAkOJlwyMTFcXFwzNDFc XFxcalwyMTBgEFwzMjJjXDIxMAkOJlxcalwyMTBcMzEwXDM0MiFcMjEwXDMyMmNcMjEwCQ4mXDIx MVxcXDM0MVxcXFxqXDIxMFwzMjJjXDIxMAkOJlxcalwyMTBcMzEwXDM0MyFcMjEwXG5cMzQ0PVwy MDMZAWAQXDMyMmNcMjEwCWpcMjEwXDMxMFwzNDMhXDIxMAhiXDIxMAsqXDIwNyIgW3Bvc2l0aW9u IG1hcmdpbiB2aGRsLXJlc2V0LWtpbmQgcmVzZXQgdmhkbC1yZXNldC1hY3RpdmUtaGlnaCB2aGRs LW9uZS1zdHJpbmcgY3VycmVudC1pbmRlbnRhdGlvbiBuaWwgdmhkbC1pbnNlcnQta2V5d29yZCAi SUYgIiBhc3luYyAiID0gIiAiIFRIRU4iIHZoZGwtY29tbWVudC1pbnNlcnQtaW5saW5lICJhc3lu Y2hyb25vdXMgcmVzZXQgKGFjdGl2ZSAiICJoaWdoIiAibG93IiAiKSIgIlxuIiAiRUxTSUYgIiBm dW5jdGlvbiAicmlzaW5nIiAiZmFsbGluZyIgIl9lZGdlKCIgIidldmVudCIgIiBBTkQgIiAiIGNs b2NrIGVkZ2UiIHN5bmMgIiIgdmhkbC10ZW1wbGF0ZS1maWVsZCAicmVzZXQgbmFtZSIgIjxyZXNl dD4iICJzeW5jaHJvbm91cyByZXNldCAoYWN0aXZlICIgMCAiRUxTRSIgIkVORCBJRjsiIG5vbmUg dmhkbC16ZXJvLXN0cmluZyB2aGRsLWJhc2ljLW9mZnNldCB2aGRsLWNsb2NrLWVkZ2UtY29uZGl0 aW9uIHZoZGwtY2xvY2stcmlzaW5nLWVkZ2UgY2xvY2sgdmhkbC1yZXNldC1uYW1lXSA0ICgjJCAu IDIxNzY4OCldKQojQDEwMSBJbnNlcnQgc3BlY2lmaWNhdGlvbiBvZiBhIHN0YW5kYXJkIHBhY2th Z2UuICBJbmNsdWRlIGEgbGlicmFyeQpzcGVjaWZpY2F0aW9uLCBpZiBub3QgYWxyZWFkeSB0aGVy ZS4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1zdGFuZGFyZC1wYWNrYWdlICNbKGxpYnJhcnkg cGFja2FnZSkgIlwzMDYgXDMwNxgZXDIxMlwzMTAaXDMxMVwzMTJcMzEzCyNcMjEwbz9cMjA1GwBc MzE0XDMxNVxmXDMxNlFcMzEwXDMwNyMSDVwyMDQmAFwzMTFcMzEyXDMxNwsjXDIxMCpcMzIwXDMy MSFcMjAzNgBcMzIyXDMyM1wzMjBcMzIxIVwiXDIwNEIAXDMyNFwzMjUhXDIxMFxmXDMyNlwyNjEC XDIxMAlqXDIxMFwzMjRcMzI3IVwyMTBcZlwzMzAOGlwyNjEDXDIxMFwzMjRcMzMxISpcMjA3IiBb Y2FzZS1mb2xkLXNlYXJjaCBtYXJnaW4gcmVzdWx0IHZoZGwtbW9kZS1zeW50YXgtdGFibGUgbGli cmFyeSB2aGRsLXVuZGVyc2NvcmUtaXMtcGFydC1vZi13b3JkIGN1cnJlbnQtaW5kZW50YXRpb24g dCBuaWwgbW9kaWZ5LXN5bnRheC1lbnRyeSA5NSAidyIgcmUtc2VhcmNoLWJhY2t3YXJkICJeXFxz LSpcXChsaWJyYXJ5XFxzLStcXChcXChcXHdcXHxcXHNfXFwpKyxcXHMtK1xcKSoiICJcXHxlbmRc XClcXD4iICJfIiBtYXRjaC1zdHJpbmcgMSBzdHJpbmctbWF0Y2ggImxpYnJhcnkiIHZoZGwtaW5z ZXJ0LWtleXdvcmQgIkxJQlJBUlkgIiAiO1xuIiAiVVNFICIgIi4iICIuQUxMOyIgcGFja2FnZV0g NCAoIyQgLiAyMTkwNjgpXSkKI0A0OSBJbnNlcnQgc3BlY2lmaWNhdGlvbiBvZiBgbWF0aF9jb21w bGV4JyBwYWNrYWdlLh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXBhY2thZ2UtbWF0aC1jb21w bGV4ICNbbmlsICJcMzAwXDMwMVwzMDJcIlwyMDciIFt2aGRsLXRlbXBsYXRlLXN0YW5kYXJkLXBh Y2thZ2UgImllZWUiICJtYXRoX2NvbXBsZXgiXSAzICgjJCAuIDIxOTgxNSkgbmlsXSkKI0A0NiBJ bnNlcnQgc3BlY2lmaWNhdGlvbiBvZiBgbWF0aF9yZWFsJyBwYWNrYWdlLh8KKGRlZmFsaWFzICd2 aGRsLXRlbXBsYXRlLXBhY2thZ2UtbWF0aC1yZWFsICNbbmlsICJcMzAwXDMwMVwzMDJcIlwyMDci IFt2aGRsLXRlbXBsYXRlLXN0YW5kYXJkLXBhY2thZ2UgImllZWUiICJtYXRoX3JlYWwiXSAzICgj JCAuIDIyMDAxOSkgbmlsXSkKI0A0OCBJbnNlcnQgc3BlY2lmaWNhdGlvbiBvZiBgbnVtZXJpY19i aXQnIHBhY2thZ2UuHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtcGFja2FnZS1udW1lcmljLWJp dCAjW25pbCAiXDMwMFwzMDFcMzAyXCJcMjA3IiBbdmhkbC10ZW1wbGF0ZS1zdGFuZGFyZC1wYWNr YWdlICJpZWVlIiAibnVtZXJpY19iaXQiXSAzICgjJCAuIDIyMDIxNCkgbmlsXSkKI0A0OCBJbnNl cnQgc3BlY2lmaWNhdGlvbiBvZiBgbnVtZXJpY19zdGQnIHBhY2thZ2UuHwooZGVmYWxpYXMgJ3Zo ZGwtdGVtcGxhdGUtcGFja2FnZS1udW1lcmljLXN0ZCAjW25pbCAiXDMwMFwzMDFcMzAyXCJcMjA3 IiBbdmhkbC10ZW1wbGF0ZS1zdGFuZGFyZC1wYWNrYWdlICJpZWVlIiAibnVtZXJpY19zdGQiXSAz ICgjJCAuIDIyMDQxNSkgbmlsXSkKI0A1MSBJbnNlcnQgc3BlY2lmaWNhdGlvbiBvZiBgc3RkX2xv Z2ljXzExNjQnIHBhY2thZ2UuHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtcGFja2FnZS1zdGQt bG9naWMtMTE2NCAjW25pbCAiXDMwMFwzMDFcMzAyXCJcMjA3IiBbdmhkbC10ZW1wbGF0ZS1zdGFu ZGFyZC1wYWNrYWdlICJpZWVlIiAic3RkX2xvZ2ljXzExNjQiXSAzICgjJCAuIDIyMDYxNikgbmls XSkKI0A1MiBJbnNlcnQgc3BlY2lmaWNhdGlvbiBvZiBgc3RkX2xvZ2ljX2FyaXRoJyBwYWNrYWdl Lh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXBhY2thZ2Utc3RkLWxvZ2ljLWFyaXRoICNbbmls ICJcMzAwXDMwMVwzMDJcIlwyMDciIFt2aGRsLXRlbXBsYXRlLXN0YW5kYXJkLXBhY2thZ2UgImll ZWUiICJzdGRfbG9naWNfYXJpdGgiXSAzICgjJCAuIDIyMDgyNikgbmlsXSkKI0A1MSBJbnNlcnQg c3BlY2lmaWNhdGlvbiBvZiBgc3RkX2xvZ2ljX21pc2MnIHBhY2thZ2UuHwooZGVmYWxpYXMgJ3Zo ZGwtdGVtcGxhdGUtcGFja2FnZS1zdGQtbG9naWMtbWlzYyAjW25pbCAiXDMwMFwzMDFcMzAyXCJc MjA3IiBbdmhkbC10ZW1wbGF0ZS1zdGFuZGFyZC1wYWNrYWdlICJpZWVlIiAic3RkX2xvZ2ljX21p c2MiXSAzICgjJCAuIDIyMTAzOSkgbmlsXSkKI0A1MyBJbnNlcnQgc3BlY2lmaWNhdGlvbiBvZiBg c3RkX2xvZ2ljX3NpZ25lZCcgcGFja2FnZS4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1wYWNr YWdlLXN0ZC1sb2dpYy1zaWduZWQgI1tuaWwgIlwzMDBcMzAxXDMwMlwiXDIwNyIgW3ZoZGwtdGVt cGxhdGUtc3RhbmRhcmQtcGFja2FnZSAiaWVlZSIgInN0ZF9sb2dpY19zaWduZWQiXSAzICgjJCAu IDIyMTI0OSkgbmlsXSkKI0A1MyBJbnNlcnQgc3BlY2lmaWNhdGlvbiBvZiBgc3RkX2xvZ2ljX3Rl eHRpbycgcGFja2FnZS4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1wYWNrYWdlLXN0ZC1sb2dp Yy10ZXh0aW8gI1tuaWwgIlwzMDBcMzAxXDMwMlwiXDIwNyIgW3ZoZGwtdGVtcGxhdGUtc3RhbmRh cmQtcGFja2FnZSAiaWVlZSIgInN0ZF9sb2dpY190ZXh0aW8iXSAzICgjJCAuIDIyMTQ2NSkgbmls XSkKI0A1NSBJbnNlcnQgc3BlY2lmaWNhdGlvbiBvZiBgc3RkX2xvZ2ljX3Vuc2lnbmVkJyBwYWNr YWdlLh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXBhY2thZ2Utc3RkLWxvZ2ljLXVuc2lnbmVk ICNbbmlsICJcMzAwXDMwMVwzMDJcIlwyMDciIFt2aGRsLXRlbXBsYXRlLXN0YW5kYXJkLXBhY2th Z2UgImllZWUiICJzdGRfbG9naWNfdW5zaWduZWQiXSAzICgjJCAuIDIyMTY4MSkgbmlsXSkKI0A0 MyBJbnNlcnQgc3BlY2lmaWNhdGlvbiBvZiBgdGV4dGlvJyBwYWNrYWdlLh8KKGRlZmFsaWFzICd2 aGRsLXRlbXBsYXRlLXBhY2thZ2UtdGV4dGlvICNbbmlsICJcMzAwXDMwMVwzMDJcIlwyMDciIFt2 aGRsLXRlbXBsYXRlLXN0YW5kYXJkLXBhY2thZ2UgInN0ZCIgInRleHRpbyJdIDMgKCMkIC4gMjIx OTAzKSBuaWxdKQojQDE5IEluc2VydCBkaXJlY3RpdmUuHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxh dGUtZGlyZWN0aXZlICNbKGRpcmVjdGl2ZSkgIlwzMDEgaVVcMjA0DQBcMzAyIFwyMTBcMzAzY1wy MTBcMzA0CFwyNjECXDIwNyIgW2RpcmVjdGl2ZSBjdXJyZW50LWluZGVudGF0aW9uIGRlbGV0ZS1o b3Jpem9udGFsLXNwYWNlICIgICIgIi0tIHByYWdtYSAiXSAyICgjJCAuIDIyMjA4OCldKQojQDM0 IEluc2VydCBkaXJlY3RpdmUgJ3RyYW5zbGF0ZV9vbicuHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxh dGUtZGlyZWN0aXZlLXRyYW5zbGF0ZS1vbiAjW25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwtdGVt cGxhdGUtZGlyZWN0aXZlICJ0cmFuc2xhdGVfb24iXSAyICgjJCAuIDIyMjMwMSkgbmlsXSkKI0Az NSBJbnNlcnQgZGlyZWN0aXZlICd0cmFuc2xhdGVfb2ZmJy4fCihkZWZhbGlhcyAndmhkbC10ZW1w bGF0ZS1kaXJlY3RpdmUtdHJhbnNsYXRlLW9mZiAjW25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwt dGVtcGxhdGUtZGlyZWN0aXZlICJ0cmFuc2xhdGVfb2ZmIl0gMiAoIyQgLiAyMjI0NzMpIG5pbF0p CiNAMzQgSW5zZXJ0IGRpcmVjdGl2ZSAnc3ludGhlc2lzX29uJy4fCihkZWZhbGlhcyAndmhkbC10 ZW1wbGF0ZS1kaXJlY3RpdmUtc3ludGhlc2lzLW9uICNbbmlsICJcMzAwXDMwMSFcMjA3IiBbdmhk bC10ZW1wbGF0ZS1kaXJlY3RpdmUgInN5bnRoZXNpc19vbiJdIDIgKCMkIC4gMjIyNjQ4KSBuaWxd KQojQDM1IEluc2VydCBkaXJlY3RpdmUgJ3N5bnRoZXNpc19vZmYnLh8KKGRlZmFsaWFzICd2aGRs LXRlbXBsYXRlLWRpcmVjdGl2ZS1zeW50aGVzaXMtb2ZmICNbbmlsICJcMzAwXDMwMSFcMjA3IiBb dmhkbC10ZW1wbGF0ZS1kaXJlY3RpdmUgInN5bnRoZXNpc19vZmYiXSAyICgjJCAuIDIyMjgyMCkg bmlsXSkKI0AxOCBJbmRlbnQgY29tbWVudHMuHwooZGVmYWxpYXMgJ3ZoZGwtY29tbWVudC1pbmRl bnQgI1tuaWwgImAYXDMwM3lcMjEwXDMwNFwzMDUIXDMwNiNcMjAzEwBpXDMwN1pcMjAyHgAIYlwy MTBcMzEwXDMxMXhcMjEwCWlUXRoIYlwyMTBcbipcMjA3IiBbcG9zaXRpb24gY29tbWVudC1jb2x1 bW4gY29sIC0xIHJlLXNlYXJjaC1mb3J3YXJkICItLSIgdCAyICIgCSIgbmlsXSA0ICgjJCAuIDIy Mjk5NSldKQojQDE1MyBTdGFydCBhIGNvbW1lbnQgYXQgdGhlIGVuZCBvZiB0aGUgbGluZS4KSWYg b24gbGluZSB3aXRoIGNvZGUsIGluZGVudCBhdCBsZWFzdCBgY29tbWVudC1jb2x1bW4nLgpJZiBz dGFydGluZyBhZnRlciBlbmQtY29tbWVudC1jb2x1bW4sIHN0YXJ0IGEgbmV3IGxpbmUuHwooZGVm YWxpYXMgJ3ZoZGwtY29tbWVudC1pbnNlcnQgI1tuaWwgImkIVlwyMDMJAFwzMDYgXDIxMFwzMDdc MzEwIVwyMDQYAAlcMjA0SwBcMzExf1wyMDRLAFwzMTEaaFwzMTJVXDIwMycAXDMxM1wzMTQhXDIx MFwyMDIaAGkSXDMxNSBcMjEwblwyMDM5AFxualwyMTBcMzE2Y1wyMTBcMjAyQgBcMzE3Y1wyMTAL alwyMTBcMzE2Y1wyMTAJP1wyMDVJAFwzMjBjKVwyMDdcMzExXDIxMRwdaFwzMTJVXDIwM1xcAFwz MTNcMzIxIVwyMTBcMjAyTwBcMzIyIFwyMTEVXDMyM1VcMjAzdwBcMzE2Y1wyMTBcMzIxdVwyMTBc MzI0eVwyMTBcMzI1XDMyNiFcMjEwXDMyNxRcMjAyXFwAXGZcMjA0fgBcMzE2Y1wyMTBcMzMwDSFD XDIxMREqXDIwNyIgW2VuZC1jb21tZW50LWNvbHVtbiB1bnJlYWQtY29tbWFuZC1ldmVudHMgbWFy Z2luIGNvbW1lbnQtY29sdW1uIGNvZGUgbmV4dC1pbnB1dCBuZXdsaW5lLWFuZC1pbmRlbnQgbG9v a2luZy1hdCAiXFxzLSokIiBuaWwgNDUgZGVsZXRlLWNoYXIgLTEgZGVsZXRlLWhvcml6b250YWwt c3BhY2UgIi0tIiAiICAiICIgIiAtMiByZWFkLWNoYXIgMTMgMSBtZXNzYWdlICJFbnRlciBDUiBp ZiBjb21tZW50aW5nIG91dCBhIGxpbmUgb2YgY29kZS4iIHQgdmhkbC1jaGFyYWN0ZXItdG8tZXZl bnRdIDIgKCMkIC4gMjIzMjI2KSBuaWxdKQojQDcwIEFkZCAyIGNvbW1lbnQgbGluZXMgYXQgdGhl IGN1cnJlbnQgaW5kZW50LCBtYWtpbmcgYSBkaXNwbGF5IGNvbW1lbnQuHwooZGVmYWxpYXMgJ3Zo ZGwtY29tbWVudC1kaXNwbGF5ICNbKCZvcHRpb25hbCBsaW5lLWV4aXN0cykgIlwzMDIgGAlcMjA0 XG4AXDMwMyBcMjEwXDMwNGNcMjEwCGpcMjEwXDMwNGNcMjEwCGpcMjEwXDMwMyBcMjEwXDMwNX9c MjEwXDMwNmMpXDIwNyIgW21hcmdpbiBsaW5lLWV4aXN0cyBjdXJyZW50LWluZGVudGF0aW9uIHZo ZGwtY29tbWVudC1kaXNwbGF5LWxpbmUgIlxuIiAwICItLSAiXSAxICgjJCAuIDIyNDA0MSkgbmls XSkKI0AzMCBEaXNwbGF5cyBvbmUgbGluZSBvZiBkYXNoZXMuHwooZGVmYWxpYXMgJ3ZoZGwtY29t bWVudC1kaXNwbGF5LWxpbmUgI1tuaWwgImhcMzAzVVwyMDMNAFwzMDRcMzA1IVwyMTBcMjAyAABp GAkIWhpcMzA2XDMwM1xuXCIqXDIwNyIgW2NvbCBlbmQtY29tbWVudC1jb2x1bW4gbGVuIDQ1IGRl bGV0ZS1jaGFyIC0yIGluc2VydC1jaGFyXSAzICgjJCAuIDIyNDM2MCkgbmlsXSkKI0A0NiBBcHBl bmQgZW1wdHkgaW5saW5lIGNvbW1lbnQgdG8gY3VycmVudCBsaW5lLh8KKGRlZmFsaWFzICd2aGRs LWNvbW1lbnQtYXBwZW5kLWlubGluZSAjW25pbCAiXDMwMX9cMjEwXDMwMiBcMjEwXDMwM2NcMjEw CGpcMjEwXDMwNGNcMjA3IiBbY29tbWVudC1jb2x1bW4gbmlsIGRlbGV0ZS1ob3Jpem9udGFsLXNw YWNlICIgICIgIi0tICJdIDEgKCMkIC4gMjI0NTc2KSBuaWxdKQojQDI0IEluc2VydCBpbmxpbmUg Y29tbWVudC4fCihkZWZhbGlhcyAndmhkbC1jb21tZW50LWluc2VydC1pbmxpbmUgI1soJm9wdGlv bmFsIHN0cmluZyBhbHdheXMtaW5zZXJ0KSAiCFwyMDNcZgAJXDIwNBUAXG5cMjA0FQAIP1wyMDVP AAtcMjA1TwBgHFwzMDZjXDIxMA1qXDIxMFwzMDdjXDIxMAhcMjAzKgAIY1wyMTBcMjAyMgBcMzEw XDMxMVwzMTJcMzEzI1wyMDNLAGkOD1ZcMjA1TgBcMzE0IBRcMzE1XDMwNyFcMjEwXDMxNmNcMjEw DWpcMjEwXGZiXDIwMk4AXGZgfClcMjA3IiBbc3RyaW5nIHZoZGwtc2VsZi1pbnNlcnQtY29tbWVu dHMgYWx3YXlzLWluc2VydCB2aGRsLXByb21wdC1mb3ItY29tbWVudHMgcG9zaXRpb24gY29tbWVu dC1jb2x1bW4gIiAgIiAiLS0gIiB2aGRsLXRlbXBsYXRlLWZpZWxkICJbY29tbWVudF0iIG5pbCB0 IHBvaW50LW1hcmtlciByZS1zZWFyY2gtYmFja3dhcmQgIlxuIiBlbmQtY29tbWVudC1jb2x1bW5d IDQgKCMkIC4gMjI0Nzk0KV0pCiNAMzIgSW5zZXJ0IGNvbW1lbnQgZm9yIGNvZGUgYmxvY2suHwoo ZGVmYWxpYXMgJ3ZoZGwtY29tbWVudC1ibG9jayAjW25pbCAiCFwyMDVdAFwzMDYgXDMwNxkaXDMx MBtcMzExXDMxMlwzMTNcZiNcMjEwXDMxNFwzMTVcMzEwXDMwNyNcMjA1TQBcMzE0XDMxNlwzMTBc MzA3I1wyMDVNAFwzMTAdXDMxNyBcMjEwaRVcMzIwf1wyMTBvXDIwMzgAXDMyMWNcMjEwXDMyMnlc MjEwXDIwMjsAXDMyMWNcMjEwDWpcMjEwXDMyM2NcMjEwXDMyNFwzMjVcMzEwXDMwNyM/XDIwNUwA XDMyNiApEw4YXDIwNFkAXDMxMVwzMTJcMzI3XGYjXDIxMClcbmIqXDIwNyIgW3ZoZGwtcHJvbXB0 LWZvci1jb21tZW50cyBjYXNlLWZvbGQtc2VhcmNoIGZpbmFsLXBvcyByZXN1bHQgdmhkbC1tb2Rl LXN5bnRheC10YWJsZSBtYXJnaW4gcG9pbnQtbWFya2VyIHQgbmlsIG1vZGlmeS1zeW50YXgtZW50 cnkgOTUgInciIHJlLXNlYXJjaC1iYWNrd2FyZCAiXlxccy0qYmVnaW5cXD4iICJcXDxcXChhcmNo aXRlY3R1cmVcXHxibG9ja1xcfGZ1bmN0aW9uXFx8cHJvY2VkdXJlXFx8cHJvY2Vzc1xcfHByb2Nl ZHVyYWxcXClcXD4iIGJhY2stdG8taW5kZW50YXRpb24gMCAiXG4iIC0xICItLSBwdXJwb3NlOiAi IHZoZGwtdGVtcGxhdGUtZmllbGQgIltkZXNjcmlwdGlvbl0iIHZoZGwtbGluZS1raWxsLWVudGly ZSAiXyIgdmhkbC11bmRlcnNjb3JlLWlzLXBhcnQtb2Ytd29yZF0gNCAoIyQgLiAyMjUyODgpXSkK I0A2MyBDb21tZW50IG91dCByZWdpb24gaWYgbm90IGNvbW1lbnRlZCBvdXQsIHVuY29tbWVudCBv dGhlcndpc2UuHwooZGVmYWxpYXMgJ3ZoZGwtY29tbWVudC11bmNvbW1lbnQtcmVnaW9uICNbKGJl ZyBlbmQgJm9wdGlvbmFsIGFyZykgIlwyMTIIU2JcMjEwXDMwM39cMjEwXDMwNCAQCWJcMjEwXDMw NXlcMjEwYBFcMzA2XG4hXDIwMyEAXDMwNwkIXDMxMCNcMjAyJQBcMzA3CQhcIilcMjA3IiBbZW5k IGJlZyBjb21tZW50LXN0YXJ0IG5pbCBwb2ludC1tYXJrZXIgMCBsb29raW5nLWF0IGNvbW1lbnQt cmVnaW9uIC0xXSA0ICgjJCAuIDIyNjAxMCkgInJcblAiXSkKI0A2MSBDb21tZW50IG91dCBsaW5l IGlmIG5vdCBjb21tZW50ZWQgb3V0LCB1bmNvbW1lbnQgb3RoZXJ3aXNlLh8KKGRlZmFsaWFzICd2 aGRsLWNvbW1lbnQtdW5jb21tZW50LWxpbmUgI1soJm9wdGlvbmFsIGFyZykgIlwyMTJcMzAyeVwy MTBgGAlcMjA2CwBcMzAzeVwyMTBcMzA0CGBcIipcMjA3IiBbcG9zaXRpb24gYXJnIDAgMSB2aGRs LWNvbW1lbnQtdW5jb21tZW50LXJlZ2lvbl0gMyAoIyQgLiAyMjYzMzEpICJwIl0pCiNAMjYgS2ls bCBjb21tZW50cyBpbiByZWdpb24uHwooZGVmYWxpYXMgJ3ZoZGwtY29tbWVudC1raWxsLXJlZ2lv biAjWyhiZWcgZW5kKSAiXDIxMghiXDIxMFwzMDIgEAliXDIxMFwzMDN5XDIxMGAIV1wyMDUoAFwz MDRcMzA1IVwyMDNcIgBcMzA2XDIyNFwzMDZcMjI1fFwyMTBcMjAyDQBcMzA2eVwyMTBcMjAyDQAp XDIwNyIgW2VuZCBiZWcgcG9pbnQtbWFya2VyIDAgbG9va2luZy1hdCAiXlxcKFxccy0qLS0uKlxu XFwpIiAxXSAyICgjJCAuIDIyNjU3MikgInIiXSkKI0AzMyBLaWxsIGlubGluZSBjb21tZW50cyBp biByZWdpb24uHwooZGVmYWxpYXMgJ3ZoZGwtY29tbWVudC1raWxsLWlubGluZS1yZWdpb24gI1so YmVnIGVuZCkgIlwyMTIIYlwyMTBcMzAyIBAJYlwyMTBcMzAzeVwyMTBgCFdcMjA1JQBcMzA0XDMw NSFcMjAzHwBcMzA2XDIyNFwzMDZcMjI1fFwyMTBcMzA2eVwyMTBcMjAyDQApXDIwNyIgW2VuZCBi ZWcgcG9pbnQtbWFya2VyIDAgbG9va2luZy1hdCAiXi4qW14gCVxuLV0rXFwoXFxzLSotLS4qXFwp JCIgMV0gMiAoIyQgLiAyMjY4MzgpICJyIl0pCiNAOTEgSW5zZXJ0IGEgYmVnaW4gLi4uIGVuZCBw YWlyIHdpdGggb3B0aW9uYWwgbmFtZSBhZnRlciB0aGUgZW5kLgpQb2ludCBpcyBsZWZ0IGJldHdl ZW4gdGhlbS4fCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1iZWdpbi1lbmQgI1soY29uc3RydWN0 IG5hbWUgbWFyZ2luICZvcHRpb25hbCBlbXB0eS1saW5lcykgIlwzMDYYXDMwN2NcMjEwCVwyMDQP AFxuXDMxMD1cMjAzEgBcMzA3Y1wyMTALalwyMTBcMzExXDMxMiFcMjEwXGZcMjA0IQANXDIwMz0A DhBcMjAzPQBcMzEzY1wyMTBcZlwyMDM0AFwzMTRjXDIxMFwzMTFcZiFcMjEwDVwyMDM9AFwzMTQN XDI2MQJcMjEwXDMwN2NcMjEwCVwyMDRKAFxuXDMxMD1cMjAzTQBcMzA3Y1wyMTALDhFcXGpcMjEw YBBcMzA3Y1wyMTAJXDIwNGIAXG5cMzEwPVwyMDNlAFwzMDdjXDIxMAtqXDIxMFwzMTFcMzE1IVwy MTBcZlwyMDN3AFwzMTRjXDIxMFwzMTFcZiFcMjEwDVwyMDNcMjAxAFwzMTQNUFwyMDJcMjAyAFwz MTZcMzE3XDI2MQJcMjEwCGIpXDIwNyIgW3Bvc2l0aW9uIGVtcHR5LWxpbmVzIHZoZGwtaW5zZXJ0 LWVtcHR5LWxpbmVzIG1hcmdpbiBjb25zdHJ1Y3QgbmFtZSBuaWwgIlxuIiBhbGwgdmhkbC1pbnNl cnQta2V5d29yZCAiQkVHSU4iICIgIC0tIiAiICIgIkVORCIgIiIgIjsiIHZoZGwtc2VsZi1pbnNl cnQtY29tbWVudHMgdmhkbC1iYXNpYy1vZmZzZXRdIDIgKCMkIC4gMjI3MTIxKV0pCiNANTUgUmVh ZCBmcm9tIHVzZXIgYSBwcm9jZWR1cmUgb3IgZnVuY3Rpb24gYXJndW1lbnQgbGlzdC4fCihkZWZh bGlhcyAndmhkbC10ZW1wbGF0ZS1hcmd1bWVudC1saXN0ICNbKCZvcHRpb25hbCBpcy1mdW5jdGlv bikgIlwzMDZjXDIxMGlgYFwzMDdcMjExXDIxMRgZGhscHQ4eXDIwNCAAXDMxMCAOH1xcFVwzMTFj XDIxMA1qXDIxMFwzMTJcMzEzDiA/XDIwNSkAXDMxNFwzMTVRXDMxNlwzMTcjEVwzMTJcMzIwXDMw N1wzMTcjXDIwM38AXDMxNxJcMzIxY1wyMTAOIFwyMDRZAAlcMjAzUwAJXDIyNlwzMjJcMjMyXDIw M1MAXDMyM1wzMjQhXDIxMFwyMDJZAFwzMTJcMzI1XDMxNlwzMTcjXDIxMFwzMTJcMzI2IVwyMTBg EFwzMjdjXDIxMFwzMzAgXDIxMGATXDMxMWNcMjEwDWpcMjEwXDMxMlwzMTMOID9cMjA1dgBcMzE0 XDMxNVFcMzE2XDMxNyMRXDIwMi8AC2B8XDIxMAhcMjAzXDIxMgAIYlwyMTBcblwyMDNcMjI3AFwz MzFcMzMyIVwyMTBcMzMzY1wyMDJcMjMyAFwzMzRcMzM1IS4GXDIwNyIgW3NlbWljb2xvbi1wb3Mg aW50ZXJmYWNlIG5vdC1lbXB0eSBlbmQtcG9zIHN0YXJ0IG1hcmdpbiAiICgiIG5pbCBjdXJyZW50 LWluZGVudGF0aW9uICJcbiIgdmhkbC10ZW1wbGF0ZS1maWVsZCAiW0NPTlNUQU5UIHwgU0lHTkFM IiAiIHwgVkFSSUFCTEUiICJdIiAiICIgdCAiW25hbWVzXSIgIiA6ICIgIkNPTlNUQU5UIiB2aGRs LWluc2VydC1rZXl3b3JkICJJTiAiICJbSU4gfCBPVVQgfCBJTk9VVF0iICJ0eXBlIiAiOyIgdmhk bC1jb21tZW50LWluc2VydC1pbmxpbmUgZGVsZXRlLWNoYXIgMSAiKSIgYmFja3dhcmQtZGVsZXRl LWNoYXIgMiB2aGRsLWFyZ3VtZW50LWxpc3QtaW5kZW50IHZoZGwtYmFzaWMtb2Zmc2V0IGlzLWZ1 bmN0aW9uXSA2ICgjJCAuIDIyNzgyNildKQojQDQ2IFJlYWQgZnJvbSB1c2VyIGEgZ2VuZXJpYyBz cGVjIGFyZ3VtZW50IGxpc3QuHwooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtZ2VuZXJpYy1saXN0 ICNbKG9wdGlvbmFsICZvcHRpb25hbCBuby12YWx1ZSkgIlwzMDZgGBlcMzA3XDMxMCFcMjEwaRFc blwyMDQhAGAbXDMxMSBcMjEwaVxmXFwRC2JcMjEwXDMxMmNcMjEwCWpcMjEwKVwzMTMNXDIwNScA XDMxNFwzMTUOIFwyMDUuAFwzMTYNXDIwNTMAXDMxN1JcMzA2DSNcMjExHiFcMjA0XQANXDIwM1QA XDMyMCBcMjEwXDMyMX9cMjEwXG4/XDIwNVwzMTUAXDMyMCBcMjEwXDMyMX9cMjAyXDMxNQBcMzIy CGBcIlwyMTBcMzA2XDIwMlwzMTUAXDMyM2NcMjEwXDMwNlwyMTEeXCIeIw4hXDIwM1wyNjEAXDMx M1wzMjQhXDIxMA4gXDIwM30AYBYjXDMyNWNcMjEwXDIwMlwyMjIAXDMyNmNcMjEwXDMxM1wzMjdc MzA2XDMzMCNcMjA0XDIxNABcMzMxXDMzMiFcMjEwYBYjXDMyNWNcMjEwXDMzMyBcMjEwYBZcIlwz MTJjXDIxMAlqXDIxMFwzMTNcMzM0DiBcMjA1XDI0NgBcMzE2XDMxN1FcMzIzXDMzMCNcMjExFiFc MjA0awAOXCJgfFwyMTAOI2JcMjEwXDMzNWNcMjEwXDMwNn9cMjEwDiRcMjAzXDMxMwBcMzM2CGBc MzM3I1wyMTAqXDMzMCtcMjA3IiBbc3RhcnQgbWFyZ2luIHZoZGwtYXJndW1lbnQtbGlzdC1pbmRl bnQgcG9zaXRpb24gdmhkbC1iYXNpYy1vZmZzZXQgb3B0aW9uYWwgbmlsIHZoZGwtaW5zZXJ0LWtl eXdvcmQgIkdFTkVSSUMgKCIgYmFjay10by1pbmRlbnRhdGlvbiAiXG4iIHZoZGwtdGVtcGxhdGUt ZmllbGQgIlsiICJuYW1lIiAicyIgIl0iIHZoZGwtbGluZS1raWxsLWVudGlyZSAwIHZoZGwtdGVt cGxhdGUtdW5kbyAiIDogIiAidHlwZSIgIjsiICIgOj0gIiAiW3ZhbHVlXSIgdCBkZWxldGUtY2hh ciAtNCB2aGRsLWNvbW1lbnQtaW5zZXJ0LWlubGluZSAiW25hbWUiICIpIiB2aGRsLWFsaWduLW5v aW5kZW50LXJlZ2lvbiAxIG5vLXZhbHVlIHZoZGwtZ2VuZXJpY3MgZW5kLXBvcyBzZW1pY29sb24t cG9zIHZoZGwtYXV0by1hbGlnbl0gNiAoIyQgLiAyMjg3MTUpXSkKI0A0MyBSZWFkIGZyb20gdXNl ciBhIHBvcnQgc3BlYyBhcmd1bWVudCBsaXN0Lh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXBv cnQtbGlzdCAjWyhvcHRpb25hbCkgImBcMzA2XDIxMVwyMTEYGRobXDMwN1wzMTAhXDIxMGkSXGZc MjA0JgBgHVwzMTEgXDIxMGkOJFxcEg1iXDIxMFwzMTJjXDIxMFxualwyMTApXDMxMx4lXDMxMw4m QD1cMjA2PAAOJQ4mXDIxMR4nQUApPilcMjAzRgBcMzE0XDMxNVwzMTZcMzE3IxBcMzE0DihcMjA1 TQBcMzIwXDMyMQ4oXDIwNVQAXDMyMlFcMzA2DigjXDIxMRFcMjA0fwAOKFwyMDN2AFwzMjMgXDIx MFwzMjR/XDIxMFxmP1wyMDUYAVwzMjMgXDIxMFwzMjR/XDIwMhgBXDMyNQtgXCJcMjEwXDMwNlwy MDIYAVwzMjZjXDIxMFwzMDZcMjExHikeKglcMjAzXDM3MwAIXDIwM1wyMjcACFwyMjZcMzI3XDIz MlwyMDNcMjM3AFwzMTRcMzMwXDMxNlwiXDIxMFwyMDJcMjU0AAhcMjI2XDMzMVwyMzJcMjAzXDI1 NABcMzE0XDMzMlwzMTZcMzE3I1wyMTBcMzE0CFwyMDNcMjc0AAhcMjI2XDMzM1wyMzJcMjAzXDI3 NABcMzM0XDIwMlwyNzUAXDMzNSFcMjEwYBYqXDMzNmNcMjEwXDMzNyBcMjEwYBYpXDMxMmNcMjEw XG5qXDIxMFwzMTMeJVwzMTMOJkA9XDIwNlwzNDcADiUOJlwyMTEeJ0FAKT4pXDIwM1wzNjEAXDMx NFwzMTVcMzE2XDMxNyMQXDMxNFwzNDBcMzI2XDMxNyNcMjExEVwyMDRcMjE0AA4pYHxcMjEwDipi XDIxMFwzNDFjXDIxMFwzMDZ/XDIxMA4rXDIwMxYBXDM0MgsOKVwzNDMjXDIxMCpcMzE3LFwyMDci IFtvYmplY3QgdmhkbC1wb3J0cyBtYXJnaW4gc3RhcnQgdmhkbC1hcmd1bWVudC1saXN0LWluZGVu dCBwb3NpdGlvbiBuaWwgdmhkbC1pbnNlcnQta2V5d29yZCAiUE9SVCAoIiBiYWNrLXRvLWluZGVu dGF0aW9uICJcbiIgYW1zIHZoZGwtdGVtcGxhdGUtZmllbGQgIltTSUdOQUwgfCBURVJNSU5BTCB8 IFFVQU5USVRZXSIgIiAiIHQgIlsiICJuYW1lcyIgIl0iIHZoZGwtbGluZS1raWxsLWVudGlyZSAw IHZoZGwtdGVtcGxhdGUtdW5kbyAiIDogIiAiU0lHTkFMIiAiSU4gfCBPVVQgfCBJTk9VVCIgIlFV QU5USVRZIiAiW0lOIHwgT1VUXSIgIlRFUk1JTkFMIiAibmF0dXJlIiAidHlwZSIgIjsiIHZoZGwt Y29tbWVudC1pbnNlcnQtaW5saW5lICJbbmFtZXNdIiAiKSIgdmhkbC1hbGlnbi1ub2luZGVudC1y ZWdpb24gMSB2aGRsLWJhc2ljLW9mZnNldCBzdGFuZGFyZCB2aGRsLXN0YW5kYXJkIHggb3B0aW9u YWwgZW5kLXBvcyBzZW1pY29sb24tcG9zIHZoZGwtYXV0by1hbGlnbl0gNSAoIyQgLiAyMjk3NTQp XSkKI0AzNiBJbnNlcnQgYm9keSBmb3IgZ2VuZXJhdGUgdGVtcGxhdGUuHwooZGVmYWxpYXMgJ3Zo ZGwtdGVtcGxhdGUtZ2VuZXJhdGUtYm9keSAjWyhtYXJnaW4gbGFiZWwpICJcMzA2XDMwNyFcMjEw XDMxMBhcMzEwCUA9XDIwNhUACAlcMjExGkFAKT4pXDIwNB8AXDMxMVwzMTILXGYjXDIwN1wzMTNj XDIxMFxmalwyMTBcMzA2XDMxNCFcMjEwC1wzMTVcMjYxAlwyMTBcMzE2f1wyMTBcZg1cXGpcMjA3 IiBbc3RhbmRhcmQgdmhkbC1zdGFuZGFyZCB4IGxhYmVsIG1hcmdpbiB2aGRsLWJhc2ljLW9mZnNl dCB2aGRsLWluc2VydC1rZXl3b3JkICIgR0VORVJBVEUiIDg3IHZoZGwtdGVtcGxhdGUtYmVnaW4t ZW5kICJHRU5FUkFURSIgIlxuXG4iICJFTkQgR0VORVJBVEUgIiAiOyIgMF0gNCAoIyQgLiAyMzEw MjkpXSkKI0AzNiBJbnNlcnQgZGF0ZSBpbiBhcHByb3ByaWF0ZSBmb3JtYXQuHwooZGVmYWxpYXMg J3ZoZGwtdGVtcGxhdGUtaW5zZXJ0LWRhdGUgI1tuaWwgIghcMzAxPVwyMDMNAFwzMDJcMzAzXDMw NFwiXDIwMisACFwzMDU9XDIwMxoAXDMwMlwzMDZcMzA0XCJcMjAyKwAIXDMwNz1cMjAzJwBcMzAy XDMxMFwzMDRcIlwyMDIrAFwzMDIIXDMwNFwiY1wyMDciIFt2aGRsLWRhdGUtZm9ybWF0IGFtZXJp Y2FuIGZvcm1hdC10aW1lLXN0cmluZyAiJW0vJWQvJVkiIG5pbCBldXJvcGVhbiAiJWQuJW0uJVki IHNjaWVudGlmaWMgIiVZLyVtLyVkIl0gMyAoIyQgLiAyMzE0MzEpIG5pbF0pCiNAMTE4IEV4cGFu ZCBhYmJyZXZpYXRpb25zIGFuZCBzZWxmLWluc2VydCBzcGFjZShzKSwgZG8gaW5kZW50LW5ldy1j b21tZW50LWxpbmUKaWYgaW4gY29tbWVudCBhbmQgcGFzdCBlbmQtY29tbWVudC1jb2x1bW4uHwoo ZGVmYWxpYXMgJ3ZoZGwtZWxlY3RyaWMtc3BhY2UgI1soY291bnQpICJgGFwyMTJcMzA2eVwyMTBc MzA3XDMxMAhcMzExIypcMjAzMwBcMzEyCSFcMjEwaVxuXDMxM1xcWVwyMDMoAFwzMTRcMzE1IVwy MTBcMzE2IFwyMTBcMzE1dlwyMTBcMzE1dVwyMDdpXG5ZXDIwMzEAXDMxNiBcMjA3XDMxN1wyMDdo XDMyMFlcMjAzPwBoXDMyMVhcMjA0SwBoXDMyMllcMjAzaQBoXDMyM1hcMjAzaQBcMzE3G1wzMjRc MzI1XDMyNlxmI1wyMTBcMzExHVwzMjcgKRMOGVwyMDRkAFwzMjRcMzI1XDMzMFxmI1wyMTApXDMx MgkhXDIwN1wzMTIJIVwyMDciIFtwb3NpdGlvbiBjb3VudCBlbmQtY29tbWVudC1jb2x1bW4gcmVz dWx0IHZoZGwtbW9kZS1zeW50YXgtdGFibGUgY2FzZS1mb2xkLXNlYXJjaCAwIHJlLXNlYXJjaC1m b3J3YXJkICJeXFwoW15cIl0qXCJbXlwiXSpcIlxcKSpbXlwiXSotLSIgdCBzZWxmLWluc2VydC1j b21tYW5kIDIgYmFja3dhcmQtd29yZCAxIGluZGVudC1uZXctY29tbWVudC1saW5lIG5pbCA5NyAx MjIgNjUgOTAgbW9kaWZ5LXN5bnRheC1lbnRyeSA5NSAidyIgZXhwYW5kLWFiYnJldiAiXyIgdmhk bC11bmRlcnNjb3JlLWlzLXBhcnQtb2Ytd29yZF0gNCAoIyQgLiAyMzE3NTcpICJwIl0pCiNAMzY4 IFByb21wdCBmb3Igc3RyaW5nIGFuZCBpbnNlcnQgaXQgaW4gYnVmZmVyIHdpdGggb3B0aW9uYWwg Rk9MTE9XLVNUUklORy4KSWYgT1BUSU9OQUwgaXMgbmlsLCB0aGUgcHJvbXB0IGlzIGxlZnQgaWYg YW4gZW1wdHkgc3RyaW5nIGlzIGluc2VydGVkLiAgSWYKYW4gZW1wdHkgc3RyaW5nIGlzIGluc2Vy dGVkLCByZXR1cm4gbmlsIGFuZCBjYWxsIGB2aGRsLXRlbXBsYXRlLXVuZG8nIGZvcgp0aGUgcmVn aW9uIGJldHdlZW4gQkVHSU4gYW5kIEVORC4gIElTLVNUUklORyBpbmRpY2F0ZXMgd2hldGhlciBh IHN0cmluZwp3aXRoIGRvdWJsZS1xdW90ZXMgaXMgdG8gYmUgaW5zZXJ0ZWQuICBERUZBVUxUIHNw ZWNpZmllcyBhIGRlZmF1bHQgc3RyaW5nLh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWZpZWxk ICNbKHByb21wdCAmb3B0aW9uYWwgZm9sbG93LXN0cmluZyBvcHRpb25hbCBiZWdpbiBlbmQgaXMt c3RyaW5nIGRlZmF1bHQpICJgXDMwNhgZXDMwN1xuXDMxMFwyNjEDXDIxMFwzMDZcMzExXDMxMlwy MTdcMjExEFwzMTNcMjMyXDIwMxkAC1wyMDMdAAlgfFwyMTAIXDMxM1wyMzJcMjAzOAALXDIwMzgA XGZcMjAzOAANXDIwMzgAXDMxNFxmDVwiXDIxMFwzMTVcMzE2IVwyMTAIXDMxM1wyMzJcMjA0SgAI Y1wyMTBcMzE3CWAOEA4RJFwyMTAIXDMxM1wyMzJcMjAzVAALXDIwNFxcAA4SXDIwNloAXDMxM2Nc MjEwCFwzMTNcMjMyP1wyMDVkAAgqXDIwNyIgW3N0cmluZyBwb3NpdGlvbiBwcm9tcHQgb3B0aW9u YWwgYmVnaW4gZW5kIG5pbCAiPCIgIj4iIChieXRlLWNvZGUgIlwzMDQIXDMwNVAJXDIwM1xmAFwz MDZcMjAyDQBcbgsjXDIwNyIgW3Byb21wdCBpcy1zdHJpbmcgZGVmYXVsdCB2aGRsLW1pbmlidWZm ZXItbG9jYWwtbWFwIHJlYWQtZnJvbS1taW5pYnVmZmVyICI6ICIgKCJcIlwiIiAuIDIpXSA0KSAo KHF1aXQgKGJ5dGUtY29kZSAiCFwyMDMRAAlcMjAzEQBcblwyMDMRAFwzMDMgXDIxMFwzMDRcMjA3 XDMwNSBcMjA3IiBbb3B0aW9uYWwgYmVnaW4gZW5kIGJlZXAgIiIga2V5Ym9hcmQtcXVpdF0gMSkp KSAiIiB2aGRsLXRlbXBsYXRlLXVuZG8gbWVzc2FnZSAiVGVtcGxhdGUgYWJvcnRlZCIgdmhkbC1m aXgtY2FzZS1yZWdpb24tMSB2aGRsLXVwcGVyLWNhc2Uta2V5d29yZHMgdmhkbC1rZXl3b3Jkcy1y ZWdleHAgZm9sbG93LXN0cmluZ10gNiAoIyQgLiAyMzI1MDQpXSkKI0AzMyBRdWVyeSBhIGRlY2lz aW9uIGZyb20gdGhlIHVzZXIuHwooZGVmYWxpYXMgJ3ZoZGwtZGVjaXNpb24tcXVlcnkgI1soc3Ry aW5nIHByb21wdCAmb3B0aW9uYWwgb3B0aW9uYWwpICJgGAlcMjAzXGYAXDMwNQlcMzA2UCFcMjEw XDMwN1xuIVwyMTBcMzEwIBsIYHxcMjEwXGZcMjAzLgALXDMxMT1cMjAzLgBcMzA2Y1wyMTBcMzEy IFwyMTBcMzEzXDMxNFwzMTVcIlwyMDIvAAsqXDIwNyIgW3N0YXJ0IHN0cmluZyBwcm9tcHQgY2hh ciBvcHRpb25hbCB2aGRsLWluc2VydC1rZXl3b3JkICIgIiBtZXNzYWdlIHJlYWQtY2hhciAxMyB1 bmV4cGFuZC1hYmJyZXYgdGhyb3cgYWJvcnQgIlRlbXBsYXRlIGFib3J0ZWQiXSAzICgjJCAuIDIz MzY4NyldKQojQDMzIEluc2VydCBLRVlXT1JEIGFuZCBhZGp1c3QgY2FzZS4fCihkZWZhbGlhcyAn dmhkbC1pbnNlcnQta2V5d29yZCAjWyhrZXl3b3JkKSAiCFwyMDMJAAlcMjI2XDIwMgsACVwyMjdj XDIwNyIgW3ZoZGwtdXBwZXItY2FzZS1rZXl3b3JkcyBrZXl3b3JkXSAxICgjJCAuIDIzNDA1NSld KQojQDI1IEFkanVzdCBjYXNlIG9mIEtFWVdPUkQuHwooZGVmYWxpYXMgJ3ZoZGwtY2FzZS1rZXl3 b3JkICNbKGtleXdvcmQpICIIXDIwMwcACVwyMjZcMjA3CVwyMjdcMjA3IiBbdmhkbC11cHBlci1j YXNlLWtleXdvcmRzIGtleXdvcmRdIDEgKCMkIC4gMjM0MjIwKV0pCiNAMzcgQWRqdXN0IGNhc2Ug b3IgZm9sbG93aW5nIE5VTSB3b3Jkcy4fCihkZWZhbGlhcyAndmhkbC1jYXNlLXdvcmQgI1sobnVt KSAiCFwyMDMIAFwzMDIJIVwyMDdcMzAzCSFcMjA3IiBbdmhkbC11cHBlci1jYXNlLWtleXdvcmRz IG51bSB1cGNhc2Utd29yZCBkb3duY2FzZS13b3JkXSAyICgjJCAuIDIzNDM3MildKQojQDIzNyBJ ZiBwcmVjZWVkaW5nIGNoYXJhY3RlciBpcyBwYXJ0IG9mIGEgd29yZCBvciBhIHBhcmVuIHRoZW4g aGlwcGllLWV4cGFuZCwKZWxzZSBpZiByaWdodCBvZiBub24gd2hpdGVzcGFjZSBvbiBsaW5lIHRo ZW4gdGFiLXRvLXRhYi1zdG9wLAplbHNlIGluZGVudCBsaW5lIGluIHByb3BlciB3YXkgZm9yIGN1 cnJlbnQgbWFqb3IgbW9kZSAodXNlZCBmb3Igd29yZApjb21wbGV0aW9uIGluIFZIREwgbWluaWJ1 ZmZlcikuHwooZGVmYWxpYXMgJ3ZoZGwtbWluaWJ1ZmZlci10YWIgI1soJm9wdGlvbmFsIHByZWZp eC1hcmcpICJoelwzMDVVXDIwMxEACD9cMzA2GRpcMzA3CyEqXDIwN2hcMzEwVVwyMDQdAGhcMzEx VVwyMDMnAAg/XDMwNhkaXDMxMgshKlwyMDdpXDMxMyBWXDIwMzEAXDMxNCBcMjA3XGZcMzE1PVwy MDM7AFwzMTYLIVwyMDcLXDIwM0MAXGYLIVwyMDdcZiBcMjA3IiBbdmhkbC13b3JkLWNvbXBsZXRp b24tY2FzZS1zZW5zaXRpdmUgY2FzZS1yZXBsYWNlIGNhc2UtZm9sZC1zZWFyY2ggcHJlZml4LWFy ZyBpbmRlbnQtbGluZS1mdW5jdGlvbiAxMTkgbmlsIHZoZGwtZXhwYW5kLWFiYnJldiA0MCA0MSB2 aGRsLWV4cGFuZC1wYXJlbiBjdXJyZW50LWluZGVudGF0aW9uIHRhYi10by10YWItc3RvcCBpbmRl bnQtdG8tbGVmdC1tYXJnaW4gaW5zZXJ0LXRhYl0gMiAoIyQgLiAyMzQ1NTQpICJQIl0pCiNANTUg U2VhcmNoIGZvciBsZWZ0IG91dCB0ZW1wbGF0ZSBwcm9tcHRzIGFuZCBxdWVyeSBhZ2Fpbi4fCihk ZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1zZWFyY2gtcHJvbXB0ICNbbmlsICJcMzA2GFwzMDcZXDMx MFwzMTFcMzEyXG4jXDIxMFwzMTNcMzE0C1wzMTVRXDMwN1wzMDYjXDIwNCAAXDMxNlwzMTQLXDMx NVFcMzA3XDMwNiNcMjA1LABcMzE3XDMyMCEcXDMyMVwzMjIhXDIxMFwzMjNcZiEpEQ1cMjA0NwBc MzEwXDMxMVwzMjRcbiNcMjEwCSpcMjA3IiBbY2FzZS1mb2xkLXNlYXJjaCByZXN1bHQgdmhkbC1t b2RlLXN5bnRheC10YWJsZSB2aGRsLXRlbXBsYXRlLXByb21wdC1zeW50YXggc3RyaW5nIHZoZGwt dW5kZXJzY29yZS1pcy1wYXJ0LW9mLXdvcmQgdCBuaWwgbW9kaWZ5LXN5bnRheC1lbnRyeSA5NSAi dyIgcmUtc2VhcmNoLWZvcndhcmQgIjxcXCgiICJcXCk+IiByZS1zZWFyY2gtYmFja3dhcmQgbWF0 Y2gtc3RyaW5nIDEgcmVwbGFjZS1tYXRjaCAiIiB2aGRsLXRlbXBsYXRlLWZpZWxkICJfIl0gNCAo IyQgLiAyMzUyMzkpIG5pbF0pCiNANzEgVW5kbyBhYm9ydGVkIHRlbXBsYXRlIGJ5IGRlbGV0aW5n IHJlZ2lvbiBhbmQgdW5leHBhbmRpbmcgdGhlIGtleXdvcmQuHwooZGVmYWxpYXMgJ3ZoZGwtdGVt cGxhdGUtdW5kbyAjWyhiZWdpbiBlbmQpICIIXDIwMxEACWJcMjEwXDMwM2NcMjEwXG4JfFwyMTBc MzA0IFwyMDdcbgl8XDIwNyIgW3ZoZGwtdGVtcGxhdGUtaW52b2tlZC1ieS1ob29rIGVuZCBiZWdp biAiICIgdW5leHBhbmQtYWJicmV2XSAyICgjJCAuIDIzNTc3NildKQojQDY4IEluc2VydCBTVFJJ Tkcgb3IgZmlsZSBjb250ZW50cyBpZiBTVFJJTkcgaXMgYW4gZXhpc3RpbmcgZmlsZSBuYW1lLh8K KGRlZmFsaWFzICd2aGRsLWluc2VydC1zdHJpbmctb3ItZmlsZSAjWyhzdHJpbmcpICIIXDMwMlwy MzI/XDIwNRkAXDMwMwghXDIwMxcAXDMwNAghXDIxMRlBQCl1XDIwNwhjXDIwNyIgW3N0cmluZyB4 ICIiIGZpbGUtZXhpc3RzLXAgaW5zZXJ0LWZpbGUtY29udGVudHNdIDMgKCMkIC4gMjM2MDI2KV0p CiNANTMgQ2hlY2sgaWYgcG9pbnQgaXMgd2l0aGluIHNlcXVlbnRpYWwgc3RhdGVtZW50IHBhcnQu HwooZGVmYWxpYXMgJ3ZoZGwtc2VxdWVudGlhbC1zdGF0ZW1lbnQtcCAjW25pbCAiXDIxMlwzMDVg GBlcMzA2GlwzMDdcMzEwXDMxMQsjXDIxMFwzMTJcMzA2IVwyMTBcMzEzXDMxNFwzMDZcMzA1I1wy MDMfAFwzMTVcMzE2IVwyMDQRAFwzMTcgXDIwNTwAXDMxNVwzMjAhXDIyNlwzMjFcMjMyXDIwNTwA XDMxM1wzMjJcMzA2XDMwNSNcMjA1PABcMzE1XDMyMyFcMjI2XDMyNFwyMzI/ElxmXDIwNEcAXDMw N1wzMTBcMzI1CyNcMjEwXG4sXDIwNyIgW3N0YXJ0IGNhc2UtZm9sZC1zZWFyY2ggcmVzdWx0IHZo ZGwtbW9kZS1zeW50YXgtdGFibGUgdmhkbC11bmRlcnNjb3JlLWlzLXBhcnQtb2Ytd29yZCB0IG5p bCBtb2RpZnktc3ludGF4LWVudHJ5IDk1ICJ3IiBzZXQtbWF0Y2gtZGF0YSByZS1zZWFyY2gtYmFj a3dhcmQgIl5cXHMtKlxcKGJlZ2luXFx8ZW5kXFwoXFxzLSpcXChjYXNlXFx8aWZcXHxsb29wXFwp XFwpP1xcKVxcPiIgbWF0Y2gtc3RyaW5nIDIgbWF0Y2gtZGF0YSAxICJCRUdJTiIgIl5cXHMtKlxc KFxcdytcXHMtKjpcXHMtKlxcKT9cXChcXHcrXFxzLStcXCk/XFwoZnVuY3Rpb25cXHxwcm9jZWR1 cmVcXHxwcm9jZXNzXFx8cHJvY2VkdXJhbFxcfGVuZFxcKVxcPiIgMyAiRU5EIiAiXyJdIDQgKCMk IC4gMjM2MjcxKV0pCiNAMzUgQ2hlY2sgaWYgd2l0aGluIGFuIGFyZ3VtZW50IGxpc3QuHwooZGVm YWxpYXMgJ3ZoZGwtaW4tYXJndW1lbnQtbGlzdC1wICNbbmlsICJcMjEyXDMwNBhcMzA1GVwzMDZc MzA3XDMxMFxuI1wyMTBcMzExXDMxMlwzMTNcMzE0XDMxNSBAQFwiXCJcMjA2HgBcMzE2eVwyMTBc MzE3XDMyMCERC1wyMDQpAFwzMDZcMzA3XDMyMVxuI1wyMTAJK1wyMDciIFtjYXNlLWZvbGQtc2Vh cmNoIHJlc3VsdCB2aGRsLW1vZGUtc3ludGF4LXRhYmxlIHZoZGwtdW5kZXJzY29yZS1pcy1wYXJ0 LW9mLXdvcmQgdCBuaWwgbW9kaWZ5LXN5bnRheC1lbnRyeSA5NSAidyIgc3RyaW5nLW1hdGNoICJh cmdsaXN0IiBmb3JtYXQgIiVzIiB2aGRsLWdldC1zeW50YWN0aWMtY29udGV4dCAwIGxvb2tpbmct YXQgIl5cXHMtKlxcKGdlbmVyaWNcXHxwb3J0XFx8XFwoXFwoaW1wdXJlXFx8cHVyZVxcKVxccy0r XFx8XFwpZnVuY3Rpb25cXHxwcm9jZWR1cmVcXClcXD5cXHMtKlxcKFxcdytcXHMtKlxcKT8oIiAi XyJdIDUgKCMkIC4gMjM2OTY3KV0pCiNAMTE1IERvIGZ1bmN0aW9uLCBpZiBzeW50YXggc2F5cyBh YmJyZXYgaXMgYSBrZXl3b3JkLCBpbnZva2VkIGJ5IGhvb2tlZCBhYmJyZXYsCmJ1dCBub3QgaWYg aW5zaWRlIGEgY29tbWVudCBvciBxdW90ZSkuHwooZGVmYWxpYXMgJ3ZoZGwtaG9va2VkLWFiYnJl diAjWyhmdW5jKSAiYBhcMjEyXDMwNnlcMjEwXDMwN1wzMTAIXDMxMSMqXDIwNDIAYBhcMjEyXDMw NnlcMjEwCFwzMDdcMzEyCFwzMTEjKj1cMjA0MgBcMjEyXDMxM3ZcMjEwXDMxNFwzMTUhXDIwNS4A XDMxNFwzMTYhPylcMjAzPABcMzE3Y1wyMTBcMzIwIFwyMTBcMzIxXDMxMyFcMjA3CVwyMDRSAFwz MTdjXDIxMFwzMjAgXDIxMFwzMjJcMzIzIVwyMTBcMzI0XDMyMyFcMjEwXDMyMVwzMjMhXDIwN1xu XDMxM1wzMTEbHB1cMzI1XDMyNlwyMTVcMjExHh47XDIwM2cAXDMyNw4eIVwyMTApDVwzMzBVXDIw M3EAYBYfXDMzMVwzMzIOIFwiXDIwM1wyMDAAXDMzM1wzMjFcMzEzXCJcMjAyXDIwNwBcMzM0XDMz NSFDXDIxMRYhK1wyMDciIFtwb3NpdGlvbiB2aGRsLWVsZWN0cmljLW1vZGUgbGFzdC1jb21tYW5k LWNoYXIgdmhkbC10ZW1wbGF0ZS1pbnZva2VkLWJ5LWhvb2sgYWJicmV2LW1vZGUgaW52b2tlLWNo YXIgMCByZS1zZWFyY2gtZm9yd2FyZCAiXlxcKFteXCJdKlwiW15cIl0qXCJcXCkqW15cIl0qLS0i IHQgIl5cXChbXlwiXSpcIlteXCJdKlwiXFwpKlteXCJdKlwiW15cIl0qIiAtMSBsb29raW5nLWF0 ICJcXDxlbmRcXD4iICJcXDxlbmQ7IiAiICIgdW5leHBhbmQtYWJicmV2IGRlbGV0ZS1jaGFyIGJh Y2t3YXJkLXdvcmQgMSB2aGRsLWNhc2Utd29yZCBhYm9ydCAoZnVuY2FsbCBmdW5jKSBtZXNzYWdl IDQ1IHN0cmluZy1tYXRjaCAiWEVtYWNzIiBlbnF1ZXVlLWV2YWwtZXZlbnQgdmhkbC1jaGFyYWN0 ZXItdG8tZXZlbnQgMTI3IGNhdWdodCBhYmJyZXYtc3RhcnQtbG9jYXRpb24gZW1hY3MtdmVyc2lv biB1bnJlYWQtY29tbWFuZC1ldmVudHNdIDYgKCMkIC4gMjM3NDkwKV0pCihkZWZhbGlhcyAndmhk bC10ZW1wbGF0ZS1hbGlhcy1ob29rICNbbmlsICJcMzAwXDMwMSFcMjA3IiBbdmhkbC1ob29rZWQt YWJicmV2IHZoZGwtdGVtcGxhdGUtYWxpYXNdIDJdKQooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUt YXJjaGl0ZWN0dXJlLWhvb2sgI1tuaWwgIlwzMDBcMzAxIVwyMDciIFt2aGRsLWhvb2tlZC1hYmJy ZXYgdmhkbC10ZW1wbGF0ZS1hcmNoaXRlY3R1cmVdIDJdKQooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxh dGUtYXNzZXJ0LWhvb2sgI1tuaWwgIlwzMDBcMzAxIVwyMDciIFt2aGRsLWhvb2tlZC1hYmJyZXYg dmhkbC10ZW1wbGF0ZS1hc3NlcnRdIDJdKQooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtYXR0cmli dXRlLWhvb2sgI1tuaWwgIlwzMDBcMzAxIVwyMDciIFt2aGRsLWhvb2tlZC1hYmJyZXYgdmhkbC10 ZW1wbGF0ZS1hdHRyaWJ1dGVdIDJdKQooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtYmxvY2staG9v ayAjW25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwtaG9va2VkLWFiYnJldiB2aGRsLXRlbXBsYXRl LWJsb2NrXSAyXSkKKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWJyZWFrLWhvb2sgI1tuaWwgIlwz MDBcMzAxIVwyMDciIFt2aGRsLWhvb2tlZC1hYmJyZXYgdmhkbC10ZW1wbGF0ZS1icmVha10gMl0p CihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1jYXNlLWhvb2sgI1tuaWwgIlwzMDBcMzAxIVwyMDci IFt2aGRsLWhvb2tlZC1hYmJyZXYgdmhkbC10ZW1wbGF0ZS1jYXNlXSAyXSkKKGRlZmFsaWFzICd2 aGRsLXRlbXBsYXRlLWNvbXBvbmVudC1ob29rICNbbmlsICJcMzAwXDMwMSFcMjA3IiBbdmhkbC1o b29rZWQtYWJicmV2IHZoZGwtdGVtcGxhdGUtY29tcG9uZW50XSAyXSkKKGRlZmFsaWFzICd2aGRs LXRlbXBsYXRlLWluc3RhbmNlLWhvb2sgI1tuaWwgIlwzMDBcMzAxIVwyMDciIFt2aGRsLWhvb2tl ZC1hYmJyZXYgdmhkbC10ZW1wbGF0ZS1pbnN0YW5jZV0gMl0pCihkZWZhbGlhcyAndmhkbC10ZW1w bGF0ZS1jb25kaXRpb25hbC1zaWduYWwtYXNzdC1ob29rICNbbmlsICJcMzAwXDMwMSFcMjA3IiBb dmhkbC1ob29rZWQtYWJicmV2IHZoZGwtdGVtcGxhdGUtY29uZGl0aW9uYWwtc2lnbmFsLWFzc3Rd IDJdKQooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtY29uZmlndXJhdGlvbi1ob29rICNbbmlsICJc MzAwXDMwMSFcMjA3IiBbdmhkbC1ob29rZWQtYWJicmV2IHZoZGwtdGVtcGxhdGUtY29uZmlndXJh dGlvbl0gMl0pCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1jb25zdGFudC1ob29rICNbbmlsICJc MzAwXDMwMSFcMjA3IiBbdmhkbC1ob29rZWQtYWJicmV2IHZoZGwtdGVtcGxhdGUtY29uc3RhbnRd IDJdKQooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtZGlzY29ubmVjdC1ob29rICNbbmlsICJcMzAw XDMwMSFcMjA3IiBbdmhkbC1ob29rZWQtYWJicmV2IHZoZGwtdGVtcGxhdGUtZGlzY29ubmVjdF0g Ml0pCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1kaXNwbGF5LWNvbW1lbnQtaG9vayAjW25pbCAi XDMwMFwzMDEhXDIwNyIgW3ZoZGwtaG9va2VkLWFiYnJldiB2aGRsLWNvbW1lbnQtZGlzcGxheV0g Ml0pCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1lbHNlLWhvb2sgI1tuaWwgIlwzMDBcMzAxIVwy MDciIFt2aGRsLWhvb2tlZC1hYmJyZXYgdmhkbC10ZW1wbGF0ZS1lbHNlXSAyXSkKKGRlZmFsaWFz ICd2aGRsLXRlbXBsYXRlLWVsc2lmLWhvb2sgI1tuaWwgIlwzMDBcMzAxIVwyMDciIFt2aGRsLWhv b2tlZC1hYmJyZXYgdmhkbC10ZW1wbGF0ZS1lbHNpZl0gMl0pCihkZWZhbGlhcyAndmhkbC10ZW1w bGF0ZS1lbnRpdHktaG9vayAjW25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwtaG9va2VkLWFiYnJl diB2aGRsLXRlbXBsYXRlLWVudGl0eV0gMl0pCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1leGl0 LWhvb2sgI1tuaWwgIlwzMDBcMzAxIVwyMDciIFt2aGRsLWhvb2tlZC1hYmJyZXYgdmhkbC10ZW1w bGF0ZS1leGl0XSAyXSkKKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWZpbGUtaG9vayAjW25pbCAi XDMwMFwzMDEhXDIwNyIgW3ZoZGwtaG9va2VkLWFiYnJldiB2aGRsLXRlbXBsYXRlLWZpbGVdIDJd KQooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtZm9yLWhvb2sgI1tuaWwgIlwzMDBcMzAxIVwyMDci IFt2aGRsLWhvb2tlZC1hYmJyZXYgdmhkbC10ZW1wbGF0ZS1mb3JdIDJdKQooZGVmYWxpYXMgJ3Zo ZGwtdGVtcGxhdGUtZnVuY3Rpb24taG9vayAjW25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwtaG9v a2VkLWFiYnJldiB2aGRsLXRlbXBsYXRlLWZ1bmN0aW9uXSAyXSkKKGRlZmFsaWFzICd2aGRsLXRl bXBsYXRlLWdlbmVyaWMtaG9vayAjW25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwtaG9va2VkLWFi YnJldiB2aGRsLXRlbXBsYXRlLWdlbmVyaWNdIDJdKQooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUt Z3JvdXAtaG9vayAjW25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwtaG9va2VkLWFiYnJldiB2aGRs LXRlbXBsYXRlLWdyb3VwXSAyXSkKKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWxpYnJhcnktaG9v ayAjW25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwtaG9va2VkLWFiYnJldiB2aGRsLXRlbXBsYXRl LWxpYnJhcnldIDJdKQooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtbGltaXQtaG9vayAjW25pbCAi XDMwMFwzMDEhXDIwNyIgW3ZoZGwtaG9va2VkLWFiYnJldiB2aGRsLXRlbXBsYXRlLWxpbWl0XSAy XSkKKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWlmLWhvb2sgI1tuaWwgIlwzMDBcMzAxIVwyMDci IFt2aGRsLWhvb2tlZC1hYmJyZXYgdmhkbC10ZW1wbGF0ZS1pZl0gMl0pCihkZWZhbGlhcyAndmhk bC10ZW1wbGF0ZS1iYXJlLWxvb3AtaG9vayAjW25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwtaG9v a2VkLWFiYnJldiB2aGRsLXRlbXBsYXRlLWJhcmUtbG9vcF0gMl0pCihkZWZhbGlhcyAndmhkbC10 ZW1wbGF0ZS1tYXAtaG9vayAjW25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwtaG9va2VkLWFiYnJl diB2aGRsLXRlbXBsYXRlLW1hcF0gMl0pCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1uYXR1cmUt aG9vayAjW25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwtaG9va2VkLWFiYnJldiB2aGRsLXRlbXBs YXRlLW5hdHVyZV0gMl0pCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1uZXh0LWhvb2sgI1tuaWwg IlwzMDBcMzAxIVwyMDciIFt2aGRsLWhvb2tlZC1hYmJyZXYgdmhkbC10ZW1wbGF0ZS1uZXh0XSAy XSkKKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXBhY2thZ2UtaG9vayAjW25pbCAiXDMwMFwzMDEh XDIwNyIgW3ZoZGwtaG9va2VkLWFiYnJldiB2aGRsLXRlbXBsYXRlLXBhY2thZ2VdIDJdKQooZGVm YWxpYXMgJ3ZoZGwtdGVtcGxhdGUtcG9ydC1ob29rICNbbmlsICJcMzAwXDMwMSFcMjA3IiBbdmhk bC1ob29rZWQtYWJicmV2IHZoZGwtdGVtcGxhdGUtcG9ydF0gMl0pCihkZWZhbGlhcyAndmhkbC10 ZW1wbGF0ZS1wcm9jZWR1cmFsLWhvb2sgI1tuaWwgIlwzMDBcMzAxIVwyMDciIFt2aGRsLWhvb2tl ZC1hYmJyZXYgdmhkbC10ZW1wbGF0ZS1wcm9jZWR1cmFsXSAyXSkKKGRlZmFsaWFzICd2aGRsLXRl bXBsYXRlLXByb2NlZHVyZS1ob29rICNbbmlsICJcMzAwXDMwMSFcMjA3IiBbdmhkbC1ob29rZWQt YWJicmV2IHZoZGwtdGVtcGxhdGUtcHJvY2VkdXJlXSAyXSkKKGRlZmFsaWFzICd2aGRsLXRlbXBs YXRlLXByb2Nlc3MtaG9vayAjW25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwtaG9va2VkLWFiYnJl diB2aGRsLXRlbXBsYXRlLXByb2Nlc3NdIDJdKQooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtcXVh bnRpdHktaG9vayAjW25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwtaG9va2VkLWFiYnJldiB2aGRs LXRlbXBsYXRlLXF1YW50aXR5XSAyXSkKKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXJlcG9ydC1o b29rICNbbmlsICJcMzAwXDMwMSFcMjA3IiBbdmhkbC1ob29rZWQtYWJicmV2IHZoZGwtdGVtcGxh dGUtcmVwb3J0XSAyXSkKKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXJldHVybi1ob29rICNbbmls ICJcMzAwXDMwMSFcMjA3IiBbdmhkbC1ob29rZWQtYWJicmV2IHZoZGwtdGVtcGxhdGUtcmV0dXJu XSAyXSkKKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXNlbGVjdGVkLXNpZ25hbC1hc3N0LWhvb2sg I1tuaWwgIlwzMDBcMzAxIVwyMDciIFt2aGRsLWhvb2tlZC1hYmJyZXYgdmhkbC10ZW1wbGF0ZS1z ZWxlY3RlZC1zaWduYWwtYXNzdF0gMl0pCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1zaWduYWwt aG9vayAjW25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwtaG9va2VkLWFiYnJldiB2aGRsLXRlbXBs YXRlLXNpZ25hbF0gMl0pCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1zdWJuYXR1cmUtaG9vayAj W25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwtaG9va2VkLWFiYnJldiB2aGRsLXRlbXBsYXRlLXN1 Ym5hdHVyZV0gMl0pCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1zdWJ0eXBlLWhvb2sgI1tuaWwg IlwzMDBcMzAxIVwyMDciIFt2aGRsLWhvb2tlZC1hYmJyZXYgdmhkbC10ZW1wbGF0ZS1zdWJ0eXBl XSAyXSkKKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXRlcm1pbmFsLWhvb2sgI1tuaWwgIlwzMDBc MzAxIVwyMDciIFt2aGRsLWhvb2tlZC1hYmJyZXYgdmhkbC10ZW1wbGF0ZS10ZXJtaW5hbF0gMl0p CihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS10eXBlLWhvb2sgI1tuaWwgIlwzMDBcMzAxIVwyMDci IFt2aGRsLWhvb2tlZC1hYmJyZXYgdmhkbC10ZW1wbGF0ZS10eXBlXSAyXSkKKGRlZmFsaWFzICd2 aGRsLXRlbXBsYXRlLXVzZS1ob29rICNbbmlsICJcMzAwXDMwMSFcMjA3IiBbdmhkbC1ob29rZWQt YWJicmV2IHZoZGwtdGVtcGxhdGUtdXNlXSAyXSkKKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXZh cmlhYmxlLWhvb2sgI1tuaWwgIlwzMDBcMzAxIVwyMDciIFt2aGRsLWhvb2tlZC1hYmJyZXYgdmhk bC10ZW1wbGF0ZS12YXJpYWJsZV0gMl0pCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS13YWl0LWhv b2sgI1tuaWwgIlwzMDBcMzAxIVwyMDciIFt2aGRsLWhvb2tlZC1hYmJyZXYgdmhkbC10ZW1wbGF0 ZS13YWl0XSAyXSkKKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXdoZW4taG9vayAjW25pbCAiXDMw MFwzMDEhXDIwNyIgW3ZoZGwtaG9va2VkLWFiYnJldiB2aGRsLXRlbXBsYXRlLXdoZW5dIDJdKQoo ZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtd2hpbGUtbG9vcC1ob29rICNbbmlsICJcMzAwXDMwMSFc MjA3IiBbdmhkbC1ob29rZWQtYWJicmV2IHZoZGwtdGVtcGxhdGUtd2hpbGUtbG9vcF0gMl0pCihk ZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS13aXRoLWhvb2sgI1tuaWwgIlwzMDBcMzAxIVwyMDciIFt2 aGRsLWhvb2tlZC1hYmJyZXYgdmhkbC10ZW1wbGF0ZS13aXRoXSAyXSkKKGRlZmFsaWFzICd2aGRs LXRlbXBsYXRlLWFuZC1ob29rICNbbmlsICJcMzAwXDMwMSFcMjA3IiBbdmhkbC1ob29rZWQtYWJi cmV2IHZoZGwtdGVtcGxhdGUtYW5kXSAyXSkKKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLW9yLWhv b2sgI1tuaWwgIlwzMDBcMzAxIVwyMDciIFt2aGRsLWhvb2tlZC1hYmJyZXYgdmhkbC10ZW1wbGF0 ZS1vcl0gMl0pCihkZWZhbGlhcyAndmhkbC10ZW1wbGF0ZS1uYW5kLWhvb2sgI1tuaWwgIlwzMDBc MzAxIVwyMDciIFt2aGRsLWhvb2tlZC1hYmJyZXYgdmhkbC10ZW1wbGF0ZS1uYW5kXSAyXSkKKGRl ZmFsaWFzICd2aGRsLXRlbXBsYXRlLW5vci1ob29rICNbbmlsICJcMzAwXDMwMSFcMjA3IiBbdmhk bC1ob29rZWQtYWJicmV2IHZoZGwtdGVtcGxhdGUtbm9yXSAyXSkKKGRlZmFsaWFzICd2aGRsLXRl bXBsYXRlLXhvci1ob29rICNbbmlsICJcMzAwXDMwMSFcMjA3IiBbdmhkbC1ob29rZWQtYWJicmV2 IHZoZGwtdGVtcGxhdGUteG9yXSAyXSkKKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLXhub3ItaG9v ayAjW25pbCAiXDMwMFwzMDEhXDIwNyIgW3ZoZGwtaG9va2VkLWFiYnJldiB2aGRsLXRlbXBsYXRl LXhub3JdIDJdKQooZGVmYWxpYXMgJ3ZoZGwtdGVtcGxhdGUtbm90LWhvb2sgI1tuaWwgIlwzMDBc MzAxIVwyMDciIFt2aGRsLWhvb2tlZC1hYmJyZXYgdmhkbC10ZW1wbGF0ZS1ub3RdIDJdKQooZGVm YWxpYXMgJ3ZoZGwtdGVtcGxhdGUtZGVmYXVsdC1ob29rICNbbmlsICJcMzAwXDMwMSFcMjA3IiBb dmhkbC1ob29rZWQtYWJicmV2IHZoZGwtdGVtcGxhdGUtZGVmYXVsdF0gMl0pCihkZWZhbGlhcyAn dmhkbC10ZW1wbGF0ZS1kZWZhdWx0LWluZGVudC1ob29rICNbbmlsICJcMzAwXDMwMSFcMjA3IiBb dmhkbC1ob29rZWQtYWJicmV2IHZoZGwtdGVtcGxhdGUtZGVmYXVsdC1pbmRlbnRdIDJdKQojQDUx IEluc2VydCB0aGUgYnVpbHQtaW4gY29uc3RydWN0IHRlbXBsYXRlIHdpdGggTkFNRS4fCihkZWZh bGlhcyAndmhkbC10ZW1wbGF0ZS1pbnNlcnQtY29uc3RydWN0ICNbKG5hbWUpICJcMzAyXDMwMwgJ XCJBQCFcMjA3IiBbbmFtZSB2aGRsLXRlbXBsYXRlLWNvbnN0cnVjdC1hbGlzdCB2aGRsLXRlbXBs YXRlLWluc2VydC1mdW4gYXNzb2NdIDQgKCMkIC4gMjQ0NzU5KSAobGlzdCAobGV0ICgoY29tcGxl dGlvbi1pZ25vcmUtY2FzZSB0KSkgKGNvbXBsZXRpbmctcmVhZCAiQ29uc3RydWN0IG5hbWU6ICIg dmhkbC10ZW1wbGF0ZS1jb25zdHJ1Y3QtYWxpc3QgbmlsIHQpKSldKQojQDQ5IEluc2VydCB0aGUg YnVpbHQtaW4gcGFja2FnZSB0ZW1wbGF0ZSB3aXRoIE5BTUUuHwooZGVmYWxpYXMgJ3ZoZGwtdGVt cGxhdGUtaW5zZXJ0LXBhY2thZ2UgI1sobmFtZSkgIlwzMDJcMzAzCAlcIkFAIVwyMDciIFtuYW1l IHZoZGwtdGVtcGxhdGUtcGFja2FnZS1hbGlzdCB2aGRsLXRlbXBsYXRlLWluc2VydC1mdW4gYXNz b2NdIDQgKCMkIC4gMjQ1MDg5KSAobGlzdCAobGV0ICgoY29tcGxldGlvbi1pZ25vcmUtY2FzZSB0 KSkgKGNvbXBsZXRpbmctcmVhZCAiUGFja2FnZSBuYW1lOiAiIHZoZGwtdGVtcGxhdGUtcGFja2Fn ZS1hbGlzdCBuaWwgdCkpKV0pCiNANTEgSW5zZXJ0IHRoZSBidWlsdC1pbiBkaXJlY3RpdmUgdGVt cGxhdGUgd2l0aCBOQU1FLh8KKGRlZmFsaWFzICd2aGRsLXRlbXBsYXRlLWluc2VydC1kaXJlY3Rp dmUgI1sobmFtZSkgIlwzMDJcMzAzCAlcIkFAIVwyMDciIFtuYW1lIHZoZGwtdGVtcGxhdGUtZGly ZWN0aXZlLWFsaXN0IHZoZGwtdGVtcGxhdGUtaW5zZXJ0LWZ1biBhc3NvY10gNCAoIyQgLiAyNDU0 MDkpIChsaXN0IChsZXQgKChjb21wbGV0aW9uLWlnbm9yZS1jYXNlIHQpKSAoY29tcGxldGluZy1y ZWFkICJEaXJlY3RpdmUgbmFtZTogIiB2aGRsLXRlbXBsYXRlLWRpcmVjdGl2ZS1hbGlzdCBuaWwg dCkpKV0pCiNANDEgQ2FsbCBGVU4gdG8gaW5zZXJ0IGEgYnVpbHQtaW4gdGVtcGxhdGUuHwooZGVm YWxpYXMgJ3ZoZGwtdGVtcGxhdGUtaW5zZXJ0LWZ1biAjWyhmdW4pICJcMzAxXDMwMlwyMTVcMjEx GDtcMjA1XGYAXDMwMwghKVwyMDciIFtjYXVnaHQgYWJvcnQgKGJ5dGUtY29kZSAiCFwyMDUGAAgg XDIwNyIgW2Z1bl0gMSkgbWVzc2FnZV0gMyAoIyQgLiAyNDU3MzkpXSkKI0A0NSBJbnNlcnQgdGhl IHVzZXIgbW9kZWwgd2l0aCBuYW1lIE1PREVMLU5BTUUuHwooZGVmYWxpYXMgJ3ZoZGwtbW9kZWwt aW5zZXJ0ICNbKG1vZGVsLW5hbWUpICJcMzA2IFwyMTBcMzA3IFwzMTAgXDMxMVwzMTJcMjExXDIx MVwyMTFcMjExGBkaGxwdHiMeJFwzMTIeJVwzMTNcMzE0XDMxNQ4mI1wyMTBcMzE2DicOKFwiXDIx MRRcMjA1XDM1NQBcMzE3eVwyMTBcMzIwIFwyMTAOJGJcMjEwXDMyMVxmQUAhXDIxMFwzMDcgEA4k YlwyMTBcMzE3eVwyMTBgCFdcMjAzXgBcMzIyXDMyMyFcMjA0WABcMzI0XDMyNQ4jXCJcMjEwXDMy NnlcMjEwXDIwMkYADiRiXDIxMA4pXDMyN1wyMzJcMjA0eQBcMzMwXDMzMQhcMzExI1wyMDN5AFwz MzIOKSFcMjEwXDIwMmkADiRiXDIxMA4qXDMyN1wyMzJcMjA0XDIyNABcMzMwXDMzMwhcMzExI1wy MDNcMjI0AFwzMzIOKiFcMjEwXDIwMlwyMDQADiRiXDIxMFwzMzBcMzM0DitcMzM1UQhcMzExI1wy MDNcMzMxAFwzMzZcMzI2IVwzMzdcMjMyXDIwNFwyMzAAXDMyNlwyMjQTXDMzNlwzMjYhElwzMzJc MzI3IVwyMTBcMzQwXG5cMzEyXDMxMSMRXDMzMFwzMzRcblwzMzVRCFwzMTEjXDIwM1wzMjMAXDMz MglcMjA2XDMxNgBcMzI3IVwyMTBcMjAyXDI3NQALYlwyMTBcMjAyXDIzMAAOJGJcMjEwXDMzMFwz NDEIXDMxMSNcMjAzXDM1MwBcMzMyXDMyNyFcMjAyXDM1NQAIYhYlDixcMjA0XDM3MwBcMzEzXDMx NFwzNDIOJiNcMjEwDiUuCVwyMDciIFtlbmQgc3RyaW5nIHByb21wdCBwb3NpdGlvbiBtb2RlbCBj YXNlLWZvbGQtc2VhcmNoIHZoZGwtaW5kZW50LWxpbmUgcG9pbnQtbWFya2VyIGN1cnJlbnQtaW5k ZW50YXRpb24gdCBuaWwgbW9kaWZ5LXN5bnRheC1lbnRyeSA5NSAidyIgYXNzb2MgMCBkZWxldGUt aG9yaXpvbnRhbC1zcGFjZSB2aGRsLWluc2VydC1zdHJpbmctb3ItZmlsZSBsb29raW5nLWF0ICJe JCIgaW5zZXJ0LWNoYXIgMzIgMSAiIiByZS1zZWFyY2gtZm9yd2FyZCAiPGNsb2NrPiIgcmVwbGFj ZS1tYXRjaCAiPHJlc2V0PiIgIjxcXCgiICJcXCk+IiBtYXRjaC1zdHJpbmcgImN1cnNvciIgdmhk bC10ZW1wbGF0ZS1maWVsZCAiPGN1cnNvcj4iICJfIiBtYXJnaW4gc3RhcnQgcmVzdWx0IHZoZGwt bW9kZS1zeW50YXgtdGFibGUgbW9kZWwtbmFtZSB2aGRsLW1vZGVsLWFsaXN0IHZoZGwtY2xvY2st bmFtZSB2aGRsLXJlc2V0LW5hbWUgdmhkbC10ZW1wbGF0ZS1wcm9tcHQtc3ludGF4IHZoZGwtdW5k ZXJzY29yZS1pcy1wYXJ0LW9mLXdvcmRdIDggKCMkIC4gMjQ1OTQ1KSAobGV0ICgoY29tcGxldGlv bi1pZ25vcmUtY2FzZSB0KSkgKGxpc3QgKGNvbXBsZXRpbmctcmVhZCAiTW9kZWwgbmFtZTogIiB2 aGRsLW1vZGVsLWFsaXN0KSkpXSkKI0A0OSBEZWZpbmUgaGVscCBhbmQgaG9vayBmdW5jdGlvbnMg Zm9yIHVzZXIgbW9kZWxzLh8KKGRlZmFsaWFzICd2aGRsLW1vZGVsLWRlZnVuICNbbmlsICIIXDMw NFwyMTEZGlwyMTEbXDIwNUcAC0BAElwzMDVcMzA2XDMwN1wzMTBcblwiXDMwNFwzMTFcblwzMTJR XDMxM1wzMTRcbkRcMjU3BiFcMjEwXDMxNQtAOFwyMTERXDMxNlwyMzJcMjA0PwBcMzA1XDMwNlwz MDdcMzEwXG5cMzE3I1wzMDRcMzIwXDMyMVwzMDdcMzEwXG5cIkRERiFcMjEwC0FcMjExE1wyMDRc bgBcMzA0K1wyMDciIFt2aGRsLW1vZGVsLWFsaXN0IG1vZGVsLWtleXdvcmQgbW9kZWwtbmFtZSBt b2RlbC1hbGlzdCBuaWwgZXZhbCBkZWZ1biB2aGRsLWZ1bmN0aW9uLW5hbWUgInZoZGwtbW9kZWwi ICJJbnNlcnQgbW9kZWwgZm9yIFwiIiAiXCIuIiAoaW50ZXJhY3RpdmUpIHZoZGwtbW9kZWwtaW5z ZXJ0IDMgIiIgImhvb2siIHZoZGwtaG9va2VkLWFiYnJldiBxdW90ZV0gMTAgKCMkIC4gMjQ3Mjky KV0pCih2aGRsLW1vZGVsLWRlZnVuKQojQDQwIFZhcmlhYmxlIHRvIGhvbGQgbGFzdCBQT1JUIG1h cCBwYXJzZWQuHwooZGVmdmFyIHZoZGwtcG9ydC1saXN0IG5pbCAoIyQgLiAyNDc4MDcpKQojQDEz MSBDaGVjayB0aGF0IHRoZSB0ZXh0IGZvbGxvd2luZyBwb2ludCBtYXRjaGVzIHRoZSByZWdleHAg aW4gU1RSSU5HLgpFTkQgaXMgdGhlIHBvaW50IGJleW9uZCB3aGljaCBtYXRjaGluZy9zZWFyY2hp bmcgc2hvdWxkIG5vdCBnby4fCihkZWZhbGlhcyAndmhkbC1wYXJzZS1zdHJpbmcgI1soc3RyaW5n ICZvcHRpb25hbCBvcHRpb25hbCkgIlwzMDIIIVwyMDNcZgBcMzAzCFwzMDRcMzA1I1wyMDcJXDIw NBkAXDMwNlwzMDdcMzEwXDMxMVwzMTIgXCJcIlwyMTBcMzA0XDIwNyIgW3N0cmluZyBvcHRpb25h bCBsb29raW5nLWF0IHJlLXNlYXJjaC1mb3J3YXJkIG5pbCB0IHRocm93IHBhcnNlIGZvcm1hdCAi U3ludGF4IGVycm9yIG5lYXIgbGluZSAlcyIgdmhkbC1jdXJyZW50LWxpbmVdIDUgKCMkIC4gMjQ3 ODk1KV0pCiNANjMgUmVwbGFjZSBTVFJJTkcgZnJvbSBjYXIgb2YgUkVHRVhQLUNPTlMgdG8gY2Ry IG9mIFJFR0VYUC1DT05TLh8KKGRlZmFsaWFzICd2aGRsLXJlcGxhY2Utc3RyaW5nICNbKHJlZ2V4 cC1jb25zIHN0cmluZykgIlwzMDUYXDMwNlwzMDdcMzEwCSNcMjEwXDMxMVxuQAtcIlwyMDMaAFwz MTJcbkFcMzEzXDMwNQskXDIwMhsACxBcZlwyMDQmAFwzMDZcMzA3XDMxNAkjXDIxMAgpXDIwNyIg W3Jlc3VsdCB2aGRsLW1vZGUtc3ludGF4LXRhYmxlIHJlZ2V4cC1jb25zIHN0cmluZyB2aGRsLXVu ZGVyc2NvcmUtaXMtcGFydC1vZi13b3JkIG5pbCBtb2RpZnktc3ludGF4LWVudHJ5IDk1ICJ3IiBz dHJpbmctbWF0Y2ggcmVwbGFjZS1tYXRjaCB0ICJfIl0gNSAoIyQgLiAyNDgzMDQpXSkKI0A2NiBG bGF0dGVuIHBvcnQgbGlzdCBzbyB0aGF0IG9ubHkgb25lIGdlbmVyaWMvcG9ydCBleGlzdHMgcGVy IGxpbmUuHwooZGVmYWxpYXMgJ3ZoZGwtcG9ydC1mbGF0dGVuICNbbmlsICIIXDIwNAgAXDMwNlwz MDchXDIwN1wzMTBcMzExIVwyMTAIQEMIQVwzMTJcMjExXDIxMVwyMTFcMjExGRobHB0eDR4ODg1c MjAzYwAODUAVXDMxMhQNXDIwM1MADUBcMjExE0BcMjExEVwyMDNMAAlAQwtBQhJcMzEzXGZcbkNc IhQJQVwyMTERXDIwNDgADUFcMjExFVwyMDQuAA4NQRYNXDMxMw4OXGZDXCIWDlwyMDIfAA4OEFwz MTBcMzE0IS4HXDIwNyIgW3ZoZGwtcG9ydC1saXN0IG5hbWVzIG5ldy1wb3J0IG9sZC1wb3J0IG5l dy1wb3J0LWxpc3Qgb2xkLXBvcnQtbGlzdCBlcnJvciAiTm8gcG9ydCByZWFkIiBtZXNzYWdlICJG bGF0dGVuaW5nIHBvcnQuLi4iIG5pbCBhcHBlbmQgIkZsYXR0ZW5pbmcgcG9ydC4uLmRvbmUiIG9s ZC12aGRsLXBvcnQtbGlzdCBuZXctdmhkbC1wb3J0LWxpc3RdIDggKCMkIC4gMjQ4NjkwKSBuaWxd KQojQDc1IEdldCBnZW5lcmljIGFuZCBwb3J0IGluZm9ybWF0aW9uIGZyb20gYW4gZW50aXR5IG9y IGNvbXBvbmVudCBkZWNsYXJhdGlvbi4fCihkZWZhbGlhcyAndmhkbC1wb3J0LWNvcHkgI1tuaWwg IlwzMDZcMzA3IVwyMTBcMjEyXDMxMFwzMTFcMjExXDIxMVwyMTFcMjExXDIxMVwyMTFcMjExXDIx MVwyMTFcMjExGBkaGxwdHhIeEx4UHhUeFh4XXDMxMR4YXDMxMlwzMTNcMzE0DhkjXDIxMFwzMTVc MzE2XDIxNVwyMTEWFhYYDhpcMjA0QQBcMzEyXDMxM1wzMTcOGSNcMjEwKQ4WXDIwM04AXDMyMA4W IVwyMDJaAA4UDhMOEkUWG1wzMDZcMzIxIS4NXDIwNyIgW2NvbW1lbnQgaW5pdCB0eXBlIGRpcmVj dCBuYW1lcyBvYmplY3QgbWVzc2FnZSAiUmVhZGluZyBwb3J0Li4uIiB0IG5pbCBtb2RpZnktc3lu dGF4LWVudHJ5IDk1ICJ3IiBwYXJzZSAoYnl0ZS1jb2RlICJcMzA2XDMwN1wzMTBcMzExI1wyMDMQ AFwzMTJcMzEzIVwzMTRcMjMyXDIwMxUAXDMxNVwzMTZcMzE3XCJcMjEwXDMxM3ZcMjEwXDMyMFwz MjEhXDIxMFwzMTJcMzEzIRBcMzIyIFwyMTBcMzIwXDMyM1wzMTFcIlwyMDMfAVwzMjIgXDIxMFwz MjRcMzI1IREJXDIwNB8BXDMyMFwzMjYhXDIxMFwzMTJcMzEzIUMSXDMyMFwzMjdcMzExXCJcMjAz UABcMzMwXG5cMzEyXDMxMyFDXCISXDIwMj4AXDMyMFwzMzEhXDIxMFwzMTJcMzEzIRNcMzEwFFwz MjRcMzMyIVwyMDN2AAtgXDMzMyBcMjEwYHtcMzIwXDMzNFwzMTFcIlwyMDVxAFwzMTJcMzEzIVET XDIwMloAC1wyMDNcMjE1AFwzMzVcMzM2C1wiXDIwM1wyMTUAC1wzMzdcMjI0XDMxME8UC1wzNDBc MzEzXDIyNE8TXDMzNVwzNDELXCJcMjEwC1wzNDBcMzEzXDIyNU8TXDMxMBVcMzIwXDM0MlwzMTFc IlwyMDNcMzA1AFwzMjBcMzQzIVwyMTBcMzEyXDMxMyEVXDMyNFwzMzIhXDIwM1wzMDUADWBcMzMz IFwyMTBge1wzMjBcMzQzXDMxMVwiXDIwNVwzMDAAXDMxMlwzMTMhURVcMjAyXDI1MQANXDIwM1wz MzcAXDMzNVwzMzYNXCJcMjAzXDMzNwANXDMzN1wyMjRcMzEwTxQNXDM0MFwzMTNcMjI0TxVcMzIy IFwyMTBcMzQ0XDMxMHdcMjEwXGZcMjA0XDM2MgBcMzIwXDM0NVwzMTFcIlwyMDVcMzYxAFwzMTJc MzEzIRRcMzIyIFwyMTBcMzIwXDMyNVwzMTFcIhFcMzIwXDM0NiFcMjEwXGZcMjA0DQFcMzIwXDM0 NVwzMTFcIlwyMDVcZgFcMzEyXDMxMyEUXDMyMiBcMjEwXDMzMA4sXG4LDVxmRkNcIhYsXDIwMjEA XDMyMFwzNDdcMzExXCJcMjAzXDMzNQFcMzIyIFwyMTBcMzI0XDMyNSERCVwyMDRcMzM1AVwzMjBc MzUwXDMxMVwiXDIwNTsBXDMxMlwzMTMhFi1cMzIwXDMyNiFcMjEwXDMxMlwzMTMhQxJcMzIwXDMy N1wzMTFcIlwyMDNYAVwzMzBcblwzMTJcMzEzIUNcIhJcMjAyRgFcMzIwXDM1MSFcMjEwXDMyMFwz NTJcMzExXCJcMjA1ZgFcMzEyXDMxMyEWLlwzMjBcMzUzIVwyMTBcMzEyXDMxMyETXDMxMBRcMzI0 XDMzMiFcMjAzXDIxNgELYFwzMzMgXDIxMGB7XDMyMFwzNDNcMzExXCJcMjA1XDIxMQFcMzEyXDMx MyFRE1wyMDJyAVwzMzVcMzM2C1wiXDIwM1wyNDEBC1wzMzdcMjI0XDMxME8UC1wzNDBcMzEzXDIy NE8TXDMzNVwzNDELXCJcMjEwC1wzNDBcMzEzXDIyNU8TXDMyMiBcMjEwXDMyMFwzMjVcMzExXCIR XDMyMFwzNDYhXDIxMFxmXDIwNFwzMDcBXDMyMFwzNDVcMzExXCJcMjA1XDMwNgFcMzEyXDMxMyEU XDMyMiBcMjEwXDMzMA4vXG4OLQ4uC1xmXDI1NwVDXCIWL1wyMDItAVwzMTBcMjA3IiBbbmFtZSBl bmQtb2YtbGlzdCBuYW1lcyB0eXBlIGNvbW1lbnQgaW5pdCByZS1zZWFyY2gtYmFja3dhcmQgIl5c XHMtKlxcKGNvbXBvbmVudFxcfGVudGl0eVxcfGVuZFxcKVxcPiIgbmlsIHQgbWF0Y2gtc3RyaW5n IDEgImVuZCIgdGhyb3cgcGFyc2UgIk5vdCB3aXRoaW4gZW50aXR5IG9yIGNvbXBvbmVudCBkZWNs YXJhdGlvbiIgdmhkbC1wYXJzZS1zdHJpbmcgIlxccy0qXFwoXFx3K1xcKVxccy0qXFwoaXNcXCk/ XFxzLSokIiB2aGRsLWZvcndhcmQtc3ludGFjdGljLXdzICJnZW5lcmljWyAJXG5dKigiIGxvb2tp bmctYXQgIikiICJcXChcXHcrXFwpWyAJXG5dKiIgIixbIAlcbl0qXFwoXFx3K1xcKVsgCVxuXSoi IGFwcGVuZCAiOlsgCVxuXSpcXChbXigpOjtcbl0rXFwpIiAiKCIgZm9yd2FyZC1zZXhwICJcXChb XigpOjtcbl0qXFwpIiBzdHJpbmctbWF0Y2ggIlxcKFxccy0qLS1cXHMtKlxcKVxcKC4qXFwpIiAy IDAgIlxcKFxcKFxccy0qXFxTLStcXCkrXFwpXFxzLSoiICI6PVsgCVxuXSoiICJcXChbXigpO1xu XSpcXCkiICIgCSIgIi0tXFxzLSpcXChbXlxuXSpcXCkiICJcXHMtKjtcXHMtKiIgInBvcnRbIAlc bl0qKCIgIlxcKHNpZ25hbFxcfHF1YW50aXR5XFx8dGVybWluYWxcXClbIAlcbl0qIiAiOlsgCVxu XSoiICJcXChJTlxcfE9VVFxcfElOT1VUXFwpWyAJXG5dKyIgIlxcKFteKCk7XG5dK1xcKSIgZ2Vu ZXJpY3Mgb2JqZWN0IGRpcmVjdCBwb3J0c10gNykgIl8iIGVycm9yICJSZWFkaW5nIHBvcnQuLi5k b25lIiBwb3J0cyBnZW5lcmljcyBuYW1lIGVuZC1vZi1saXN0IHBhcnNlLWVycm9yIGNhc2UtZm9s ZC1zZWFyY2ggcmVzdWx0IHZoZGwtbW9kZS1zeW50YXgtdGFibGUgdmhkbC11bmRlcnNjb3JlLWlz LXBhcnQtb2Ytd29yZCB2aGRsLXBvcnQtbGlzdF0gMTIgKCMkIC4gMjQ5MjExKSBuaWxdKQojQDI1 IFBhc3RlIGEgZ2VuZXJpYyBjbGF1c2UuHwooZGVmYWxpYXMgJ3ZoZGwtcG9ydC1wYXN0ZS1nZW5l cmljICNbKCZvcHRpb25hbCBuby1pbml0KSAiXDMwNiBcMzA3XDIxMVwyMTFcMjExCEFAGRobHB0e FglcMjA1XDIzMwBgFFwzMTBcMzExIVwyMTAOF1wyMDQpAFwzMTJjXDIxMA4WDhhcXGpcMjEwaRUJ XDIwM1wyMjAACUBcMjExEkATC1wyMDNKAAtAY1wyMTALQVwyMTETXDIwMzUAXDMxM2NcMjEwXDIw MjUAXDMxNFxuQUBcMjYxAlwyMTAOGVwyMDRjAFwzMTVcbjhcMjAzYwBcMzE2XDMxNVxuOFwyNjEC XDIxMAlBXDIwNGsAXDMxN2NcMjEwXDMyMGNcMjEwDhpcMjAzXDIwMABcMzIxXG44XDIwM1wyMDAA XDMyMlwzMjFcbjhcMzIzXCJcMjEwCUFcMjExEVwyMDMrAFwzMTJjXDIxMA1qXDIxMFwyMDIrAA4b XDIwNVwyMzMAXDMyNFxmYFwzMjVcMzIzJC4GXDIwNyIgW3ZoZGwtcG9ydC1saXN0IGdlbmVyaWNz LWxpc3QgZ2VuZXJpYyBuYW1lcyBzdGFydCBsaXN0LW1hcmdpbiBjdXJyZW50LWluZGVudGF0aW9u IG5pbCB2aGRsLWluc2VydC1rZXl3b3JkICJHRU5FUklDICgiICJcbiIgIiwgIiAiIDogIiAyICIg Oj0gIiAiKSIgIjsiIDMgdmhkbC1jb21tZW50LWluc2VydC1pbmxpbmUgdCB2aGRsLWFsaWduLW5v aW5kZW50LXJlZ2lvbiAxIG1hcmdpbiB2aGRsLWFyZ3VtZW50LWxpc3QtaW5kZW50IHZoZGwtYmFz aWMtb2Zmc2V0IG5vLWluaXQgdmhkbC1pbmNsdWRlLXBvcnQtY29tbWVudHMgdmhkbC1hdXRvLWFs aWduXSA3ICgjJCAuIDI1MTgyNyldKQojQDIyIFBhc3RlIGEgcG9ydCBjbGF1c2UuHwooZGVmYWxp YXMgJ3ZoZGwtcG9ydC1wYXN0ZS1wb3J0ICNbbmlsICJcMzA2IFwzMDdcMjExXDIxMVwyMTFcMzEw CDgZGhscHR4XCVwyMDVcMjQzAGAUXDMxMVwzMTIhXDIxMA4YXDIwNCkAXDMxM2NcMjEwDhcOGVxc alwyMTBpFQlcMjAzXDIzMQAJQFwyMTESQUBcMjAzPwBcbkFAXDMxNFwyNjECXDIxMFxuQBMLXDIw M1cAC0BjXDIxMAtBXDIxMRNcMjAzQgBcMzE1Y1wyMTBcMjAyQgBcMzE2Y1wyMTBcMzEwXG44XDIw M2cAXDMxMFxuOFwzMTRcMjYxAlwyMTBcMzE3XG44Y1wyMTAJQVwyMDR0AFwzMjBjXDIxMFwzMjFj XDIxMA4aXDIwM1wyMTEAXDMyMlxuOFwyMDNcMjExAFwzMjNcMzIyXG44XDMyNFwiXDIxMAlBXDIx MRFcMjAzKwBcMzEzY1wyMTANalwyMTBcMjAyKwAOG1wyMDVcMjQzAFwzMjVcZmBcMzI2Iy4GXDIw NyIgW3ZoZGwtcG9ydC1saXN0IHBvcnRzLWxpc3QgcG9ydCBuYW1lcyBzdGFydCBsaXN0LW1hcmdp biBjdXJyZW50LWluZGVudGF0aW9uIG5pbCAyIHZoZGwtaW5zZXJ0LWtleXdvcmQgIlBPUlQgKCIg IlxuIiAiICIgIiwgIiAiIDogIiAzICIpIiAiOyIgNCB2aGRsLWNvbW1lbnQtaW5zZXJ0LWlubGlu ZSB0IHZoZGwtYWxpZ24tbm9pbmRlbnQtcmVnaW9uIDEgbWFyZ2luIHZoZGwtYXJndW1lbnQtbGlz dC1pbmRlbnQgdmhkbC1iYXNpYy1vZmZzZXQgdmhkbC1pbmNsdWRlLXBvcnQtY29tbWVudHMgdmhk bC1hdXRvLWFsaWduXSA4ICgjJCAuIDI1MjU5NSldKQojQDQ2IFBhc3RlIGFzIGFuIGVudGl0eSBv ciBjb21wb25lbnQgZGVjbGFyYXRpb24uHwooZGVmYWxpYXMgJ3ZoZGwtcG9ydC1wYXN0ZS1kZWNs YXJhdGlvbiAjWyhraW5kKSAiXDMwNiBcMjEwXDMwNyAIQBkaXDMxMAtcMzExPVwyMDMUAFwzMTJc MjAyFQBcMzEzIVwyMTAJY1wyMTALXDMxMT1cMjAzJABcMzEwXDMxNCFcMjEwCEFAXDIwM0cAXDMx NWNcMjEwXGZcMzE2PlwyMDM8AAtcMzExPVwyMDM8AFwzMTVjXDIxMFxuDVxcalwyMTBcMzE3C1wz MjA9IVwyMTBcMzIxCDhcMjAzZABcMzE1Y1wyMTBcZlwzMjI+XDIwM18AC1wzMTE9XDIwM18AXDMx NWNcMjEwXG4NXFxqXDIxMFwzMjMgXDIxMFwzMTVjXDIxMFxmXDMyND5cMjAzeQALXDMxMT1cMjAz eQBcMzE1Y1wyMTBcbmpcMjEwXDMxMFwzMjUhXDIxMAtcMzExPVwyMDNcMjU0AFwzMjYeG1wzMjYO HEA9XDIwNlwyMzQADhsOHFwyMTEeHUFAKT4pXDIwNFwyNDQAXDMxMFwzMjchXDIxMFwzMzAJXDI2 MQJcMjEwXDIwMlwzMTcAXDMxMFwzMzEhXDIxMFwzMjYeG1wzMjYOHEA9XDIwNlwzMDYADhsOHFwy MTEeHUFAKT4pXDIwNFwzMTcAXDMzMAlcMjYxAlwyMTBcMzMyYypcMjA3IiBbdmhkbC1wb3J0LWxp c3QgbmFtZSBtYXJnaW4ga2luZCB2aGRsLWluc2VydC1lbXB0eS1saW5lcyB2aGRsLWJhc2ljLW9m ZnNldCB2aGRsLWluZGVudC1saW5lIGN1cnJlbnQtaW5kZW50YXRpb24gdmhkbC1pbnNlcnQta2V5 d29yZCBlbnRpdHkgIkVOVElUWSAiICJDT01QT05FTlQgIiAiIElTIiAiXG4iICh1bml0IGFsbCkg dmhkbC1wb3J0LXBhc3RlLWdlbmVyaWMgY29tcG9uZW50IDIgKHVuaXQgYWxsKSB2aGRsLXBvcnQt cGFzdGUtcG9ydCAodW5pdCBhbGwpICJFTkQiIDg3ICIgRU5USVRZIiAiICIgIiBDT01QT05FTlQi ICI7IiBzdGFuZGFyZCB2aGRsLXN0YW5kYXJkIHhdIDMgKCMkIC4gMjUzMzQ1KV0pCiNAMzMgUGFz dGUgYXMgYW4gZW50aXR5IGRlY2xhcmF0aW9uLh8KKGRlZmFsaWFzICd2aGRsLXBvcnQtcGFzdGUt ZW50aXR5ICNbbmlsICIIXDIwNAgAXDMwMVwzMDIhXDIwN1wzMDNcMzA0IVwyMTBcMzA1XDMwNiFc MjEwXDMwM1wzMDchXDIwNyIgW3ZoZGwtcG9ydC1saXN0IGVycm9yICJObyBwb3J0IHJlYWQiIG1l c3NhZ2UgIlBhc3RpbmcgcG9ydCBhcyBlbnRpdHkuLi4iIHZoZGwtcG9ydC1wYXN0ZS1kZWNsYXJh dGlvbiBlbnRpdHkgIlBhc3RpbmcgcG9ydCBhcyBlbnRpdHkuLi5kb25lIl0gMiAoIyQgLiAyNTQy NzQpIG5pbF0pCiNAMzUgUGFzdGUgYXMgYSBjb21wb25lbnQgZGVjbGFyYXRpb24uHwooZGVmYWxp YXMgJ3ZoZGwtcG9ydC1wYXN0ZS1jb21wb25lbnQgI1tuaWwgIghcMjA0CABcMzAxXDMwMiFcMjA3 XDMwM1wzMDQhXDIxMFwzMDVcMzA2IVwyMTBcMzAzXDMwNyFcMjA3IiBbdmhkbC1wb3J0LWxpc3Qg ZXJyb3IgIk5vIHBvcnQgcmVhZCIgbWVzc2FnZSAiUGFzdGluZyBwb3J0IGFzIGNvbXBvbmVudC4u LiIgdmhkbC1wb3J0LXBhc3RlLWRlY2xhcmF0aW9uIGNvbXBvbmVudCAiUGFzdGluZyBwb3J0IGFz IGNvbXBvbmVudC4uLmRvbmUiXSAyICgjJCAuIDI1NDU3NykgbmlsXSkKI0AyNSBQYXN0ZSBhcyBh IGdlbmVyaWMgbWFwLh8KKGRlZmFsaWFzICd2aGRsLXBvcnQtcGFzdGUtZ2VuZXJpYy1tYXAgI1so Jm9wdGlvbmFsIHNlY29uZGFyeSBuby1jb25zdGFudHMpICIIXDIwNAcAXDMwNiBcMjEwXDMwNyBc MzEwXDIxMVwyMTEJQUAaGxwdHhhcblwyMDVcMjU0AGAUXDMxMVwzMTIhXDIxMA4ZXDIwNEMAXG5c MjA1XDI1NABcMzEzXG5AOFwyMDYwAFwzMTRjXDIxMFxuQVwyMTESXDIwMz0AXDMxNVwyMDI+AFwz MTZjXDIxMFwyMDIkAA4aXDIwNFIAXDMxN2NcMjEwDhgOG1xcalwyMTBpFVxuXDIwM1wyNDEAXG5A XDIxMRNAQFwzMjAOHFwyMDNqAAtAQFwyMDJxAFwzMTMLOFwyMDZxAFwzMjFcMjYxA1wyMTBcbkFc MjExElwyMDN/AFwzMjJcMjAyXDIwMABcMzE2Y1wyMTAOHVwyMDNcMjI0AFwzMjMLOFwyMDNcMjI0 AFwzMjRcMzIzCzhcMzI1XCJcMjEwXG5cMjAzVABcMzE3Y1wyMTANalwyMTBcMjAyVAAOHlwyMDVc MjU0AFwzMjZcZmBcMzI3XDMyNSQtXDIwNyIgW3NlY29uZGFyeSB2aGRsLXBvcnQtbGlzdCBnZW5l cmljcy1saXN0IGdlbmVyaWMgc3RhcnQgbGlzdC1tYXJnaW4gdmhkbC1pbmRlbnQtbGluZSBjdXJy ZW50LWluZGVudGF0aW9uIG5pbCB2aGRsLWluc2VydC1rZXl3b3JkICJHRU5FUklDIE1BUCAoIiAy ICIgIiAiLCAiICIpIiAiXG4iICIgPT4gIiAiIiAiLCIgMyB2aGRsLWNvbW1lbnQtaW5zZXJ0LWlu bGluZSB0IHZoZGwtYWxpZ24tbm9pbmRlbnQtcmVnaW9uIDEgbWFyZ2luIHZoZGwtYXNzb2NpYXRp b24tbGlzdC13aXRoLWZvcm1hbHMgdmhkbC1hcmd1bWVudC1saXN0LWluZGVudCB2aGRsLWJhc2lj LW9mZnNldCBuby1jb25zdGFudHMgdmhkbC1pbmNsdWRlLXBvcnQtY29tbWVudHMgdmhkbC1hdXRv LWFsaWduXSA2ICgjJCAuIDI1NDg5NCkgbmlsXSkKI0AyMiBQYXN0ZSBhcyBhIHBvcnQgbWFwLh8K KGRlZmFsaWFzICd2aGRsLXBvcnQtcGFzdGUtcG9ydC1tYXAgI1tuaWwgIlwzMDYgXDMwN1wyMTFc MjExXDMxMAg4GRobHB0JXDIwNVwyNzUAYBNcMzExXDMxMiFcMjEwDhpcMjA0OwAJXDIwNVwyNzUA XDMxMw4bCUBAQFwiY1wyMTAJQVwyMTERXDIwMzUAXDMxNFwyMDI2AFwzMTVjXDIxMFwyMDIcAA4c XDIwNEkAXDMxNmNcMjEwDQ4dXFxqXDIxMGkUCVwyMDNcMjYzAAlAXDIxMRJAQFwzMTdcMjYxAlwy MTBcMzEzDhtcbkBAXCJjXDIxMAlBXDIxMRFcMjAzbQBcMzIwXDIwMm4AXDMxNWNcMjEwDh5cMjA0 XDIwMAAOH1wyMDNcMjQ2AFwzMjFcbjhcMjAzXDI0NgBcMzIyDh5cMjAzXDIyNQBcMzIzXDMyNFwz MTBcbjhcMzI1UFwyMDZcMjIxAFwzMjZcIlwyMDJcMjI2AFwzMjYOH1wyMDNcMjQxAFwzMjFcbjhc MjAyXDI0MgBcMzI2UFwzMjdcIlwyMTAJXDIwM0sAXDMxNmNcMjEwXGZqXDIxMFwyMDJLAA4gXDIw NVwyNzUAXDMzMAtgXDMzMSMtXDIwNyIgW3ZoZGwtcG9ydC1saXN0IHBvcnRzLWxpc3QgcG9ydCBz dGFydCBsaXN0LW1hcmdpbiBtYXJnaW4gY3VycmVudC1pbmRlbnRhdGlvbiBuaWwgMiB2aGRsLWlu c2VydC1rZXl3b3JkICJQT1JUIE1BUCAoIiB2aGRsLXJlcGxhY2Utc3RyaW5nICIsICIgIik7IiAi XG4iICIgPT4gIiAiLCIgNCB2aGRsLWNvbW1lbnQtaW5zZXJ0LWlubGluZSBmb3JtYXQgIiUtNHMi ICIgIiAiIiB0IHZoZGwtYWxpZ24tbm9pbmRlbnQtcmVnaW9uIDEgdmhkbC1hc3NvY2lhdGlvbi1s aXN0LXdpdGgtZm9ybWFscyB2aGRsLWFjdHVhbC1wb3J0LW5hbWUgdmhkbC1hcmd1bWVudC1saXN0 LWluZGVudCB2aGRsLWJhc2ljLW9mZnNldCB2aGRsLWluY2x1ZGUtZGlyZWN0aW9uLWNvbW1lbnRz IHZoZGwtaW5jbHVkZS1wb3J0LWNvbW1lbnRzIHZoZGwtYXV0by1hbGlnbl0gNyAoIyQgLiAyNTU3 OTQpXSkKI0AyOCBQYXN0ZSBhcyBhbiBpbnN0YW50aWF0aW9uLh8KKGRlZmFsaWFzICd2aGRsLXBv cnQtcGFzdGUtaW5zdGFuY2UgI1soJm9wdGlvbmFsIG5hbWUpICIIXDIwNAgAXDMwNlwzMDchXDIw NwgZXDMxMCBcMjEwXDMxMSBcMjEwXDMxMiBcMzEzXDIxMVwyMTFcMjExCEFAXDMxNAg4GhscHR4d Hh4eHw4gXDIwMzQADiBcMzE1XDI2MQJcMjEwXDIwMk4ADiFBXDMxNlwyMzJcMjAzRABcMzE3XDMy MFwzMTVcIlwyMTBcMjAyTgBcMzIxDiEIQFwiXDMxNVwyNjECXDIxMFwzMjJcMzIzIVwyMTBcMzI0 HlwiXDMyNA4jQD1cMjA2aAAOXCIOI1wyMTEeJEFAKT4pXDIwM3MACEBjXDIxMFwyMDJ9AFwzMjVc MzI2IVwyMTBcMzI3CEBcMjYxAlwyMTAIQUBcMjAzXDIyMgBcMzMwY1wyMTAOHw4lXFxqXDIxMFwz MzFcMzMyXDIxMVwiXDIxMFwzMTQIOFwyMDNcMjQ1AFwzMzBjXDIxMA4fDiVcXGpcMjEwXDMzMyBc MjEwXDMyMlwzMzQhXDIxMC4HCVwyMTEQKVwyMDciIFt2aGRsLXBvcnQtbGlzdCBvcmlnLXZoZGwt cG9ydC1saXN0IHBvcnRzLWxpc3QgZ2VuZXJpY3MtbGlzdCBwb3J0IGdlbmVyaWMgZXJyb3IgIk5v IHBvcnQgcmVhZCIgdmhkbC1wb3J0LWZsYXR0ZW4gdmhkbC1pbmRlbnQtbGluZSBjdXJyZW50LWlu ZGVudGF0aW9uIG5pbCAyICI6ICIgIiIgdmhkbC10ZW1wbGF0ZS1maWVsZCAiaW5zdGFuY2UgbmFt ZSIgdmhkbC1yZXBsYWNlLXN0cmluZyBtZXNzYWdlICJQYXN0aW5nIHBvcnQgYXMgaW5zdGFudGlh dGlvbi4uLiIgODcgdmhkbC1pbnNlcnQta2V5d29yZCAiRU5USVRZICIgIndvcmsuIiAiXG4iIHZo ZGwtcG9ydC1wYXN0ZS1nZW5lcmljLW1hcCB0IHZoZGwtcG9ydC1wYXN0ZS1wb3J0LW1hcCAiUGFz dGluZyBwb3J0IGFzIGluc3RhbnRpYXRpb24uLi5kb25lIiBzdGFydCBsaXN0LW1hcmdpbiBtYXJn aW4gbmFtZSB2aGRsLWluc3RhbmNlLW5hbWUgc3RhbmRhcmQgdmhkbC1zdGFuZGFyZCB4IHZoZGwt YmFzaWMtb2Zmc2V0XSA4ICgjJCAuIDI1NjczOSkgbmlsXSkKI0AzNCBQYXN0ZSBwb3J0cyBhcyBp bnRlcm5hbCBzaWduYWxzLh8KKGRlZmFsaWFzICd2aGRsLXBvcnQtcGFzdGUtc2lnbmFscyAjWygm b3B0aW9uYWwgaW5pdGlhbGl6ZSkgIghcMjA0CABcMzA2XDMwNyFcMjA3XDMxMFwzMTEhXDIxMFwz MTIgXDIxMFwzMTMgXDMxNFwyMTFcMjExXDMxNQg4GRobHB0JXDIwM1wyNTcAYBQJXDIwM1wyNDQA CUBcMjExE0FAXDIwMzkAC0FAXDMxNlwyNjECXDIxMFwyMDI9AFwzMTdcMzIwIVwyMTALQBJcblwy MDNZAFwzMjEOI1xuQFwiY1wyMTBcbkFcMjExElwyMDNAAFwzMjJjXDIxMFwyMDJAAFwzMjNcMzI0 CzhcMjYxAlwyMTAOJFwyMDN/AFwzMTULOFwzMjVcMjMyXDIwM38AXDMyNlwzMjdcMzMwXDMyNAs4 XCJcMjAzewBcMzMxXDIwMnwAXDMzMlwyNjECXDIxMFwzMzNjXDIxMA4lXDIwM1wyMjQAXDMzNAs4 XDIwM1wyMjQAXDMzNVwzMzQLOFwzMzZcIlwyMTAJQVwyMTERXDIwM1wiAFwzMzdjXDIxMA1qXDIx MFwyMDJcIgAOJlwyMDNcMjU3AFwzNDBcZmBcMzQxI1wyMTAtXDMxMFwzNDIhXDIwNyIgW3ZoZGwt cG9ydC1saXN0IHBvcnRzLWxpc3QgbmFtZXMgcG9ydCBzdGFydCBtYXJnaW4gZXJyb3IgIk5vIHBv cnQgcmVhZCIgbWVzc2FnZSAiUGFzdGluZyBwb3J0IGFzIHNpZ25hbHMuLi4iIHZoZGwtaW5kZW50 LWxpbmUgY3VycmVudC1pbmRlbnRhdGlvbiBuaWwgMiAiICIgdmhkbC1pbnNlcnQta2V5d29yZCAi U0lHTkFMICIgdmhkbC1yZXBsYWNlLXN0cmluZyAiLCAiICIgOiAiIDMgImluIiAiIDo9ICIgc3Ry aW5nLW1hdGNoICIoLispIiAiKG90aGVycyA9PiAnMCcpIiAiJzAnIiAiOyIgNCB2aGRsLWNvbW1l bnQtaW5zZXJ0LWlubGluZSB0ICJcbiIgdmhkbC1hbGlnbi1ub2luZGVudC1yZWdpb24gMSAiUGFz dGluZyBwb3J0IGFzIHNpZ25hbHMuLi5kb25lIiB2aGRsLWFjdHVhbC1wb3J0LW5hbWUgaW5pdGlh bGl6ZSB2aGRsLWluY2x1ZGUtcG9ydC1jb21tZW50cyB2aGRsLWF1dG8tYWxpZ25dIDcgKCMkIC4g MjU3NzM4KSBuaWxdKQojQDMwIFBhc3RlIGdlbmVyaWNzIGFzIGNvbnN0YW50cy4fCihkZWZhbGlh cyAndmhkbC1wb3J0LXBhc3RlLWNvbnN0YW50cyAjW25pbCAiCFwyMDQIAFwzMDZcMzA3IVwyMDcI GVwzMTBcMzExIVwyMTBcMzEyIFwyMTBcMzEzIFwyMTBcMzE0IFwzMTVcMjExXDIxMQhBQBobHB0e G1xuXDIwM1wyMDMAYBVcblwyMDN4AFxuQBRcMzE2XDMxNyFcMjEwXGZAXDIxMRNcMjAzKAALQGNc MjEwXDMyMFxmQUBcMjYxAlwyMTBcMzIxXGY4XDIwM1IAXDMyMlwzMjFcZjhcMjYxAlwyMTBcMzIz Y1wyMTAOHFwyMDNnAFwzMjRcZjhcMjAzZwBcMzI1XDMyNFxmOFwzMjZcIlwyMTBcbkFcMjExElwy MDMoAFwzMjdjXDIxMA4balwyMTBcMjAyKAAOHVwyMDNcMjAzAFwzMzANYFwzMzEjXDIxMC1cMzEw XDMzMiFcMjEwCVwyMTEQKVwyMDciIFt2aGRsLXBvcnQtbGlzdCBvcmlnLXZoZGwtcG9ydC1saXN0 IGdlbmVyaWNzLWxpc3QgbmFtZSBnZW5lcmljIHN0YXJ0IGVycm9yICJObyBwb3J0IHJlYWQiIG1l c3NhZ2UgIlBhc3RpbmcgcG9ydCBhcyBjb25zdGFudHMuLi4iIHZoZGwtcG9ydC1mbGF0dGVuIHZo ZGwtaW5kZW50LWxpbmUgY3VycmVudC1pbmRlbnRhdGlvbiBuaWwgdmhkbC1pbnNlcnQta2V5d29y ZCAiQ09OU1RBTlQgIiAiIDogIiAyICIgOj0gIiAiOyIgMyB2aGRsLWNvbW1lbnQtaW5zZXJ0LWlu bGluZSB0ICJcbiIgdmhkbC1hbGlnbi1ub2luZGVudC1yZWdpb24gMSAiUGFzdGluZyBwb3J0IGFz IGNvbnN0YW50cy4uLmRvbmUiIG1hcmdpbiB2aGRsLWluY2x1ZGUtcG9ydC1jb21tZW50cyB2aGRs LWF1dG8tYWxpZ25dIDYgKCMkIC4gMjU4NzQyKSBuaWxdKQojQDM1IFBhc3RlIGFzIGEgYmFyZS1i b25lcyB0ZXN0IGJlbmNoLh8KKGRlZmFsaWFzICd2aGRsLXBvcnQtcGFzdGUtdGVzdGJlbmNoICNb bmlsICIIXDIwNAgAXDMwNlwzMDchXDIwN1wzMTBcMzExIVwyMTBcMzEyXDMxMwkIQFwicFwzMTRc MjExXDIxMVwyMTFcMjExGhscHR47HjwePR4+Dj9cMzE1PVwyMDRcMjAwAFwzMTZcMzE3XDMyMHAh XCJcMjEwDj1cMzIwcCFcMzIxXDIyNFwzMTRPUBVcMzIyDSFcMjAzdABcMzIzXDMyNA1cMzI1USFc MjAzZABcMzI2DSFcMjEwXDMyNw0hXDIwM3QADXFcMjEwXDMzMFwzMTQhXDIxMFwzMzENIVwyMTBc MjAydAAOP1wzMzI9XDIwM3AAXDMxMhNcMjAydABcMzA2XDMzMyFcMjEwC1wyMDRcMjAwAA48cVwy MTBcMzM0DSFcMjEwXDMyMR5ADj9cMzMyPVwyMDNcMjE2AAtcMjA0HQEOQVwzMzVcMjMyXDIwNFwy MzIAXDMzNg5BIVwyMTBcMzM3IFwyMTBcMzQwY1wyMTAOQGpcMjEwXDM0MVwzNDIhXDIxMFwzNDNj XDIxMA5AalwyMTBcMzQxXDM0NCFcMjEwXDM0NWNcMjEwXDM0MVwzNDYhXDIxMFwzNDBjXDIxMA5A alwyMTBcMzM3IFwyMTBcMzQwY1wyMTAOQGpcMjEwXDM0MVwzNDchXDIxMA49Y1wyMTBcMzQxXDM1 MCFcMjEwDkJcMzUxPlwyMDNcMzQxAFwzNTJjXDIxMFwzNTJjXDIxMA5AalwyMTBcMzQxXDM1MyFc MjEwXDM1NB5DXDM1NA5EQD1cMjA2AgEOQw5EXDIxMR5FQUApPilcMjA0XG4BXDM0MVwzNDchXDIx MA49XDM1NVwyNjECXDIxMFwzNDBjXDIxMA5AalwyMTBcMzM3IFwyMTBcMzUyY1wyMTAORkFcMzM1 XDIzMlwyMDMuAVwzNTZcMzU3XDMxNA5HI1wyMDI0AVwzMTMORghAXCIWOw4/XDMzMj1cMjAzXDIz MQFcMzYwIFwyMTBcMzE2XDMxN1wzMjBwIVwiXDIxMA47XDMyMHAhXDMyMVwyMjRcMzE0T1AUXDMy MlxmIVwyMDN/AVwzMjNcMzI0DVwzMjVRIVwyMDN7AVwzMjZcZiFcMjEwXDMyN1xmIVwyMDN/AVwz MjdcZiFxXDIxMFwzMzBcMzE0IVwyMTBcMzMxXGYhXDIxMFwyMDJ/AVwzMDZcMzMzIVwyMTAOPHFc MjEwXDMzNFxmIVwyMTAOSFwzMzVcMjMyXDIwNFwyMjMBXDMzNg5IIVwyMTBcMzM3IFwyMTBcMzUy Y1wyMTBcMzUyY1wyMTAOQGpcMjEwXDM0MVwzNjEhXDIxMA47Y1wyMTBcMzQxXDM2MiFcMjEwDj1j XDIxMFwzNDFcMzUwIVwyMTBcMzQwY1wyMTAOQGpcMjEwXDM1NB5DXDM1NA5EQD1cMjA2XDMyMQEO Qw5EXDIxMR5FQUApPilcMjAzXDMzNwFcMzYzIFwyMTBcMzQwY1wyMTAOQGpcMjEwCEFAXDIwM1wz NTcBXDM2NCBcMjEwXDM0MGNcMjEwDkBqXDIxMFwzNjUOSSFcMjEwDkpcMzM1XDIzMlwyMDQGAlwz NDBjXDIxMFwzMzYOSiFcMjEwXDM2NiBcMjEwYBJcMzQwY1wyMTAOQGpcMjEwXDMzNyBcMjEwXDM1 MmNcMjEwXG5iXDIxMFwzNjdcMzU0HkNcMzU0DkRAPVwyMDYvAg5DDkRcMjExHkVBQCk+KT9cMjA1 NQJcMzcwDjsOQFwzMTIkXDIxMFwzNzFcMzEzDksIQFwiIVwyMTBcMzUyY1wyMTAOTFwzMzVcMjMy XDIwNFcCXDM1MmNcMjEwXDMzNg5MIVwyMTBcMzUyY1wyMTAOQA5NXFxqXDIxMA4/XDMxNT1cMjA0 awJcMzYwIFwyMTBcMzEwXDM3MiEuCVwyMDciIFt2aGRsLXBvcnQtbGlzdCB2aGRsLXRlc3RiZW5j aC1lbnRpdHktbmFtZSBwb3NpdGlvbiBuby1lbnRpdHkgYXJjaC1maWxlLW5hbWUgZW50LWZpbGUt bmFtZSBlcnJvciAiTm8gcG9ydCByZWFkIiBtZXNzYWdlICJQYXN0aW5nIHBvcnQgYXMgdGVzdCBi ZW5jaC4uLiIgdCB2aGRsLXJlcGxhY2Utc3RyaW5nIG5pbCBub25lIHN0cmluZy1tYXRjaCAiXFwu W14uXSpcXCciIGJ1ZmZlci1maWxlLW5hbWUgMCBmaWxlLWV4aXN0cy1wIHktb3Itbi1wICJGaWxl IGAiICInIGV4aXN0czsgb3ZlcndyaXRlPyAiIGRlbGV0ZS1maWxlIGdldC1maWxlLWJ1ZmZlciBz ZXQtYnVmZmVyLW1vZGlmaWVkLXAga2lsbC1idWZmZXIgc2VwYXJhdGUgIlBhc3RpbmcgcG9ydCBh cyB0ZXN0IGJlbmNoLi4uYWJvcnRlZCIgZmluZC1maWxlICIiIHZoZGwtaW5zZXJ0LXN0cmluZy1v ci1maWxlIHZoZGwtY29tbWVudC1kaXNwbGF5LWxpbmUgIlxuXG4iIHZoZGwtaW5zZXJ0LWtleXdv cmQgIkxJQlJBUlkgIiAiaWVlZTtcbiIgIlVTRSAiICJpZWVlLnN0ZF9sb2dpY18xMTY0LiIgIkFM TDsiICJFTlRJVFkgIiAiIElTIiAodW5pdCBhbGwpICJcbiIgIkVORCAiIDg3ICI7IiByZWFkLWZy b20tbWluaWJ1ZmZlciAiYXJjaGl0ZWN0dXJlIG5hbWU6ICIgc2F2ZS1idWZmZXIgIkFSQ0hJVEVD VFVSRSAiICIgT0YgIiB2aGRsLXBvcnQtcGFzdGUtY29tcG9uZW50IHZoZGwtcG9ydC1wYXN0ZS1j b25zdGFudHMgdmhkbC1wb3J0LXBhc3RlLXNpZ25hbHMgZGVsZXRlLWluZGVudGF0aW9uIHZoZGwt dGVtcGxhdGUtYmVnaW4tZW5kICJBUkNISVRFQ1RVUkUiIHZoZGwtcG9ydC1wYXN0ZS1pbnN0YW5j ZSAiUGFzdGluZyBwb3J0IGFzIHRlc3QgYmVuY2guLi5kb25lIiBhcmNoLW5hbWUgc291cmNlLWJ1 ZmZlciBlbnQtbmFtZSBjYXNlLWZvbGQtc2VhcmNoIHZoZGwtdGVzdGJlbmNoLWNyZWF0ZS1maWxl cyBtYXJnaW4gdmhkbC10ZXN0YmVuY2gtZW50aXR5LWhlYWRlciB2aGRsLWluc2VydC1lbXB0eS1s aW5lcyBzdGFuZGFyZCB2aGRsLXN0YW5kYXJkIHggdmhkbC10ZXN0YmVuY2gtYXJjaGl0ZWN0dXJl LW5hbWUgdmhkbC1taW5pYnVmZmVyLWxvY2FsLW1hcCB2aGRsLXRlc3RiZW5jaC1hcmNoaXRlY3R1 cmUtaGVhZGVyIHZoZGwtdGVzdGJlbmNoLWluaXRpYWxpemUtc2lnbmFscyB2aGRsLXRlc3RiZW5j aC1kZWNsYXJhdGlvbnMgdmhkbC10ZXN0YmVuY2gtZHV0LW5hbWUgdmhkbC10ZXN0YmVuY2gtc3Rh dGVtZW50cyB2aGRsLWJhc2ljLW9mZnNldF0gOCAoIyQgLiAyNTk1NjEpIG5pbF0pCihieXRlLWNv ZGUgIlwzMDJcMzAwIVwyMDQIAFwzMDMQXDMwMAlCEVwzMDNcMjA3IiBbdmhkbC1leHBhbmQtdXBw ZXItY2FzZSBjdXJyZW50LWxvYWQtbGlzdCBib3VuZHAgbmlsXSAyKQojQDU0IFRyeSBleHBhbmRp bmcgYWJicmV2aWF0aW9ucyBmcm9tIGB2aGRsLWFiYnJldi1saXN0Jy4fCihkZWZhbGlhcyAndmhk bC10cnktZXhwYW5kLWFiYnJldiAjWyhvbGQpICIIXDIwNDIAXDMwNlwzMDcgYFwiXDIxMAlcMzEw GlwyMTEbXDIwMy4AC0A7XDIwM1wiAFwzMTFcMzEyXGZQC0BcIlwyMDMnAAtAXG5CEgtBXDIxMRNc MjA0EgBcblwyMzcqFQ1cMjAzVwANQDtcMjAzRgBcMzEzDUAOD1wzMTQjXDIwM1cADUA7XDIwNFAA DUAWEA1BXDIxMRVcMjA0NgANXDIwNGQACFwyMDNiAFwzMTUgXDIxMFwzMTBcMjA3XDMxNg4QXDIw M3AADUBcMjI2XDIwMnIADUBcMzE0XCJcMjEwDUEVXDMxNFwyMDciIFtvbGQgdmhkbC1hYmJyZXYt bGlzdCBzZWwtYWJicmV2LWxpc3QgYWJicmV2LWxpc3QgaGUtc2VhcmNoLXN0cmluZyBoZS1leHBh bmQtbGlzdCBoZS1pbml0LXN0cmluZyBoZS1kYWJicmV2LWJlZyBuaWwgc3RyaW5nLW1hdGNoICJe IiBoZS1zdHJpbmctbWVtYmVyIHQgaGUtcmVzZXQtc3RyaW5nIGhlLXN1YnN0aXR1dGUtc3RyaW5n IGhlLXRyaWVkLXRhYmxlIHZoZGwtZXhwYW5kLXVwcGVyLWNhc2VdIDUgKCMkIC4gMjYyNDc0KV0p CiNAMTMyIEFsc28gbG9va3MgYXQgdGhlIHdvcmQgYmVmb3JlIGAoJyBpbiBvcmRlciB0byBiZXR0 ZXIgbWF0Y2ggcGFyZW50aGVzaXplZApleHByZXNzaW9ucyAoZS5nLiBmb3IgaW5kZXggcmFuZ2Vz IG9mIHR5cGVzIGFuZCBzaWduYWxzKS4fCihkZWZhbGlhcyAndmhkbC1oZS1saXN0LWJlZyAjW25p bCAiXDIxMlwzMDBcMzAxXDMwMlwyMTdcMjEwYClcMjA3IiBbbmlsIChieXRlLWNvZGUgIlwzMDBc MzAxIVwyMTBcMzAyXDMwMyFcMjA3IiBbYmFja3dhcmQtdXAtbGlzdCAxIHNraXAtc3ludGF4LWJh Y2t3YXJkICJ3XyJdIDIpICgoZXJyb3IpKV0gMyAoIyQgLiAyNjMwNjIpXSkKKGJ5dGUtY29kZSAi XDMwMVwzMDAhXDIwM1xuAAhcMjA0EwBcMzAyXDMwMyFcMjEwXDMwNFwzMDVcMzA2XCJcMjEwXDMw N1wzMTBNXDIxMFwzMTFcMzEyTVwyMDciIFt2aXBlci1tb2RlIGJvdW5kcCByZXF1aXJlIGhpcHBp ZS1leHAgZGVmYWxpYXMgaGUtbGlzdC1iZWcgdmhkbC1oZS1saXN0LWJlZyB2aGRsLWV4cGFuZC1h YmJyZXYgI1soYXJnKSAiXDMwM1wzMDQYGVwzMDVcbiEqXDIwNyIgW2hpcHBpZS1leHBhbmQtdmVy Ym9zZSBoaXBwaWUtZXhwYW5kLXRyeS1mdW5jdGlvbnMtbGlzdCBhcmcgKHRyeS1leHBhbmQtZGFi YnJldiB0cnktZXhwYW5kLWRhYmJyZXYtYWxsLWJ1ZmZlcnMgdmhkbC10cnktZXhwYW5kLWFiYnJl dikgbmlsIGhpcHBpZS1leHBhbmRdIDIgIlRyeSB0byBleHBhbmQgdGV4dCBiZWZvcmUgcG9pbnQs IHVzaW5nIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zOiBcbnRyeS1leHBhbmQtZGFiYnJldiwgdHJ5 LWV4cGFuZC1kYWJicmV2LWFsbC1idWZmZXJzLCB2aGRsLXRyeS1leHBhbmQtYWJicmV2IiAiUCJd IHZoZGwtZXhwYW5kLXBhcmVuICNbKGFyZykgIlwzMDNcMzA0GBlcMzA1XG4hKlwyMDciIFtoaXBw aWUtZXhwYW5kLXZlcmJvc2UgaGlwcGllLWV4cGFuZC10cnktZnVuY3Rpb25zLWxpc3QgYXJnICh0 cnktZXhwYW5kLWxpc3QgdHJ5LWV4cGFuZC1saXN0LWFsbC1idWZmZXJzKSBuaWwgaGlwcGllLWV4 cGFuZF0gMiAiVHJ5IHRvIGV4cGFuZCB0ZXh0IGJlZm9yZSBwb2ludCwgdXNpbmcgdGhlIGZvbGxv d2luZyBmdW5jdGlvbnM6IFxudHJ5LWV4cGFuZC1saXN0LCB0cnktZXhwYW5kLWxpc3QtYWxsLWJ1 ZmZlcnMiICJQIl1dIDMpCiNAMTA5IENvbnZlcnQgYWxsIHdvcmRzIG1hdGNoaW5nIHdvcmQtcmVn ZXhwIGluIHJlZ2lvbiB0byBsb3dlciBvciB1cHBlciBjYXNlLApkZXBlbmRpbmcgb24gcGFyYW1l dGVyIHVwcGVyLWNhc2UuHwooZGVmYWxpYXMgJ3ZoZGwtZml4LWNhc2UtcmVnaW9uLTEgI1soYmVn IGVuZCB1cHBlci1jYXNlIHdvcmQtcmVnZXhwICZvcHRpb25hbCBjb3VudCkgIlwzMDZcMzA3XDMx MBgZGlwzMDcbXDMxMVwzMTJcMzEzXGYjXDIxMFwyMTINYlwyMTBcMzE0IBUOGmJcMjEwXDMxNQ4b DVwzMDYjXDIwM1wyMTIAYB4cXDIxMlwzMTB5XDIxMFwzMTVcMzE2DhxcMzA2IypcMjA0VwBgHhxc MjEyXDMxMHlcMjEwDhxcMzE1XDMxNw4cXDMwNiMqPVwyMDRXAA4dXDIwM1MAXDMyMFwzMjEhXDIx MFwyMDJXAFwzMjJcMzIxIVwyMTAOHlwyMDMZAA4fXDIwMxkADh9cMzIzIEFACFpXXDIwMxkAXDMy NFwzMjUOHlwzMjZfYA4aWlwzMjZfDQ4aWlwyNDVcXFwzMjcjXDIxMFwzMjMgQUAQXDIwMhkADWIp Ew4gXDIwNFwyMzEAXDMxMVwzMTJcMzMwXGYjXDIxMCkOHlwyMDVcMjQ3AA4fXDIwNVwyNDcAXDMy NFwzMzEhK1wyMDciIFtsYXN0LXVwZGF0ZSBjYXNlLXJlcGxhY2UgY2FzZS1mb2xkLXNlYXJjaCBy ZXN1bHQgdmhkbC1tb2RlLXN5bnRheC10YWJsZSBlbmQgdCBuaWwgMCBtb2RpZnktc3ludGF4LWVu dHJ5IDk1ICJ3IiBwb2ludC1tYXJrZXIgcmUtc2VhcmNoLWZvcndhcmQgIl5cXChbXlwiXSpcIlte XCJdKlwiXFwpKlteXCJdKi0tIiAiXlxcKFteXCJdKlwiW15cIl0qXCJcXCkqW15cIl0qXCJbXlwi XSoiIHVwY2FzZS13b3JkIC0xIGRvd25jYXNlLXdvcmQgY3VycmVudC10aW1lIG1lc3NhZ2UgIkZp eGluZyBjYXNlLi4uICglMmQlcykiIDI1ICIlIiAiXyIgIkZpeGluZyBjYXNlLi4uZG9uZSIgYmVn IHdvcmQtcmVnZXhwIHBvc2l0aW9uIHVwcGVyLWNhc2UgY291bnQgdmhkbC1wcm9ncmVzcy1pbnRl cnZhbCB2aGRsLXVuZGVyc2NvcmUtaXMtcGFydC1vZi13b3JkXSA2ICgjJCAuIDI2NDIxNyldKQoj QDEzOCBDb252ZXJ0IGFsbCBWSERMIHdvcmRzIGluIHJlZ2lvbiB0byBsb3dlciBvciB1cHBlciBj YXNlLCBkZXBlbmRpbmcgb24KdmFyaWFibGVzIHZoZGwtdXBwZXItY2FzZS17a2V5d29yZHMsdHlw ZXMsYXR0cmlidXRlcyxlbnVtLXZhbHVlc30uHwooZGVmYWxpYXMgJ3ZoZGwtZml4LWNhc2UtcmVn aW9uICNbKGJlZyBlbmQgJm9wdGlvbmFsIGFyZykgIlwzMDYICVxuC1wzMDclXDIxMFwzMDYICVxm DVwzMTAlXDIxMFwzMDYICQ5cZlwzMTEODVBcMzEyJVwyMTBcMzA2CAkODg4PXDMxMyVcMjA3IiBb YmVnIGVuZCB2aGRsLXVwcGVyLWNhc2Uta2V5d29yZHMgdmhkbC1rZXl3b3Jkcy1yZWdleHAgdmhk bC11cHBlci1jYXNlLXR5cGVzIHZoZGwtdHlwZXMtcmVnZXhwIHZoZGwtZml4LWNhc2UtcmVnaW9u LTEgMCAxICInIiAyIDMgdmhkbC11cHBlci1jYXNlLWF0dHJpYnV0ZXMgdmhkbC1hdHRyaWJ1dGVz LXJlZ2V4cCB2aGRsLXVwcGVyLWNhc2UtZW51bS12YWx1ZXMgdmhkbC1lbnVtLXZhbHVlcy1yZWdl eHBdIDYgKCMkIC4gMjY1MjI2KSAiclxuUCJdKQojQDEzOCBDb252ZXJ0IGFsbCBWSERMIHdvcmRz IGluIGJ1ZmZlciB0byBsb3dlciBvciB1cHBlciBjYXNlLCBkZXBlbmRpbmcgb24KdmFyaWFibGVz IHZoZGwtdXBwZXItY2FzZS17a2V5d29yZHMsdHlwZXMsYXR0cmlidXRlcyxlbnVtLXZhbHVlc30u HwooZGVmYWxpYXMgJ3ZoZGwtZml4LWNhc2UtYnVmZmVyICNbbmlsICJcMzAwZWRcIlwyMDciIFt2 aGRsLWZpeC1jYXNlLXJlZ2lvbl0gMyAoIyQgLiAyNjU3NjkpIG5pbF0pCiNANTQgUmV0dXJuIHRo ZSBsaW5lIG51bWJlciBvZiB0aGUgbGluZSBjb250YWluaW5nIHBvaW50Lh8KKGRlZmFsaWFzICd2 aGRsLWN1cnJlbnQtbGluZSAjW25pbCAiXDIxNH5cMjEwXDIxMlwzMDB5XDIxMFwzMDFcMzAyYFwi VCpcMjA3IiBbMCBjb3VudC1saW5lcyAxXSAzICgjJCAuIDI2NjAxMCldKQojQDIxIERlbGV0ZSBl bnRpcmUgbGluZS4fCihkZWZhbGlhcyAndmhkbC1saW5lLWtpbGwtZW50aXJlICNbKCZvcHRpb25h bCBhcmcpICJcMzAxeVwyMTBcMzAyCFwyMDYJAFwzMDMhXDIwNyIgW2FyZyAwIGtpbGwtbGluZSAx XSAyICgjJCAuIDI2NjE4MikgInAiXSkKI0AyMCBLaWxsIGN1cnJlbnQgbGluZS4fCihkZWZhbGlh cyAndmhkbC1saW5lLWtpbGwgI1soJm9wdGlvbmFsIGFyZykgIlwzMDEIIVwyMDciIFthcmcgdmhk bC1saW5lLWtpbGwtZW50aXJlXSAyICgjJCAuIDI2NjMzMykgInAiXSkKI0AyMCBDb3B5IGN1cnJl bnQgbGluZS4fCihkZWZhbGlhcyAndmhkbC1saW5lLWNvcHkgI1soJm9wdGlvbmFsIGFyZykgIlwy MTJcMzAyeVwyMTBgGAlcMjA2CwBcMzAzeVwyMTBcMzA0CGBcIipcMjA3IiBbcG9zaXRpb24gYXJn IDAgMSBjb3B5LXJlZ2lvbi1hcy1raWxsXSAzICgjJCAuIDI2NjQ2NSkgInAiXSkKI0AxOSBZYW5r IGVudGlyZSBsaW5lLh8KKGRlZmFsaWFzICd2aGRsLWxpbmUteWFuayAjW25pbCAiXDMwMHlcMjEw XDMwMSBcMjA3IiBbMCB5YW5rXSAxICgjJCAuIDI2NjY0MikgbmlsXSkKI0AyOSBIaXBwaWUtZXhw YW5kIGN1cnJlbnQgbGluZS4fCihkZWZhbGlhcyAndmhkbC1saW5lLWV4cGFuZCAjWygmb3B0aW9u YWwgcHJlZml4LWFyZykgIlwzMDRcMzA1XDMwNhgZGlwzMDcLIStcMjA3IiBbaGlwcGllLWV4cGFu ZC10cnktZnVuY3Rpb25zLWxpc3QgY2FzZS1yZXBsYWNlIGNhc2UtZm9sZC1zZWFyY2ggcHJlZml4 LWFyZyB0IG5pbCAodHJ5LWV4cGFuZC1saW5lIHRyeS1leHBhbmQtbGluZS1hbGwtYnVmZmVycykg aGlwcGllLWV4cGFuZF0gMyAoIyQgLiAyNjY3NTApICJQIl0pCiNAMzkgSW50ZXJjaGFuZ2UgdGhp cyBsaW5lIHdpdGggbmV4dCBsaW5lLh8KKGRlZmFsaWFzICd2aGRsLWxpbmUtdHJhbnNwb3NlLW5l eHQgI1soJm9wdGlvbmFsIGFyZykgIlwzMDF5XDIxMFwzMDIIXDIwNgkAXDMwMSFcMjEwXDMwM3lc MjA3IiBbYXJnIDEgdHJhbnNwb3NlLWxpbmVzIC0xXSAyICgjJCAuIDI2NzAzMCkgInAiXSkKI0A0 MyBJbnRlcmNoYW5nZSB0aGlzIGxpbmUgd2l0aCBwcmV2aW91cyBsaW5lLh8KKGRlZmFsaWFzICd2 aGRsLWxpbmUtdHJhbnNwb3NlLXByZXZpb3VzICNbKCZvcHRpb25hbCBhcmcpICJcMzAxeVwyMTBc MzAyCFwyMDYJAFwzMDNbIVwyMTBcMzA0eVwyMDciIFthcmcgMSB0cmFuc3Bvc2UtbGluZXMgMCAt MV0gMiAoIyQgLiAyNjcyMTgpICJwIl0pCiNAMjkgT3BlbiBhIG5ldyBsaW5lIGFuZCBpbmRlbnQu HwooZGVmYWxpYXMgJ3ZoZGwtbGluZS1vcGVuICNbbmlsICJcMzAwf1wyMTBcMzAxIFwyMDciIFsw IG5ld2xpbmUtYW5kLWluZGVudF0gMSAoIyQgLiAyNjc0MTcpIG5pbF0pCiNAMjUgU3dpdGNoIHRv IHByb2plY3QgTkFNRS4fCihkZWZhbGlhcyAndmhkbC1wcm9qZWN0LXN3aXRjaCAjWyhuYW1lKSAi CBFcMzAzXDMwMiFcMjA1EABcMzA0XG4hXDIwNRAAXDMwNSBcMjA3IiBbbmFtZSB2aGRsLXByb2pl Y3Qgc3BlZWRiYXItZnJhbWUgYm91bmRwIGZyYW1lLWxpdmUtcCBzcGVlZGJhci1yZWZyZXNoXSAy ICgjJCAuIDI2NzU0OSldKQojQDI5IEluaXRpYWxpemUgZm9yIGNvbXBpbGF0aW9uLh8KKGRlZmFs aWFzICd2aGRsLWNvbXBpbGUtaW5pdCAjW25pbCAiCFwyMDRDAAlcMzA2XDIxMRobXDIxMRxcMjAz QABcMzA3XGZAOFwyMTESQFwzMTBcMjMyXDIwNDkAXG5AXG5BQFwzMTFVXDIwMy8AXDMxMlwzMTMN XCJcMjA1MgBcMzE0XDIwMjIAXG5BQFwzMTVcbjhFC0ITXGZBXDIxMRRcMjA0DgALKxAOED9cMjA1 cAAJXDMwNhtcMjExHFwyMDNrAFwzMTZcZkA4QFwzMTBcMjMyXDIwNGQAXDMxNwtcMzE2XGZAOENc IhNcZkFcMjExFFwyMDRRAAsqXDIxMRYQXDIwNyIgW2NvbXBpbGF0aW9uLWVycm9yLXJlZ2V4cC1h bGlzdCB2aGRsLWNvbXBpbGVyLWFsaXN0IHN1Ymxpc3QgcmVnZXhwLWFsaXN0IGNvbW1hbmRzLWFs aXN0IGVtYWNzLXZlcnNpb24gbmlsIDUgIiIgMCBzdHJpbmctbWF0Y2ggIlhFbWFjcyIgOSAyIDYg YXBwZW5kIGNvbXBpbGF0aW9uLWZpbGUtcmVnZXhwLWFsaXN0XSA1ICgjJCAuIDI2Nzc1MSldKQoj QDc4IENvbXBpbGUgY3VycmVudCBidWZmZXIgdXNpbmcgdGhlIFZIREwgY29tcGlsZXIgc3BlY2lm aWVkIGluCmB2aGRsLWNvbXBpbGVyJy4fCihkZWZhbGlhcyAndmhkbC1jb21waWxlICNbbmlsICJc MzA2IFwyMTBcMzA3CAlcIlwyMTEaQUAbXDMxMFwzMTFcbjghHAtcMjA1JwBcMzEyC1wzMTMNXDIx MVwzMTRcMjMwP1wyMDVcIgBcMzEzXDMxNSBcMjYwBSErXDIwNyIgW3ZoZGwtY29tcGlsZXIgdmhk bC1jb21waWxlci1hbGlzdCBjb21tYW5kLWVsZW0gY29tbWFuZCBkZWZhdWx0LWRpcmVjdG9yeSB2 aGRsLWNvbXBpbGVyLW9wdGlvbnMgdmhkbC1jb21waWxlLWluaXQgYXNzb2MgZXhwYW5kLWZpbGUt bmFtZSA0IGNvbXBpbGUgIiAiICIiIGJ1ZmZlci1maWxlLW5hbWVdIDcgKCMkIC4gMjY4MjQ2KSBu aWxdKQojQDg2IENhbGwgbWFrZSBjb21tYW5kIGZvciBjb21waWxhdGlvbiBvZiBhbGwgdXBkYXRl ZCBzb3VyY2UgZmlsZXMgKHJlcXVpcmVzCmBNYWtlZmlsZScpLh8KKGRlZmFsaWFzICd2aGRsLW1h a2UgI1tuaWwgIlwzMDUgXDIxMFwzMDYICVwiGlwzMDdcbjgbXDMxMFwzMTFcbjghHAtcMzEyXDIz MlwyMDMeAFwzMTNcMzE0IVwyMDIhAFwzMTMLIStcMjA3IiBbdmhkbC1jb21waWxlciB2aGRsLWNv bXBpbGVyLWFsaXN0IGNvbW1hbmQtZWxlbSBjb21tYW5kIGRlZmF1bHQtZGlyZWN0b3J5IHZoZGwt Y29tcGlsZS1pbml0IGFzc29jIDIgZXhwYW5kLWZpbGUtbmFtZSA0ICIiIGNvbXBpbGUgIm1ha2Ui XSAzICgjJCAuIDI2ODY1MSkgbmlsXSkKI0AyNiBHZW5lcmF0ZSBuZXcgYE1ha2VmaWxlJy4fCihk ZWZhbGlhcyAndmhkbC1nZW5lcmF0ZS1tYWtlZmlsZSAjW25pbCAiXDMwNSBcMjEwXDMwNggJXCIa XDMwN1xuOBtcMzEwXDMxMVxuOCEcC1wzMTJcMjMyXDIwNB4AXDMxMwshXDIwMlwiAFwzMTRcMzE1 CFwiK1wyMDciIFt2aGRsLWNvbXBpbGVyIHZoZGwtY29tcGlsZXItYWxpc3QgY29tbWFuZC1lbGVt IGNvbW1hbmQgZGVmYXVsdC1kaXJlY3RvcnkgdmhkbC1jb21waWxlLWluaXQgYXNzb2MgMyBleHBh bmQtZmlsZS1uYW1lIDQgIiIgY29tcGlsZSBlcnJvciAiTm8gc3VjaCBjb21tYW5kIHNwZWNpZmll ZCBmb3IgYCVzJyJdIDMgKCMkIC4gMjY5MDEyKSBuaWxdKQojQDU3IEZpbmQgYmVnaW4gYW5kIGVu ZCBvZiBWSERMIGRlc2lnbiB1bml0cyAoZm9yIGhpZGVzaG93KS4fCihkZWZhbGlhcyAndmhkbC1m b3J3YXJkLXVuaXQgI1soJm9wdGlvbmFsIGNvdW50KSAiXDMwMhgJXDMwM1dcMjAzEABcMzA0XDMw NVwzMDZcMzAyI1wyMDIVAFwzMDdcMzEwXDMwNlwzMDIjKVwyMDciIFtjYXNlLWZvbGQtc2VhcmNo IGNvdW50IHQgMCByZS1zZWFyY2gtYmFja3dhcmQgIl5cXChhcmNoaXRlY3R1cmVcXHxjb25maWd1 cmF0aW9uXFx8ZW50aXR5XFx8cGFja2FnZVxcKVxcPiIgbmlsIHJlLXNlYXJjaC1mb3J3YXJkICJe ZW5kXFw+Il0gNCAoIyQgLiAyNjkzNjUpICJwIl0pCihieXRlLWNvZGUgIlwzMDJcMzAzCFwiXDIw MwsAXDMwNFwzMDUhXDIxMFwzMDYJXDIzNlwyMDQVAFwzMDcJQhFcMzAyXDIwNyIgW2VtYWNzLXZl cnNpb24gaHMtc3BlY2lhbC1tb2Rlcy1hbGlzdCBzdHJpbmctbWF0Y2ggIlhFbWFjcyIgcmVxdWly ZSBoaWRlc2hvdyB2aGRsLW1vZGUgKHZoZGwtbW9kZSAiXFwoXlxcKVxcKGFyY2hpdGVjdHVyZVxc fEFSQ0hJVEVDVFVSRVxcfGNvbmZpZ3VyYXRpb25cXHxDT05GSUdVUkFUSU9OXFx8ZW50aXR5XFx8 RU5USVRZXFx8cGFja2FnZVxcfFBBQ0tBR0VcXClcXD4iICJcXCheXFwpXFwoZW5kXFx8RU5EXFwp XFw+IiAiLS1cXCggXFx8JFxcKSIgdmhkbC1mb3J3YXJkLXVuaXQpXSAzKQojQDI0IEluaXRpYWxp emUgYGhpZGVzaG93Jy4fCihkZWZhbGlhcyAndmhkbC1oaWRlc2hvdy1pbml0ICNbbmlsICIIXDIw M1xmAFwzMDJcMzAzXDMwNFwiXDIxMFwyMDIRAFwzMDVcMzAzXDMwNFwiXDIxMAlcMjAzGQBcMzA2 XDMwNyFcMjA3XDMxMFwzMDYhXDIwNVwiAFwzMDZcMzExIVwyMDciIFt2aGRsLWhpZGUtYWxsLWlu aXQgdmhkbC1oaWRlc2hvdy1tZW51IGFkZC1ob29rIGhzLW1pbm9yLW1vZGUtaG9vayBocy1oaWRl LWFsbCByZW1vdmUtaG9vayBocy1taW5vci1tb2RlIDEgYm91bmRwIDBdIDMgKCMkIC4gMjcwMDU4 KV0pCiNANTYgUmV0dXJuIHBvaW50IGlmIHdpdGhpbiB0cmFuc2xhdGUtb2ZmIHJlZ2lvbiwgZWxz ZSBuaWwuHwooZGVmYWxpYXMgJ3ZoZGwtd2l0aGluLXRyYW5zbGF0ZS1vZmYgI1tuaWwgIlwyMTJc MzAwXDMwMVwzMDJcMzAzIylcMjA1EwBcMzA0XDMwNSFcMzA2XDIzMlwyMDUTAGBcMjA3IiBbcmUt c2VhcmNoLWJhY2t3YXJkICJeXFxzLSotLVxccy0qcHJhZ21hXFxzLSp0cmFuc2xhdGVfXFwob25c XHxvZmZcXClcXHMtKlxuIiBuaWwgdCBtYXRjaC1zdHJpbmcgMSAib2ZmIl0gNCAoIyQgLiAyNzAz NjApXSkKI0A2OSBSZXR1cm4gcG9pbnQgYmVmb3JlIHRyYW5zbGF0ZS1vZmYgcHJhZ21hIGlmIGJl Zm9yZSBMSU1JVCwgZWxzZSBuaWwuHwooZGVmYWxpYXMgJ3ZoZGwtc3RhcnQtdHJhbnNsYXRlLW9m ZiAjWyhsaW1pdCkgIlwzMDFcMzAyCFwzMDMjXDIwNVxuAFwzMDRcMjI0XDIwNyIgW2xpbWl0IHJl LXNlYXJjaC1mb3J3YXJkICJeXFxzLSotLVxccy0qcHJhZ21hXFxzLSp0cmFuc2xhdGVfb2ZmXFxz LSpcbiIgdCAwXSA0ICgjJCAuIDI3MDY0NyldKQojQDY3IFJldHVybiBwb2ludCBhZnRlciB0cmFu c2xhdGUtb24gcHJhZ21hIGlmIGJlZm9yZSBMSU1JVCwgZWxzZSBuaWwuHwooZGVmYWxpYXMgJ3Zo ZGwtZW5kLXRyYW5zbGF0ZS1vZmYgI1sobGltaXQpICJcMzAxXDMwMghcMzAzI1wyMDciIFtsaW1p dCByZS1zZWFyY2gtZm9yd2FyZCAiXlxccy0qLS1cXHMtKnByYWdtYVxccy0qdHJhbnNsYXRlX29u XFxzLSpcbiIgdF0gNCAoIyQgLiAyNzA4OTgpXSkKI0A3NiBNYXRjaCBhIHRyYW5zbGF0ZS1vZmYg YmxvY2ssIHNldHRpbmcgbWF0Y2gtZGF0YSBhbmQgcmV0dXJuaW5nIHQsIGVsc2UgbmlsLh8KKGRl ZmFsaWFzICd2aGRsLW1hdGNoLXRyYW5zbGF0ZS1vZmYgI1sobGltaXQpICJgCFdcMjA1JwBcMzA0 IFwyMDYOAFwzMDUIIVwzMDYZXDIxMRpcMjA1JgBcMzA3CCFcMjA2HAAIG1wzMTBcbgtEIVwyMTAL YikqXDIwNyIgW2xpbWl0IGNhc2UtZm9sZC1zZWFyY2ggc3RhcnQgZW5kIHZoZGwtd2l0aGluLXRy YW5zbGF0ZS1vZmYgdmhkbC1zdGFydC10cmFuc2xhdGUtb2ZmIHQgdmhkbC1lbmQtdHJhbnNsYXRl LW9mZiBzZXQtbWF0Y2gtZGF0YV0gNCAoIyQgLiAyNzExMjcpXSkKI0AxMzEgTWF0Y2gsIGFuZCBt b3ZlIG92ZXIsIGFueSBkZWNsYXJhdGlvbiBpdGVtIGFmdGVyIHBvaW50LiBBZGFwdGVkIGZyb20K YGZvbnQtbG9jay1tYXRjaC1jLXN0eWxlLWRlY2xhcmF0aW9uLWl0ZW0tYW5kLXNraXAtdG8tbmV4 dCcuHwooZGVmYWxpYXMgJ3ZoZGwtZm9udC1sb2NrLW1hdGNoLWl0ZW0gI1sobGltaXQpICJcMzAw XDMwMVwzMDJcMjE3XDIwNyIgW25pbCAoYnl0ZS1jb2RlICJcMjE0ZQh9XDIxMFwzMDJcMzAzIVwy MDUlAFwzMDQgGVwzMDVcMjE2XDMwNlwyMjViXDIxMFwzMDJcMzA3IVwyMDMgAFwzMDZcMjI1Ylwy MDIkAFwzMTB/XDIxMFwzMTEqKVwyMDciIFtsaW1pdCBzYXZlLW1hdGNoLWRhdGEtaW50ZXJuYWwg bG9va2luZy1hdCAiXFxzLSpcXChcXHcrXFwpIiBtYXRjaC1kYXRhICgoc2V0LW1hdGNoLWRhdGEg c2F2ZS1tYXRjaC1kYXRhLWludGVybmFsKSkgMSAiXFwoXFxzLSosXFwpIiBuaWwgdF0gMikgKChl cnJvciB0KSldIDMgKCMkIC4gMjcxNDc5KV0pCiNANjggTWFyayBzaW5nbGUgcXVvdGVzIGFzIGhh dmluZyBzdHJpbmcgcXVvdGUgc3ludGF4IGluICdjJyBpbnN0YW5jZXMuHwooZGVmY29uc3Qgdmhk bC1mb250LWxvY2stc3ludGFjdGljLWtleXdvcmRzICcoKCJcXCgnXFwpLlxcKCdcXCkiICgxICg3 IC4gMzkpKSAoMiAoNyAuIDM5KSkpKSAoIyQgLiAyNzE5ODApKQojQDQ4IFJlZ3VsYXIgZXhwcmVz c2lvbnMgdG8gaGlnaGxpZ2h0IGluIFZIREwgTW9kZS4fCihkZWZ2YXIgdmhkbC1mb250LWxvY2st a2V5d29yZHMgbmlsICgjJCAuIDI3MjE2MSkpCiNAMTI5IEZvciBjb25zaWRlcmF0aW9uIGFzIGEg dmFsdWUgb2YgYHZoZGwtZm9udC1sb2NrLWtleXdvcmRzJy4KVGhpcyBkb2VzIGhpZ2hsaWdodGlu ZyBvZiB0ZW1wbGF0ZSBwcm9tcHRzIGFuZCBkaXJlY3RpdmVzIChwcmFnbWFzKS4fCihkZWZjb25z dCB2aGRsLWZvbnQtbG9jay1rZXl3b3Jkcy0wIChieXRlLWNvZGUgIlwzMDEIXDMwMlFcMzAzXDMw NFwzMDVGXDMwNkRcMjA3IiBbdmhkbC10ZW1wbGF0ZS1wcm9tcHQtc3ludGF4ICJcXCg8IiAiPlxc KSIgMSB2aGRsLWZvbnQtbG9jay1wcm9tcHQtZmFjZSB0ICgiLS1cXHMtKnByYWdtYVxccy0rXFwo LipcXCkkIiAxIHZoZGwtZm9udC1sb2NrLWRpcmVjdGl2ZS1mYWNlIHQpXSA0KSAoIyQgLiAyNzIy NjYpKQojQDEyMSBGb3IgY29uc2lkZXJhdGlvbiBhcyBhIHZhbHVlIG9mIGB2aGRsLWZvbnQtbG9j ay1rZXl3b3JkcycuClRoaXMgZG9lcyBoaWdobGlnaHRpbmcgb2Yga2V5d29yZHMgYW5kIHN0YW5k YXJkIGlkZW50aWZpZXJzLh8KKGRlZnZhciB2aGRsLWZvbnQtbG9jay1rZXl3b3Jkcy0xIG5pbCAo IyQgLiAyNzI2NDIpKQojQDEyMiBGb3IgY29uc2lkZXJhdGlvbiBhcyBhIHZhbHVlIG9mIGB2aGRs LWZvbnQtbG9jay1rZXl3b3JkcycuClRoaXMgZG9lcyBjb250ZXh0IHNlbnNpdGl2ZSBoaWdobGln aHRpbmcgb2YgbmFtZXMgYW5kIGxhYmVscy4fCihkZWZjb25zdCB2aGRsLWZvbnQtbG9jay1rZXl3 b3Jkcy0yIChieXRlLWNvZGUgIlwzMDNcMzA0XDMwNUVcMzA2XDMwN1wzMDVFXDMxMFwzMTFcMzEy XDMxMxhcMzEzCUA9XDIwNhwACAlcMjExGkFAKT4pXDIwNSEAXDMxNFwzMTVcMzE2XDI2MAZcMzE3 XDMwNUVcMzIwXDMyMVwzMjJFXDMyM1wzMjRcMzI1XDMyNlwzMTMYXDMxMwlAPVwyMDZBAAgJXDIx MRpBQCk+KVwyMDVGAFwzMTRcMzI3XDMzMFwyNjAHXDMwNFwzMDVFXDMzMVwzMzJcMzA1RVwzMzNc MzE3XDMwNUVcMzM0XDMzNVwzMzZFXDMzN1wzMTdcMzQwRVwzNDFcMzMyXDM0MkVcMzQzXDM0NERc MzQ1XDM0NkRcMjU3XGZcMjA3IiBbc3RhbmRhcmQgdmhkbC1zdGFuZGFyZCB4ICJeXFxzLSpcXChh cmNoaXRlY3R1cmVcXHxjb25maWd1cmF0aW9uXFx8ZW50aXR5XFx8cGFja2FnZVxcKFxccy0rYm9k eVxcfFxcKVxcfFxcKFxcKGltcHVyZVxcfHB1cmVcXClcXHMtK1xcfFxcKWZ1bmN0aW9uXFx8cHJv Y2VkdXJlXFx8Y29tcG9uZW50XFwpXFxzLStcXChcXHcrXFwpIiA1IGZvbnQtbG9jay1mdW5jdGlv bi1uYW1lLWZhY2UgIl5cXHMtKlxcKGFyY2hpdGVjdHVyZVxcfGNvbmZpZ3VyYXRpb25cXClcXHMt K1xcdytcXHMtK29mXFxzLStcXChcXHcrXFwpIiAyICJeXFxzLSpcXChcXHcrXFwpXFxzLSo6XFwo XFxzLVxcfFxuXFwpKlxcKFxcKCIgImFzc2VydFxcfGJsb2NrXFx8Y2FzZVxcfGNvbXBvbmVudFxc fGNvbmZpZ3VyYXRpb25cXHxlbnRpdHlcXHxleGl0XFx8IiAiZm9yXFx8aWZcXHxsb29wXFx8bmV4 dFxcfG51bGxcXHxwb3N0cG9uZWRcXHxwcm9jZXNzXFx8IiBhbXMgInByb2NlZHVyYWxcXHwiICJ3 aXRoXFx8d2hpbGUiICJcXClcXD5cXHxbXlxuXSo8PVxcKSIgMSAiXlxccy0qXFwoXFx3K1xcKVxc cy0qOlsgCVxuXSpcXChjb21wb25lbnRcXHMtK1xcfFxcKVxcKFxcdytcXClcXChcXHMtXFx8XG5c XCkrXFwoZ2VuZXJpY1xcfHBvcnRcXClcXHMtK21hcFxcPiIgKDEgZm9udC1sb2NrLWZ1bmN0aW9u LW5hbWUtZmFjZSkgKDMgZm9udC1sb2NrLWZ1bmN0aW9uLW5hbWUtZmFjZSkgIl5cXHMtKmVuZFxc cy0rXFwoXFwoIiAiYXJjaGl0ZWN0dXJlXFx8YmxvY2tcXHxjYXNlXFx8Y29tcG9uZW50XFx8Y29u ZmlndXJhdGlvblxcfGVudGl0eVxcfCIgImZvclxcfGZ1bmN0aW9uXFx8Z2VuZXJhdGVcXHxpZlxc fGxvb3BcXHxwYWNrYWdlXFwoXFxzLStib2R5XFx8XFwpXFx8IiAicHJvY2VkdXJlXFx8XFwocG9z dHBvbmVkXFxzLStcXHxcXClwcm9jZXNzXFx8IiAidW5pdHMiICJcXClcXD5cXHxcXClcXHMtKlxc KFxcdypcXCkiICJeXFxzLSpcXChcXHcrXFxzLSo6XFxzLSpcXCk/XFwoZXhpdFxcfG5leHRcXClc XHMtK1xcKFxcdypcXCkiIDMgIl5cXHMtKmF0dHJpYnV0ZVxccy0rXFx3K1xccy0rb2ZcXHMtK1xc KFxcdytcXCgsXFxzLSpcXHcrXFwpKlxcKVxccy0qOiIgIl5cXHMtKmZvclxccy0rXFwoXFx3K1xc KCxcXHMtKlxcdytcXCkqXFwpXFxzLSo6XFwoXFxzLVxcfFxuXFwpKlxcKFxcdytcXCkiICgxIGZv bnQtbG9jay1mdW5jdGlvbi1uYW1lLWZhY2UpICg0IGZvbnQtbG9jay1mdW5jdGlvbi1uYW1lLWZh Y2UpICJeXFxzLSphdHRyaWJ1dGVcXHMtK1xcKFxcdytcXCkiIHZoZGwtZm9udC1sb2NrLWF0dHJp YnV0ZS1mYWNlICJeXFxzLSpcXChzdWJcXHxcXClcXChuYXR1cmVcXHx0eXBlXFwpXFxzLStcXChc XHcrXFwpIiBmb250LWxvY2stdHlwZS1mYWNlICJcXCg6W149XVxcKSIgKHZoZGwtZm9udC1sb2Nr LW1hdGNoLWl0ZW0gKHByb2duIChnb3RvLWNoYXIgKG1hdGNoLWJlZ2lubmluZyAxKSkgKHNraXAt c3ludGF4LWJhY2t3YXJkICIgIikgKHNraXAtc3ludGF4LWJhY2t3YXJkICJ3XyIpIChza2lwLXN5 bnRheC1iYWNrd2FyZCAiICIpICh3aGlsZSAoPSAocHJlY2VkaW5nLWNoYXIpIDQ0KSAoYmFja3dh cmQtY2hhciAxKSAoc2tpcC1zeW50YXgtYmFja3dhcmQgIiAiKSAoc2tpcC1zeW50YXgtYmFja3dh cmQgIndfIikgKHNraXAtc3ludGF4LWJhY2t3YXJkICIgIikpKSAoZ290by1jaGFyIChtYXRjaC1l bmQgMSkpICgxIGZvbnQtbG9jay12YXJpYWJsZS1uYW1lLWZhY2UpKSAiXFw8XFwoYWxpYXNcXHxm b3JcXHxncm91cFxcKVxccy0rXFx3K1xccy0rXFwoaW5cXHxpc1xcKVxcPiIgKHZoZGwtZm9udC1s b2NrLW1hdGNoLWl0ZW0gKHByb2duIChnb3RvLWNoYXIgKG1hdGNoLWVuZCAxKSkgKG1hdGNoLWJl Z2lubmluZyAyKSkgbmlsICgxIGZvbnQtbG9jay12YXJpYWJsZS1uYW1lLWZhY2UpKV0gMTMpICgj JCAuIDI3MjgyMikpCiNAMTEzIEZvciBjb25zaWRlcmF0aW9uIGFzIGEgdmFsdWUgb2YgYHZoZGwt Zm9udC1sb2NrLWtleXdvcmRzJy4KVGhpcyBkb2VzIGhpZ2hsaWdodGluZyBvZiB3b3JkcyB3aXRo IHNwZWNpYWwgc3ludGF4Lh8KKGRlZnZhciB2aGRsLWZvbnQtbG9jay1rZXl3b3Jkcy0zIG5pbCAo IyQgLiAyNzUyMTUpKQojQDExMyBGb3IgY29uc2lkZXJhdGlvbiBhcyBhIHZhbHVlIG9mIGB2aGRs LWZvbnQtbG9jay1rZXl3b3JkcycuClRoaXMgZG9lcyBoaWdobGlnaHRpbmcgb2YgYWRkaXRpb25h bCByZXNlcnZlZCB3b3Jkcy4fCihkZWZ2YXIgdmhkbC1mb250LWxvY2sta2V5d29yZHMtNCBuaWwg KCMkIC4gMjc1Mzg3KSkKI0AxMjAgRm9yIGNvbnNpZGVyYXRpb24gYXMgYSB2YWx1ZSBvZiBgdmhk bC1mb250LWxvY2sta2V5d29yZHMnLgpUaGlzIGRvZXMgYmFja2dyb3VuZCBoaWdobGlnaHRpbmcg b2YgdHJhbnNsYXRlLW9mZiByZWdpb25zLh8KKGRlZmNvbnN0IHZoZGwtZm9udC1sb2NrLWtleXdv cmRzLTUgJygodmhkbC1tYXRjaC10cmFuc2xhdGUtb2ZmICgwIHZoZGwtZm9udC1sb2NrLXRyYW5z bGF0ZS1vZmYtZmFjZSBhcHBlbmQpKSkgKCMkIC4gMjc1NTU5KSkKI0AzMSBGYWNlIG5hbWUgdG8g dXNlIGZvciBwcm9tcHRzLh8KKGRlZnZhciB2aGRsLWZvbnQtbG9jay1wcm9tcHQtZmFjZSAndmhk bC1mb250LWxvY2stcHJvbXB0LWZhY2UgKCMkIC4gMjc1ODEwKSkKI0A0NyBGYWNlIG5hbWUgdG8g dXNlIGZvciBzdGFuZGFyZGl6ZWQgYXR0cmlidXRlcy4fCihkZWZ2YXIgdmhkbC1mb250LWxvY2st YXR0cmlidXRlLWZhY2UgJ3ZoZGwtZm9udC1sb2NrLWF0dHJpYnV0ZS1mYWNlICgjJCAuIDI3NTky NCkpCiNANTUgRmFjZSBuYW1lIHRvIHVzZSBmb3Igc3RhbmRhcmRpemVkIGVudW1lcmF0aW9uIHZh bHVlcy4fCihkZWZ2YXIgdmhkbC1mb250LWxvY2stZW51bXZhbHVlLWZhY2UgJ3ZoZGwtZm9udC1s b2NrLWVudW12YWx1ZS1mYWNlICgjJCAuIDI3NjA2MCkpCiNANTkgRmFjZSBuYW1lIHRvIHVzZSBm b3Igc3RhbmRhcmRpemVkIGZ1bmN0aW9ucyBhbmQgcGFja2FnZXMuHwooZGVmdmFyIHZoZGwtZm9u dC1sb2NrLWZ1bmN0aW9uLWZhY2UgJ3ZoZGwtZm9udC1sb2NrLWZ1bmN0aW9uLWZhY2UgKCMkIC4g Mjc2MjA0KSkKI0AzNCBGYWNlIG5hbWUgdG8gdXNlIGZvciBkaXJlY3RpdmVzLh8KKGRlZnZhciB2 aGRsLWZvbnQtbG9jay1kaXJlY3RpdmUtZmFjZSAndmhkbC1mb250LWxvY2stZGlyZWN0aXZlLWZh Y2UgKCMkIC4gMjc2MzUwKSkKI0A0OSBGYWNlIG5hbWUgdG8gdXNlIGZvciBhZGRpdGlvbmFsIHJl c2VydmVkIHdvcmRzLh8KKGRlZnZhciB2aGRsLWZvbnQtbG9jay1yZXNlcnZlZC13b3Jkcy1mYWNl ICd2aGRsLWZvbnQtbG9jay1yZXNlcnZlZC13b3Jkcy1mYWNlICgjJCAuIDI3NjQ3MykpCiNANDUg RmFjZSBuYW1lIHRvIHVzZSBmb3IgdHJhbnNsYXRlLW9mZiByZWdpb25zLh8KKGRlZnZhciB2aGRs LWZvbnQtbG9jay10cmFuc2xhdGUtb2ZmLWZhY2UgJ3ZoZGwtZm9udC1sb2NrLXRyYW5zbGF0ZS1v ZmYtZmFjZSAoIyQgLiAyNzY2MjEpKQooYnl0ZS1jb2RlICIIXDMwNBlcMjExGlwyMDMmAFwzMDVc MzA2XG5AQFwzMDcjEVwzMTBcMzExCVwzMTIJRFwzMTNcbkBAXDMxNFFGIVwyMTBcbkFcMjExElwy MDQIACpcMzE1XDMxNlwzMDRcMzE3C1wzMjAlXDIxMFwzMjFcMzE2XDMyMlwzMjMjXDIxMFwzMjFc MzE2XDMyNFwzMjMjXDIxMFwzMjFcMzE2XDMyNVwzMjMjXDIxMFwzMjFcMzE2XDMyNlwzMjMjXDIx MFwzMjFcMzE2XDMyN1wzMjMjXDIxMFwzMjFcMzE2XDMzMFwzMjMjXDIxMFwzMzFcMzMyXDMzM1wz MzQLXDMxNgtcMzM1JgdcMjEwXDMzMVwzMzZcMzM3XDM0MAtcMzE2C1wzMzUmB1wyMTBcMzMxXDM0 MVwzNDJcMzQzC1wzMTYLXDMzNSYHXDIxMFwzMzFcMzQ0XDM0NVwzNDYLXDMxNgtcMzM1JgdcMjEw XDMzMVwzNDdcMzUwXDM1MQtcMzE2C1wzMzUmB1wyMTBcMzMxXDM1MlwzNTNcMzU0C1wzMTYLXDMz NSYHXDIxMFwzMzFcMzU1XDM1NlwzNTcLXDMxNgtcMzM1JgdcMjEwCFwyMTEaXDIwM1wzMzAAXDMx MFwzNjBcMzA1XDMwNlxuQEBcMzA3I1wzMTJcMzYxXDM2MlwzNjNcbkA4RERcMzY0XDM2MlwzNjVc bkA4RERcMzY2QkJEXDM2N1xuQEBcMzE0UVwzNzBCQkJCIVwyMTBcbkFcMjExElwyMDRcMjQ2AClc MzA0XDIwNyIgW3ZoZGwtc3BlY2lhbC1zeW50YXgtYWxpc3QgbmFtZSBzeW50YXgtYWxpc3QgOmdy b3VwIG5pbCB2aGRsLWZ1bmN0aW9uLW5hbWUgInZoZGwtZm9udC1sb2NrIiAiZmFjZSIgZXZhbCBk ZWZ2YXIgcXVvdGUgIkZhY2UgbmFtZSB0byB1c2UgZm9yICIgIi4iIGN1c3RvbS1kZWNsYXJlLWdy b3VwIHZoZGwtaGlnaGxpZ2h0LWZhY2VzICJGYWNlcyBmb3IgaGlnaGxpZ2h0aW5nLiIgdmhkbC1o aWdobGlnaHQgY3VzdG9tLWFkZC10by1ncm91cCBmb250LWxvY2stY29tbWVudC1mYWNlIGN1c3Rv bS1mYWNlIGZvbnQtbG9jay1zdHJpbmctZmFjZSBmb250LWxvY2sta2V5d29yZC1mYWNlIGZvbnQt bG9jay10eXBlLWZhY2UgZm9udC1sb2NrLWZ1bmN0aW9uLW5hbWUtZmFjZSBmb250LWxvY2stdmFy aWFibGUtbmFtZS1mYWNlIGN1c3RvbS1kZWNsYXJlLWZhY2UgdmhkbC1mb250LWxvY2stcHJvbXB0 LWZhY2UgKCgoKGNsYXNzIGNvbG9yKSAoYmFja2dyb3VuZCBsaWdodCkpICg6Zm9yZWdyb3VuZCAi UmVkIiA6Ym9sZCB0KSkgKCgoY2xhc3MgY29sb3IpIChiYWNrZ3JvdW5kIGRhcmspKSAoOmZvcmVn cm91bmQgIlBpbmsiIDpib2xkIHQpKSAodCAoOmludmVyc2UtdmlkZW8gdCkpKSAiRm9udCBsb2Nr IG1vZGUgZmFjZSB1c2VkIHRvIGhpZ2hsaWdodCBwcm9tcHRzLiIgZm9udC1sb2NrLWhpZ2hsaWdo dGluZy1mYWNlcyB2aGRsLWZvbnQtbG9jay1hdHRyaWJ1dGUtZmFjZSAoKCgoY2xhc3MgY29sb3Ip IChiYWNrZ3JvdW5kIGxpZ2h0KSkgKDpmb3JlZ3JvdW5kICJPcmNoaWQiKSkgKCgoY2xhc3MgY29s b3IpIChiYWNrZ3JvdW5kIGRhcmspKSAoOmZvcmVncm91bmQgIkxpZ2h0U3RlZWxCbHVlIikpICh0 ICg6aXRhbGljIHQgOmJvbGQgdCkpKSAiRm9udCBsb2NrIG1vZGUgZmFjZSB1c2VkIHRvIGhpZ2hs aWdodCBzdGFuZGFyZGl6ZWQgYXR0cmlidXRlcy4iIHZoZGwtZm9udC1sb2NrLWVudW12YWx1ZS1m YWNlICgoKChjbGFzcyBjb2xvcikgKGJhY2tncm91bmQgbGlnaHQpKSAoOmZvcmVncm91bmQgIkdv bGQ0IikpICgoKGNsYXNzIGNvbG9yKSAoYmFja2dyb3VuZCBkYXJrKSkgKDpmb3JlZ3JvdW5kICJC dXJseVdvb2QiKSkgKHQgKDppdGFsaWMgdCA6Ym9sZCB0KSkpICJGb250IGxvY2sgbW9kZSBmYWNl IHVzZWQgdG8gaGlnaGxpZ2h0IHN0YW5kYXJkaXplZCBlbnVtZXJhdGlvbiB2YWx1ZXMuIiB2aGRs LWZvbnQtbG9jay1mdW5jdGlvbi1mYWNlICgoKChjbGFzcyBjb2xvcikgKGJhY2tncm91bmQgbGln aHQpKSAoOmZvcmVncm91bmQgIk9yY2hpZDQiKSkgKCgoY2xhc3MgY29sb3IpIChiYWNrZ3JvdW5k IGRhcmspKSAoOmZvcmVncm91bmQgIk9yY2hpZDEiKSkgKHQgKDppdGFsaWMgdCA6Ym9sZCB0KSkp ICJGb250IGxvY2sgbW9kZSBmYWNlIHVzZWQgdG8gaGlnaGxpZ2h0IHN0YW5kYXJkaXplZCBmdW5j dGlvbnMgYW5kIHBhY2thZ2VzLiIgdmhkbC1mb250LWxvY2stZGlyZWN0aXZlLWZhY2UgKCgoKGNs YXNzIGNvbG9yKSAoYmFja2dyb3VuZCBsaWdodCkpICg6Zm9yZWdyb3VuZCAiQ2FkZXRCbHVlIikp ICgoKGNsYXNzIGNvbG9yKSAoYmFja2dyb3VuZCBkYXJrKSkgKDpmb3JlZ3JvdW5kICJBcXVhbWFy aW5lIikpICh0ICg6aXRhbGljIHQgOmJvbGQgdCkpKSAiRm9udCBsb2NrIG1vZGUgZmFjZSB1c2Vk IHRvIGhpZ2hsaWdodCBkaXJlY3RpdmVzLiIgdmhkbC1mb250LWxvY2stcmVzZXJ2ZWQtd29yZHMt ZmFjZSAoKCgoY2xhc3MgY29sb3IpIChiYWNrZ3JvdW5kIGxpZ2h0KSkgKDpmb3JlZ3JvdW5kICJP cmFuZ2UiIDpib2xkIHQpKSAoKChjbGFzcyBjb2xvcikgKGJhY2tncm91bmQgZGFyaykpICg6Zm9y ZWdyb3VuZCAiWWVsbG93IiA6Ym9sZCB0KSkgKHQgbmlsKSkgIkZvbnQgbG9jayBtb2RlIGZhY2Ug dXNlZCB0byBoaWdobGlnaHQgYWRkaXRpb25hbCByZXNlcnZlZCB3b3Jkcy4iIHZoZGwtZm9udC1s b2NrLXRyYW5zbGF0ZS1vZmYtZmFjZSAoKCgoY2xhc3MgY29sb3IpIChiYWNrZ3JvdW5kIGxpZ2h0 KSkgKDpiYWNrZ3JvdW5kICJMaWdodEdyYXkiKSkgKCgoY2xhc3MgY29sb3IpIChiYWNrZ3JvdW5k IGRhcmspKSAoOmJhY2tncm91bmQgIkRpbUdyYXkiKSkgKHQgbmlsKSkgIkZvbnQgbG9jayBtb2Rl IGZhY2UgdXNlZCB0byBiYWNrZ3JvdW5kIGhpZ2hsaWdodCB0cmFuc2xhdGUtb2ZmIHJlZ2lvbnMu IiBkZWZmYWNlICgoY2xhc3MgY29sb3IpIChiYWNrZ3JvdW5kIGxpZ2h0KSkgOmZvcmVncm91bmQg MiAoKGNsYXNzIGNvbG9yKSAoYmFja2dyb3VuZCBkYXJrKSkgMyAoKHQgbmlsKSkgIkZvbnQgbG9j ayBtb2RlIGZhY2UgdXNlZCB0byBoaWdobGlnaHQgIiAoOmdyb3VwICd2aGRsLWhpZ2hsaWdodC1m YWNlcyA6Z3JvdXAgJ2ZvbnQtbG9jay1oaWdobGlnaHRpbmctZmFjZXMpXSAxMCkKI0AyNyBJbml0 aWFsaXplIGZvbnRpZmljYXRpb24uHwooZGVmYWxpYXMgJ3ZoZGwtZm9udC1sb2NrLWluaXQgI1tu aWwgIlwzMDYIUFwzMDdcMzEwRQlcMzA3XDMxMUVcblwzMDdcMzEyRQtcMzA3XDMxMkVcZlwzMDdc MzEzRQ1cMzA3XDMxNEVcMjU3BhYVDhZcMzE1HhdcMjExHhhcMjAzSABcMzE2DhhAQUBcMzE3UVwz MjBcMzIxDhhAQFwzMjIjQg4XQhYXDhhBXDIxMRYYXDIwNCkADhcqFhkOGlwzMDdcMzIzRUMWG1wz MjQOHA4dXDIwNV8ADhUOHlwyMDRpAA4fXDIwNWsADhsOIFwyMDVyAA4ZDiFcMjA1eQAOXCIOI1wy MDVcMjAwAA4kJgZcMjExFiVcMjA3IiBbdmhkbC1hdHRyaWJ1dGVzLXJlZ2V4cCB2aGRsLXR5cGVz LXJlZ2V4cCB2aGRsLWZ1bmN0aW9ucy1yZWdleHAgdmhkbC1wYWNrYWdlcy1yZWdleHAgdmhkbC1l bnVtLXZhbHVlcy1yZWdleHAgdmhkbC1rZXl3b3Jkcy1yZWdleHAgIiciIDEgdmhkbC1mb250LWxv Y2stYXR0cmlidXRlLWZhY2UgZm9udC1sb2NrLXR5cGUtZmFjZSB2aGRsLWZvbnQtbG9jay1mdW5j dGlvbi1mYWNlIHZoZGwtZm9udC1sb2NrLWVudW12YWx1ZS1mYWNlIGZvbnQtbG9jay1rZXl3b3Jk LWZhY2UgbmlsICJcXDxcXCgiICJcXClcXD4iIHZoZGwtZnVuY3Rpb24tbmFtZSAidmhkbC1mb250 LWxvY2siICJmYWNlIiB2aGRsLWZvbnQtbG9jay1yZXNlcnZlZC13b3Jkcy1mYWNlIGFwcGVuZCB2 aGRsLWZvbnQtbG9jay1rZXl3b3Jkcy0xIHZoZGwtc3BlY2lhbC1zeW50YXgtYWxpc3Qga2V5d29y ZHMgc3ludGF4LWFsaXN0IHZoZGwtZm9udC1sb2NrLWtleXdvcmRzLTMgdmhkbC1yZXNlcnZlZC13 b3Jkcy1yZWdleHAgdmhkbC1mb250LWxvY2sta2V5d29yZHMtNCB2aGRsLWZvbnQtbG9jay1rZXl3 b3Jkcy0wIHZoZGwtaGlnaGxpZ2h0LWtleXdvcmRzIHZoZGwtaGlnaGxpZ2h0LWZvcmJpZGRlbi13 b3JkcyB2aGRsLWhpZ2hsaWdodC12ZXJpbG9nLWtleXdvcmRzIHZoZGwtaGlnaGxpZ2h0LXNwZWNp YWwtd29yZHMgdmhkbC1oaWdobGlnaHQtbmFtZXMgdmhkbC1mb250LWxvY2sta2V5d29yZHMtMiB2 aGRsLWhpZ2hsaWdodC10cmFuc2xhdGUtb2ZmIHZoZGwtZm9udC1sb2NrLWtleXdvcmRzLTUgdmhk bC1mb250LWxvY2sta2V5d29yZHNdIDkgKCMkIC4gMjc5NzUyKV0pCih2aGRsLWZvbnQtbG9jay1p bml0KQojQDQ5IFJlLWluaXRpYWxpemUgZm9udGlmaWNhdGlvbiBhbmQgZm9udGlmeSBidWZmZXIu HwooZGVmYWxpYXMgJ3ZoZGwtZm9udGlmeS1idWZmZXIgI1tuaWwgIlwzMDJcMzAzCD9cMzA0XDMw NVwzMDZcMjU3BhFcMzA3XDMxMCFcMjAzEwBcMzEwIFwyMTBcMzExIFwyMTBcMzEyIFwyMDciIFt2 aGRsLWhpZ2hsaWdodC1jYXNlLXNlbnNpdGl2ZSBmb250LWxvY2stZGVmYXVsdHMgdmhkbC1mb250 LWxvY2sta2V5d29yZHMgbmlsICgoOTUgLiAidyIpKSBiZWdpbm5pbmctb2YtbGluZSAoZm9udC1s b2NrLXN5bnRhY3RpYy1rZXl3b3JkcyAuIHZoZGwtZm9udC1sb2NrLXN5bnRhY3RpYy1rZXl3b3Jk cykgZmJvdW5kcCBmb250LWxvY2stdW5zZXQtZGVmYXVsdHMgZm9udC1sb2NrLXNldC1kZWZhdWx0 cyBmb250LWxvY2stZm9udGlmeS1idWZmZXJdIDYgKCMkIC4gMjgwOTA2KSBuaWxdKQojQDY3IElu aXRpYWxpemUgY3VzdG9tIGZhY2UgYW5kIHBhZ2Ugc2V0dGluZ3MgZm9yIHBvc3RzY3JpcHQgcHJp bnRpbmcuHwooZGVmYWxpYXMgJ3ZoZGwtcHMtcHJpbnQtc2V0dGluZ3MgI1tuaWwgIghcMjAzHAAJ XDIwNBwAXDMwNVwzMDYhXDMwN0xcMjEwXDMwNVwzMTAhXDMxMUxcMjEwXDMwNVwzMTIhXDMxM0xc MjEwXDMxNBILXDIwNVsAXDMwNVwzMTUhXDMxNExcMjEwXDMwNVwzMTYhXDMxN0xcMjEwXDMwNVwz MjAhXDMyMUxcMjEwXDMwNVwzMjIhXDMyM0xcMjEwXDMwNVwzMjQhXDMyNUxcMjEwXDMwNVwzMjYh XDMyN0xcMjEwXGZcMzMwPVwyMDVbAFwzMDVcMzMxIVwzMzJMXDIxMFwzMDVcMzMzIVwzMzRMXDIx MFwzMDVcMzM1IVwzMzZMXDIwNyIgW3ZoZGwtcHJpbnQtY3VzdG9taXplLWZhY2VzIHBzLXByaW50 LWNvbG9yLXAgcHMtYWx3YXlzLWJ1aWxkLWZhY2UtcmVmZXJlbmNlIHZoZGwtcHJpbnQtdHdvLWNv bHVtbiBwcy1wYXBlci10eXBlIG1ha2UtbG9jYWwtdmFyaWFibGUgcHMtYm9sZC1mYWNlcyAoZm9u dC1sb2NrLWtleXdvcmQtZmFjZSBmb250LWxvY2stdHlwZS1mYWNlIHZoZGwtZm9udC1sb2NrLWF0 dHJpYnV0ZS1mYWNlIHZoZGwtZm9udC1sb2NrLWVudW12YWx1ZS1mYWNlIHZoZGwtZm9udC1sb2Nr LWRpcmVjdGl2ZS1mYWNlKSBwcy1pdGFsaWMtZmFjZXMgKGZvbnQtbG9jay1jb21tZW50LWZhY2Ug Zm9udC1sb2NrLWZ1bmN0aW9uLW5hbWUtZmFjZSBmb250LWxvY2stdHlwZS1mYWNlIHZoZGwtZm9u dC1sb2NrLWF0dHJpYnV0ZS1mYWNlIHZoZGwtZm9udC1sb2NrLWVudW12YWx1ZS1mYWNlIHZoZGwt Zm9udC1sb2NrLWRpcmVjdGl2ZS1mYWNlKSBwcy11bmRlcmxpbmVkLWZhY2VzIChmb250LWxvY2st c3RyaW5nLWZhY2UpIHQgcHMtbGFuZHNjYXBlLW1vZGUgcHMtbnVtYmVyLW9mLWNvbHVtbnMgMiBw cy1mb250LXNpemUgNy4wIHBzLWhlYWRlci10aXRsZS1mb250LXNpemUgMTAuMCBwcy1oZWFkZXIt Zm9udC1zaXplIDkuMCBwcy1oZWFkZXItb2Zmc2V0IDEyLjAgbGV0dGVyIHBzLWludGVyLWNvbHVt biA0MC4wIHBzLWxlZnQtbWFyZ2luIDQwLjAgcHMtcmlnaHQtbWFyZ2luIDQwLjBdIDIgKCMkIC4g MjgxMzUwKV0pCiNAMzMgSW5pdGlhbGl6ZSBwb3N0c2NyaXB0IHByaW50aW5nLh8KKGRlZmFsaWFz ICd2aGRsLXBzLXByaW50LWluaXQgI1tuaWwgIlwzMDFcMzAyCFwiXDIwM1xuAFwzMDMgXDIwN1wz MDRcMzA1IVwyMTBcMzA2XDMwNVwzMDNcIlwyMDciIFtlbWFjcy12ZXJzaW9uIHN0cmluZy1tYXRj aCAiWEVtYWNzIiB2aGRsLXBzLXByaW50LXNldHRpbmdzIG1ha2UtbG9jYWwtdmFyaWFibGUgcHMt cHJpbnQtaG9vayBhZGQtaG9va10gMyAoIyQgLiAyODI0NTApXSkKI0AxMDAgQ2FjaGUgd2l0aCBl bnRpdGllcyBhbmQgY29ycmVzcG9uZGluZyBhcmNoaXRlY3R1cmVzIGFuZCBjb25maWd1cmF0aW9u cyBmb3IKZWFjaCB2aXNpdGVkIGRpcmVjdG9yeS4fCihkZWZ2YXIgdmhkbC1lbnRpdHktYWxpc3Qg bmlsICgjJCAuIDI4MjcwOCkpCiNANDkgQ2FjaGUgd2l0aCBwYWNrYWdlcyBmb3IgZWFjaCB2aXNp dGVkIGRpcmVjdG9yeS4fCihkZWZ2YXIgdmhkbC1wYWNrYWdlLWFsaXN0IG5pbCAoIyQgLiAyODI4 NTgpKQojQDYyIENhY2hlIHdpdGggaW5zdGFudGlhdGVkIGVudGl0aWVzIGZvciBlYWNoIHZpc2l0 ZWQgZGlyZWN0b3J5Lh8KKGRlZnZhciB2aGRsLWVudC1pbnN0LWFsaXN0IG5pbCAoIyQgLiAyODI5 NTgpKQojQDk4IENhY2hlIHdpdGggZW50aXRpZXMgYW5kIGNvcnJlc3BvbmRpbmcgYXJjaGl0ZWN0 dXJlcyBhbmQgY29uZmlndXJhdGlvbnMgZm9yCmVhY2ggdmlzaXRlZCBwcm9qZWN0Lh8KKGRlZnZh ciB2aGRsLXByb2plY3QtZW50aXR5LWFsaXN0IG5pbCAoIyQgLiAyODMwNzIpKQojQDQ5IENhY2hl IHdpdGggcGFja2FnZXMgZm9yIGVhY2ggdmlzaXRlZCBkaXJlY3RvcnkuHwooZGVmdmFyIHZoZGwt cHJvamVjdC1wYWNrYWdlLWFsaXN0IG5pbCAoIyQgLiAyODMyMjgpKQojQDYyIENhY2hlIHdpdGgg aW5zdGFudGlhdGVkIGVudGl0aWVzIGZvciBlYWNoIHZpc2l0ZWQgZGlyZWN0b3J5Lh8KKGRlZnZh ciB2aGRsLXByb2plY3QtZW50LWluc3QtbGlzdCBuaWwgKCMkIC4gMjgzMzM2KSkKI0A5OSBBbGlz dCBvZiBkZXNpZ24gdW5pdHMgc2ltdWx0YW5lb3VzbHkgb3BlbiBpbiB0aGUgY3VycmVudCBzcGVl ZGJhciBmb3IgZWFjaApkaXJlY3RvcnkgYW5kIHByb2plY3QuHwooZGVmdmFyIHZoZGwtc3BlZWRi YXItc2hvd24tdW5pdHMtYWxpc3QgbmlsICgjJCAuIDI4MzQ1NykpCiNANTIgTGFzdCBmaWxlIGZv ciB3aGljaCBkZXNpZ24gdW5pdHMgd2VyZSBoaWdobGlnaHRlZC4fCihkZWZ2YXIgdmhkbC1zcGVl ZGJhci1sYXN0LWZpbGUtbmFtZSBuaWwgKCMkIC4gMjgzNjIwKSkKI0AzOSBDYWNoZSB3aXRoIGRl c2lnbiB1bml0cyBpbiBlYWNoIGZpbGUuHwooZGVmdmFyIHZoZGwtZmlsZS1hbGlzdCBuaWwgKCMk IC4gMjgzNzMzKSkKI0A4NCBSZXR1cm4gbm9uLW5pbCBpZiBhIHByb2plY3QgaXMgZGlzcGxheWVk LCBpLmUuIGRpcmVjdG9yaWVzIG9yIGZpbGVzIGFyZQpzcGVjaWZpZWQuHwooZGVmYWxpYXMgJ3Zo ZGwtc3BlZWRiYXItcHJvamVjdC1wICNbbmlsICJcMzAyCAlcIkFAXDIwNyIgW3ZoZGwtcHJvamVj dC1hbGlzdCB2aGRsLXByb2plY3QgYWdldF0gMyAoIyQgLiAyODM4MjApXSkKKHB1dCAndmhkbC1z cGVlZGJhci1wcm9qZWN0LXAgJ2J5dGUtb3B0aW1pemVyICdieXRlLWNvbXBpbGUtaW5saW5lLWV4 cGFuZCkKI0A0MyBTY2FuIGNvbnRlbnRzIG9mIFZIREwgZmlsZXMgaW4gRklMRS1MSVNULh8KKGRl ZmFsaWFzICd2aGRsLXNjYW4tZmlsZS1jb250ZW50cyAjWyhuYW1lICZvcHRpb25hbCBudW0tc3Ry aW5nKSAiXDMwNlwzMDcIXCJcMjEwXDMxMFwyMjRcMzEwXDIyNVVcMjExGVwyMDMXAFwzMTFcMzEy CFwiXDIzN1wyMDIkAFwzMTNcMzE0XDMxNQhcIlwzMTJcMzE2XDMxNFwzMTAIXCIhIxpcMzEyG3Ac XDMxNx1cMzE3HjFcMzE3HjxcMzE3Hj0JXDIwNEEAXG5cMjA0QQBcMzIwXDMyMQhcIlwyMTBcMjEy XG5cMjA1XDM1MgJcbkcWPVxuXDIwM1wyNDYCXDMyMFwzMjIJXDIwM1gAXDMyM1wyMDJZAFwzMjQO PlwyMDZfAFwzMjUIDj1cbkdaXDMyNl8OPVwyNDVcMzI3JgZcMjEwXDMzMFxuQCFcMzE3XDIxMVwy MTFcMjExXDIxMVwyMTFcMjExXDIxMR4/HkAeQR5CHkMeRB5FHkYeR1wzMzEORyFcMjAzXDIzNABc MzMxDkchcVwyMTBcMjAyXDI0NwBcMzMyDkdcMzE3XDMxMiNxXDIxMFwzMTIWRlwzMTIbXDMzM1wz MzRcMzM1XDMzNiAjXDIxMGViXDIxMFwzMzdcMzQwXDMxN1wzMTIjXDIwM1wzNTUAXDM0MQ1cMzE0 XDMxNSFcIh5IXDMxMA5IOB4nXDM0Mg5IOB4vXDMxNFwzMTUhDkNCFkNcMzQzXDMwNVwzMTRcMzE1 IQ5HXDM0NCAOJw4vXDMxN1wyNTcFI1wyMTArXDIwMlwyNjMAZWJcMjEwXDMzN1wzNDVcMzE3XDMx MiNcMjAzXDMyNwFcMzE0XDMxMCFcMjAzSwFcMzQxDVwzMTRcMzQyIVwiHkhcMzEwDkg4HidcMzQy Dkg4Hi9cMzE0XDMxMCEWRVwzMTRcMzQyIRZEDkUOQkIWQlwzNDZcMzQ3DkUOR1wzNDQgXDMxN0Uj XDIxMA5IQA5IQUAOJw4vXDMxN1wyNTcFFkhcMzQzXDMwNQ5EDkgjXDIxMCtcMjAyXDM2MABcMzQx DQ5EXCIeSFwzMTAOSDgeJ1wzNDEOJw5FXCIeSVwzMTAOSTgeLVwzMTRcMzUwIR5KXDMxNFwzNTEh HktcMzE0XDM1MiEeTFwzNDIOSDgeL1wzNTNcMzU0XDMxN1wzMTIjXDIxMA5KDj9CFj9cMzQ2XDM1 NQ5KDkdcMzQ0IA5LDkxGI1wyMTAOSUAOSUFADi1FFklcMzQ2XDM0Nw5FDkkjXDIxMA5IQA5IQUAO Jw4vXDMxN1wyNTcFFkhcMzQzXDMwNQ5EDkgjXDIxMA5LDjxcMjM1XDIwNFwzMjIBDksOPEIWPC4I XDIwMlwzNjAAZWJcMjEwXDMzN1wzNTZcMzE3XDMxMiNcMjAzJwJcMzQxDVwzMTRcMzEwIVwiHkhc MzEwDkg4HidcMzQyDkg4Hi9cMzE0XDMxNSEOQUIWQVwzNDZcMzU3XDMxNFwzMTUhDkdcMzQ0IEQj XDIxMA5IQA5IQUAOJw4vXDMxN1wyNTcFFkhcMzQzXDMwNVwzMTRcMzEwIQ5II1wyMTArXDIwMlwz MzIBZWJcMjEwXDMzN1wzNjBcMzE3XDMxMiNcMjAzcAJcMzQxDjFcMzE0XDMxMCFcIh5NXDMxNFwz MTAhDkBCFkBcMzQzXDM2MVwzMTRcMzEwIVwzMTRcMzE1IVwyMDReAg5HXDM0NCBcMzEwDk04XDM0 Mg5NOEZcMjAyagIOTUAOTUFADkdcMzQ0IEYjXDIxMClcMjAyKgJcbkESXDM0M1wzNjIORw5DDkIO QQ5ADj9cMjU3BSNcMjEwKQ5GXDIwM1wyMjICXDM2M3AhXDIxMFwyMDJcMjM2Ag5OXDIwNFwyMzYC XDMzM1wzMzRcMzY0Dk8jXDIxMFxmcVwyMTAuCVwyMDJKAFwzNjUNXDM2NlwiFVwzNjUOMVwzNjdc IhYxDVwyMDNcMjc0AlwzNDNcMzcwCA0jXDIxMA4xXDIwM1wzMTACXDM0M1wzNzEIDjEjXDIxMA48 XDIwM1wzMjUCXDM0M1wzNzIIDjxDI1wyMTBcMzIwXDM3MwlcMjAzXDMzNwJcMzIzXDIwMlwzNDAC XDMyNA4+XDIwNlwzNDYCXDMyNQgkXDIxMFwzMTIuCVwyMDciIFtuYW1lIGlzLWRpcmVjdG9yeSBm aWxlLWxpc3QgY2FzZS1mb2xkLXNlYXJjaCBzb3VyY2UtYnVmZmVyIGVudC1hbGlzdCBzdHJpbmct bWF0Y2ggIlxcKC4qL1xcKVxcKC4qXFwpIiAyIHZoZGwtZ2V0LXNvdXJjZS1maWxlcyB0IHZoZGwt ZGlyZWN0b3J5LWZpbGVzIG1hdGNoLXN0cmluZyAxIHdpbGRjYXJkLXRvLXJlZ2V4cCBuaWwgbWVz c2FnZSAiTm8gc3VjaCBmaWxlOiBcIiVzXCIiICJTY2FubmluZyAlcyAlc1wiJXNcIi4uLiAoJTJk JXMpIiAiZGlyZWN0b3J5IiAiZmlsZXMiICIiIDEwMCAiJSIgYWJicmV2aWF0ZS1maWxlLW5hbWUg ZmluZC1idWZmZXItdmlzaXRpbmcgZmluZC1maWxlLW5vc2VsZWN0IG1vZGlmeS1zeW50YXgtZW50 cnkgOTUgInciIHN5bnRheC10YWJsZSByZS1zZWFyY2gtZm9yd2FyZCAiXlxccy0qZW50aXR5XFxz LStcXChcXHcrXFwpIiBhZ2V0IDMgYXB1dCB2aGRsLWN1cnJlbnQtbGluZSAiXlxccy0qXFwoYXJj aGl0ZWN0dXJlXFxzLStcXChcXHcrXFwpXFxzLStvZlxccy0rXFwoXFx3K1xcKVxcfFxcKFxcdytc XClcXHMtKjpcXChcXHMtXFx8XG5cXCkqXFwoZW50aXR5XFxzLStcXHcrXFwuXFwpP1xcKFxcdytc XClcXChcXHMtKihcXChcXHcrXFwpKVxcKT9cXChcXHMtXFx8XG5cXHwtLS4qXG5cXCkqXFwoZ2Vu ZXJpY1xcfHBvcnRcXClcXHMtK21hcFxcPlxcKSIgdmhkbC1hYXBwZW5kIGFyY2gtYWxpc3QgNCA3 IDkgcmUtc2VhcmNoLWJhY2t3YXJkICI6IiBpbnN0LWFsaXN0ICJeXFxzLSpjb25maWd1cmF0aW9u XFxzLStcXChcXHcrXFwpXFxzLStvZlxccy0rXFwoXFx3K1xcKSIgY29uZi1hbGlzdCAiXlxccy0q cGFja2FnZVxccy0rXFwoYm9keVxccy0rXFwpP1xcKFxcdytcXCkiIHBhY2stYWxpc3QgdmhkbC1m aWxlLWFsaXN0IGtpbGwtYnVmZmVyICJfIiBzb3J0ICNbKGEgYikgIghACUBcMjMxXDIwNyIgW2Eg Yl0gMl0gI1soYSBiKSAiCEAJQFwyMzFcMjA3IiBbYSBiXSAyXSB2aGRsLWVudGl0eS1hbGlzdCB2 aGRsLXBhY2thZ2UtYWxpc3QgdmhkbC1lbnQtaW5zdC1hbGlzdCAiU2Nhbm5pbmcgJXMgJXNcIiVz XCIuLi5kb25lIiBlbnQtaW5zdC1saXN0IG5vLWZpbGVzIG51bS1zdHJpbmcgaW5zdC1saXN0IHBh Y2stbGlzdCBjb25mLWxpc3QgYXJjaC1saXN0IGVudC1saXN0IGVudC1uYW1lIGFyY2gtbmFtZSBv cGVuZWQgZmlsZS1uYW1lIGVudC1lbnRyeSBhcmNoLWVudHJ5IGluc3QtbmFtZSBpbnN0LWVudC1u YW1lIGluc3QtYXJjaC1uYW1lIHBhY2stZW50cnkgdmhkbC11bmRlcnNjb3JlLWlzLXBhcnQtb2Yt d29yZCB2aGRsLW1vZGUtc3ludGF4LXRhYmxlXSAxMCAoIyQgLiAyODQwOTkpXSkKI0A4NCBTY2Fu IHRoZSBjb250ZW50cyBvZiBhbGwgVkhETCBmaWxlcyBmb3VuZCBpbiB0aGUgZGlyZWN0b3JpZXMg YW5kIGZpbGVzCm9mIFBST0pFQ1QuHwooZGVmYWxpYXMgJ3ZoZGwtc2Nhbi1wcm9qZWN0LWNvbnRl bnRzICNbKHByb2plY3QgJm9wdGlvbmFsIHJlc2NhbikgIlwzMDYICVwiQUBcMzA3XDIxMVwyMTFc MjExXDIxMVwyMTFcMjExXDIxMRobHB0eIB4YHhUeIR5cIlwzMTAOXCIhXDIxMRZcIlwyMDNRAA5c IkAVXDMxMVwzMTINXCJcMjAzQABcMzEzDiFcMzE0XDMxNVwzMTYNXCIhXCIWIVwyMDJIAFwzMTMO IQ1DXCIWIQ5cIkFcMjExFlwiXDIwNCYADiFHE1wzMTYSDiFcMjAzTQFcMzE3DiFAIRQOI1wyMDR3 AFwzMjBcZg4kXCJcMjA0XDIwMABcMzIwXGYOJVwiXDIwNFwyMDAAXDMyMVxmXDMyMlwzMjNcbgsj XCJcMjEwXDMwNg4kXGZcIlwyMTEeJlwyMDNcMzMwAA4mQEAeJw4mQEEeKFwzMDYOFQ4nXCIeKVwz MjRcMzI1DicOKUBcMjA2XDI1NAAOKEAOKUFAXDIwNlwyNjcADihBQFwzMTNcMzI2Dik4XDMyNg4o OFwiXDMxM1wzMjcOKThcMzI3Dig4XCJGI1wyMTArDiZBXDIxMRYmXDIwNFwyMTMAKVwzMDYOJVxm XCJcMjExHipcMjAzMwEOKkBAHisOKkBBHixcMzA2DhgOK1wiHi1cMzI0XDMzMA4rDi1AXDIwNgUB DixADi1BQFwyMDYQAQ4sQUBcMzI2Di04XDIwNhsBXDMyNg4sOFwzMjcOLThcMjA2JgFcMzI3Diw4 RiNcMjEwKw4qQVwyMTEWKlwyMDRcMzQ0AClcMzEzDiBcMzMxXDMwNg4uXGZcIkAhXCIWIA4hQRYh XG5UElwyMDJXAA4VXDIwM1xcAVwzMjRcMzMyCVwzMzMOFVwzMzRcIiNcMjEwDhhcMjAzawFcMzI0 XDMzNQlcMzMzDhhcMzM2XCIjXDIxMA4gXDIwNXYBXDMyNFwzMzcJDiAjLglcMjA3IiBbdmhkbC1w cm9qZWN0LWFsaXN0IHByb2plY3QgYWN0LWRpciBudW0tZGlyIG5hbWUgZGlyIGFnZXQgbmlsIHZo ZGwtcmVzb2x2ZS1wYXRocyBzdHJpbmctbWF0Y2ggIi1yIFxcKC4qL1xcKSIgYXBwZW5kIHZoZGwt Z2V0LXN1YmRpcnMgbWF0Y2gtc3RyaW5nIDEgYWJicmV2aWF0ZS1maWxlLW5hbWUgYXNzb2Mgdmhk bC1zY2FuLWZpbGUtY29udGVudHMgZm9ybWF0ICIoJXMvJXMpICIgYXB1dCBwcm8tZW50LWFsaXN0 IDIgMyBwcm8tcGFjay1hbGlzdCBjb3B5LWFsaXN0IHZoZGwtcHJvamVjdC1lbnRpdHktYWxpc3Qg c29ydCAjWyhhIGIpICIIQAlAXDIzMVwyMDciIFthIGJdIDJdIHZoZGwtcHJvamVjdC1wYWNrYWdl LWFsaXN0ICNbKGEgYikgIghACUBcMjMxXDIwNyIgW2EgYl0gMl0gdmhkbC1wcm9qZWN0LWVudC1p bnN0LWxpc3QgcHJvLWVudC1pbnN0LWxpc3QgZGlyLWxpc3QgZGlyLWxpc3QtdG1wIHJlc2NhbiB2 aGRsLWVudGl0eS1hbGlzdCB2aGRsLXBhY2thZ2UtYWxpc3QgZW50LWFsaXN0IGVudC1uYW1lIGVu dC1lbnRyeSBwcm8tZW50LWVudHJ5IHBhY2stYWxpc3QgcGFjay1uYW1lIHBhY2stZW50cnkgcHJv LXBhY2stZW50cnkgdmhkbC1lbnQtaW5zdC1hbGlzdF0gMTEgKCMkIC4gMjg3MTA1KV0pCiNAODUg R2V0IGluc3RhbnRpYXRpb24gaGllcmFyY2h5IGJlZ2lubmluZyBpbiBhcmNoaXRlY3R1cmUgQVJD SC1OQU1FIG9mCmVudGl0eSBFTlQtTkFNRS4fCihkZWZhbGlhcyAndmhkbC1nZXQtaGllcmFyY2h5 ICNbKGVudC1uYW1lIGFyY2gtbmFtZSBsZXZlbCBpbmRlbnQgJm9wdGlvbmFsIGVudC1oaWVyKSAi XDMwNggJXCJBQFwyMDMQAFwzMDZcbglcIlwyMDIbAFwzMDYLXDMwN1wzMTBcMzExXGZTISEhXCId XDMwNg0OGFwiHhkOGlwyMDMzAFwzMDZcMzEyDhk4DhpcIlwyMDI7AFwzMTNcMzEyDhk4IUBBHhtc MzEyDhs4HhxcMzE0Hh1cMzE0Hh5cMzE0Hh9cMzE0HiAOIVwzMTVVXDIwM1oAXDMxNlwzMTchXDIx MA4YDlwiXDIzNVwyMDNqAFwzMjBcMzIxXDMyMg4YXCIhXDIxMA4cXDIwM1wzNTIADhxAFh1cMzA2 DVwzMjMOHThcIhYeXDMyNA4dOFwyMDNcMjI2AFwzMjQOHThcMzA2XDMxMg4eOFwzMjQOHThcIkJc MjAyXDIzNQBcMzEzXDMxMg4eOCFAFh9cMzI1DiAOHUAOHUFAXDMxMg4dOEJcMzIzDh04Dh5ADh5B QEIOH0AOH0FAXDMxMg4fOEIOIVwyNTcHXDMyNlwzMjMOHThcMzI0Dh04DiFUXGYOGA5cIkIlQlwi FiAOHEFcMjExFhxcMjA0bwAOIVwzMTVVXDIwM1wzNjUAXDMxNlwzMjchXDIxMA4gLghcMjA3IiBb dmhkbC1wcm9qZWN0LWFsaXN0IHZoZGwtcHJvamVjdCB2aGRsLXByb2plY3QtZW50aXR5LWFsaXN0 IHZoZGwtZW50aXR5LWFsaXN0IGluZGVudCBlbnQtYWxpc3QgYWdldCBhYmJyZXZpYXRlLWZpbGUt bmFtZSBmaWxlLW5hbWUtYXMtZGlyZWN0b3J5IHNwZWVkYmFyLWxpbmUtcGF0aCAyIGxhc3Qgbmls IDAgbWVzc2FnZSAiRXh0cmFjdCBkZXNpZ24gaGllcmFyY2h5Li4uIiBlcnJvciBmb3JtYXQgIklu c3RhbnRpYXRpb24gbG9vcCBkZXRlY3RlZDsgY29tcG9uZW50IFwiJXNcIiBpbnN0YW50aWF0ZXMg aXRzZWxmIiAzIDQgYXBwZW5kIHZoZGwtZ2V0LWhpZXJhcmNoeSAiRXh0cmFjdCBkZXNpZ24gaGll cmFyY2h5Li4uZG9uZSIgZW50LW5hbWUgZW50LWVudHJ5IGFyY2gtbmFtZSBhcmNoLWVudHJ5IGlu c3QtbGlzdCBpbnN0LWVudHJ5IGluc3QtZW50LWVudHJ5IGluc3QtYXJjaC1lbnRyeSBoaWVyLWxp c3QgbGV2ZWwgZW50LWhpZXJdIDExICgjJCAuIDI4ODU5MSldKQojQDQ0IEdldCBhbGwgaW5zdGFu dGlhdGlvbnMgb2YgZW50aXR5IEVOVC1OQU1FLh8KKGRlZmFsaWFzICd2aGRsLWdldC1pbnN0YW50 aWF0aW9ucyAjWyhlbnQtbmFtZSBpbmRlbnQpICJcMzA2CAlcIkFAXDIwMxAAXDMwNlxuCVwiXDIw MhoAXDMwNgtcMzA3XDMxMFwzMTFcZiEhIVwiXDMxMlwyMTFcMjExXDIxMVwyMTFcMjExHR4NHg4e Dx4QHhFcMjExHhJcMjAzXDIzNwAOEkAWDlwzMTMODjhcMjExFhFcMjAzXDIyNgAOEUAWDVwzMTMO DThcMjExFhBcMjAzXDIxNQAOEEAVDhNcMzEzDThcMjMyXDIwM1wyMDQADUANQUBcMzE0DThCDg5A Dg5BQFwzMTQODjhCDg1ADg1BQFwzMTQODThCXDI1NwYOD0IWDw4QQVwyMTEWEFwyMDRPAA4RQVwy MTEWEVwyMDRAAA4SQVwyMTEWElwyMDQxAA4PXDIzNy4HXDIwNyIgW3ZoZGwtcHJvamVjdC1hbGlz dCB2aGRsLXByb2plY3QgdmhkbC1wcm9qZWN0LWVudGl0eS1hbGlzdCB2aGRsLWVudGl0eS1hbGlz dCBpbmRlbnQgaW5zdC1lbnRyeSBhZ2V0IGFiYnJldmlhdGUtZmlsZS1uYW1lIGZpbGUtbmFtZS1h cy1kaXJlY3Rvcnkgc3BlZWRiYXItbGluZS1wYXRoIG5pbCAzIDIgYXJjaC1lbnRyeSBlbnQtZW50 cnkgZW50LWluc3QtbGlzdCBpbnN0LWFsaXN0IGFyY2gtYWxpc3QgZW50LWFsaXN0IGVudC1uYW1l XSA5ICgjJCAuIDI4OTcxNyldKQojQDU0IEtleW1hcCB1c2VkIHdoZW4gaW4gdGhlIFZIREwgaGll cmFyY2h5IGJyb3dzZXIgbW9kZS4fCihkZWZ2YXIgdmhkbC1zcGVlZGJhci1rZXktbWFwIG5pbCAo IyQgLiAyOTAzODMpKQojQDQ5IEFkZGl0aW9uYWwgbWVudS1pdGVtcyB0byBhZGQgdG8gc3BlZWRi YXIgZnJhbWUuHwooZGVmdmFyIHZoZGwtc3BlZWRiYXItbWVudS1pdGVtcyAnKFsiRWRpdCBEZXNp Z24gVW5pdCIgc3BlZWRiYXItZWRpdC1saW5lIHRdIFsiRXhwYW5kIEhpZXJhcmNoeSIgc3BlZWRi YXItZXhwYW5kLWxpbmUgKHNhdmUtZXhjdXJzaW9uIChiZWdpbm5pbmctb2YtbGluZSkgKGxvb2tp bmctYXQgIlswLTldKzogKi5cXCsuICIpKV0gWyJDb250cmFjdCBIaWVyYXJjaHkiIHNwZWVkYmFy LWNvbnRyYWN0LWxpbmUgKHNhdmUtZXhjdXJzaW9uIChiZWdpbm5pbmctb2YtbGluZSkgKGxvb2tp bmctYXQgIlswLTldKzogKi4tLiAiKSldIFsiUmVzY2FuIEhpZXJhcmNoeSIgdmhkbC1zcGVlZGJh ci1yZXNjYW4taGllcmFyY2h5IHRdICItLSIgWyJDb3B5IFBvcnQiIHZoZGwtc3BlZWRiYXItcG9y dC1jb3B5IChzYXZlLWV4Y3Vyc2lvbiAoYmVnaW5uaW5nLW9mLWxpbmUpIChsb29raW5nLWF0ICJb MC05XSs6ICpcXFtbLSs/XVxcXSAiKSldKSAoIyQgLiAyOTA0OTEpKQojQDIyIEluaXRpYWxpemUg c3BlZWRiYXIuHwooZGVmYWxpYXMgJ3ZoZGwtc3BlZWRiYXItaW5pdGlhbGl6ZSAjW25pbCAiCFwy MTEZXDIwMxsACUBBXDMwNj1cMjAzFABcMzA3CUBAIVwyMTAJQVwyMTERXDIwNAYAKVwzMTBcMzEx IVwyMDVnAFwzMTJcMzEzIVwyMTBcblwyMDRRAFwzMTQgElwzMTVcblwzMTZcMzE3I1wyMTBcMzE1 XG5cMzIwXDMxNyNcMjEwXDMxNVxuXDMyMVwzMjIjXDIxMFwzMTVcblwzMjNcMzI0I1wyMTBcMzE1 XG5cMzI1XDMyNiNcMjEwXDMxNVxuXDMyN1wzMzAjXDIxMFwzMTULXDMzMVwzMzIjXDIxMFwzMzNc MzM0IVwyMTBcMzM1XGZCFA1cMjA1ZwBcMzM2XDIxMRYfXDIwNyIgW2F1dG8tbW9kZS1hbGlzdCBt b2RlLWFsaXN0IHZoZGwtc3BlZWRiYXIta2V5LW1hcCBzcGVlZGJhci1rZXktbWFwIHNwZWVkYmFy LXN0ZWFsdGh5LWZ1bmN0aW9uLWxpc3QgdmhkbC1zcGVlZGJhci1zaG93LWhpZXJhcmNoeSB2aGRs LW1vZGUgc3BlZWRiYXItYWRkLXN1cHBvcnRlZC1leHRlbnNpb24gYm91bmRwIHNwZWVkYmFyLW1v ZGUtZnVuY3Rpb25zLWxpc3Qgc3BlZWRiYXItYWRkLW1vZGUtZnVuY3Rpb25zLWxpc3QgKCJ2aGRs IGhpZXJhcmNoeSIgKHNwZWVkYmFyLWl0ZW0taW5mbyAuIHZoZGwtc3BlZWRiYXItaXRlbS1pbmZv KSAoc3BlZWRiYXItbGluZS1wYXRoIC4gc3BlZWRiYXItZmlsZXMtbGluZS1wYXRoKSkgc3BlZWRi YXItbWFrZS1zcGVjaWFsaXplZC1rZXltYXAgZGVmaW5lLWtleSAiZSIgc3BlZWRiYXItZWRpdC1s aW5lICINIiAiKyIgc3BlZWRiYXItZXhwYW5kLWxpbmUgIi0iIHNwZWVkYmFyLWNvbnRyYWN0LWxp bmUgInMiIHZoZGwtc3BlZWRiYXItcmVzY2FuLWhpZXJhcmNoeSAiYyIgdmhkbC1zcGVlZGJhci1w b3J0LWNvcHkgImgiICNbbmlsICJcMzAwXDMwMSFcMjA3IiBbc3BlZWRiYXItY2hhbmdlLWluaXRp YWwtZXhwYW5zaW9uLWxpc3QgInZoZGwgaGllcmFyY2h5Il0gMiBuaWwgbmlsXSBzcGVlZGJhci1h ZGQtZXhwYW5zaW9uLWxpc3QgKCJ2aGRsIGhpZXJhcmNoeSIgdmhkbC1zcGVlZGJhci1tZW51LWl0 ZW1zIHZoZGwtc3BlZWRiYXIta2V5LW1hcCB2aGRsLXNwZWVkYmFyLWRpc3BsYXktaGllcmFyY2h5 KSAoInZoZGwgaGllcmFyY2h5IiB2aGRsLXNwZWVkYmFyLXVwZGF0ZS1jdXJyZW50LXVuaXQpICJ2 aGRsIGhpZXJhcmNoeSIgc3BlZWRiYXItaW5pdGlhbC1leHBhbnNpb24tbGlzdC1uYW1lXSA1ICgj JCAuIDI5MTAzMSldKQojQDIyIE9wZW4vY2xvc2Ugc3BlZWRiYXIuHwooZGVmYWxpYXMgJ3ZoZGwt c3BlZWRiYXIgI1soJm9wdGlvbmFsIGFyZykgIlwzMDBcMzAxIVwyMDRcbgBcMzAyXDMwMyFcMjA3 XDMwNFwzMDVcMzA2XDIxN1wyMDciIFtmYm91bmRwIHNwZWVkYmFyIGVycm9yICJXQVJOSU5HOiAg U3BlZWRiYXIgaXMgb25seSBhdmFpbGFibGUgaW4gbmV3ZXIgRW1hY3MgdmVyc2lvbnMiIG5pbCAo c3BlZWRiYXItZnJhbWUtbW9kZSBhcmcpICgoZXJyb3IgKGVycm9yICJXQVJOSU5HOiAgSW5zdGFs bCBpbmNsdWRlZCBgc3BlZWRiYXIuZWwnIHBhdGNoIGZpcnN0IikpKV0gMyAoIyQgLiAyOTIyNTgp IG5pbF0pCihieXRlLWNvZGUgIlwzMDFcMzAwIVwyMDQOAFwzMDJcMzAzXDMwNFwiXDIxMFwyMDIY AFwzMDQgXDIxMAhcMjAzGABcMzA1IFwyMTBcMzAxXDIwNyIgW3NwZWVkYmFyLWZyYW1lIGJvdW5k cCBhZGQtaG9vayBzcGVlZGJhci1sb2FkLWhvb2sgdmhkbC1zcGVlZGJhci1pbml0aWFsaXplIHNw ZWVkYmFyLXJlZnJlc2hdIDMpCiNANTMgQWxsb3cgdGhlIGJ1ZmZlciB0byBiZSB3cml0YWJsZSBh bmQgZXZhbHVhdGUgRk9STVMuHwooZGVmYWxpYXMgJ3NwZWVkYmFyLXdpdGgtd3JpdGFibGUgJyht YWNybyAuICNbKCZyZXN0IGZvcm1zKSAiXDMwMVwzMDJcMzAzCEJFXDIwNyIgW2Zvcm1zIGxldCAo KGluaGliaXQtcmVhZC1vbmx5IHQpKSBwcm9nbl0gNCAoIyQgLiAyOTI3NzYpXSkpCihwdXQgJ3Nw ZWVkYmFyLXdpdGgtd3JpdGFibGUgJ2xpc3AtaW5kZW50LWZ1bmN0aW9uIDApCiNANTggRGlzcGxh eSBkaXJlY3RvcnkgYW5kIGhpZXJhcmNoeSBpbmZvcm1hdGlvbiBpbiBzcGVlZGJhci4fCihkZWZh bGlhcyAndmhkbC1zcGVlZGJhci1kaXNwbGF5LWhpZXJhcmNoeSAjWyhkaXJlY3RvcnkgZGVwdGgg Jm9wdGlvbmFsIHJlc2NhbikgIlwzMDZcMzA3CCEhEFwzMTARXDMxMRpcMjEyXDMxMgtcZlwiQUBc MjAzPwBcMzEzXDMxNFwzMTVcIlwyMTBgHVwzMTZjXDIxMFwzMTcNYFwzMjBcMzExJFwyMTBgFVxm Y1wyMTBcMzE3DWBcMzIxXDMyMiRcMjEwKVwzMjNcMzI0XDMyNVwiXDIxMFwzMjZcZg4cXCJcMjAy XwBcMzI3CA4dXCJcMjEwXDMzMFwzMzEIIQ4dXCJcMjEwXDMzMggOHQ4cI1wyMTAOHVwzMTVVXDIw NV8AXDMzMwghKlwyMDciIFtkaXJlY3Rvcnkgc3BlZWRiYXItbGFzdC1zZWxlY3RlZC1maWxlIGlu aGliaXQtcmVhZC1vbmx5IHZoZGwtcHJvamVjdC1hbGlzdCB2aGRsLXByb2plY3Qgc3RhcnQgYWJi cmV2aWF0ZS1maWxlLW5hbWUgZmlsZS1uYW1lLWFzLWRpcmVjdG9yeSBuaWwgdCBhZ2V0IHZoZGwt c3BlZWRiYXItbWFrZS10aXRsZS1saW5lICJQcm9qZWN0OiIgMCAicDoiIHB1dC10ZXh0LXByb3Bl cnR5IGludmlzaWJsZSBmYWNlIHNwZWVkYmFyLWRpcmVjdG9yeS1mYWNlIGluc2VydC1jaGFyIDEw IDEgdmhkbC1zcGVlZGJhci1pbnNlcnQtcHJvamVjdC1oaWVyYXJjaHkgc3BlZWRiYXItZGlyZWN0 b3J5LWJ1dHRvbnMgdmhkbC1zcGVlZGJhci1pbnNlcnQtZGlycyBzcGVlZGJhci1maWxlLWxpc3Rz IHZoZGwtc3BlZWRiYXItaW5zZXJ0LWRpci1oaWVyYXJjaHkgdmhkbC1zcGVlZGJhci1leHBhbmQt ZGlycyBzcGVlZGJhci1wb3dlci1jbGljayBkZXB0aF0gNSAoIyQgLiAyOTMwMzEpXSkKI0A0NyBJ bnNlcnQgaGllcmFyY2h5IG9mIEVOVC1BTElTVCBhbmQgUEFDSy1BTElTVC4fCihkZWZhbGlhcyAn dmhkbC1zcGVlZGJhci1pbnNlcnQtaGllcmFyY2h5ICNbKGVudC1hbGlzdCBwYWNrLWFsaXN0IGVu dC1pbnN0LWxpc3QgZGVwdGgpICIIXDIwNA0ACVwyMDQNAFwzMDZcMzA3XG5cIlwyMDdcMzEwXDIx MRscCFwyMDMaAFwzMDZcMzExXG5cIlwyMTAIXDIwM00ACEAUXDMxMlwzMTNcMzE0XDMxNVxmQFxm QFwzMTZcZkFAXDMxN1xmOEJcMzIwXG4mCVwyMTBcZkANXDIzNVwyMDRGAFwzMjF/XDIxMFwzMjJj XDIxMFwzMjN1XDIxMAhBXDIxMRBcMjA0HgAJXDIwM1YAXDMwNlwzMjRcblwiXDIxMAlcMjA1eQAJ QBNcMzI1C0ALQUBcMzE3CzhCXDMyNgs4XDMyNws4QlxuJFwyMTAJQVwyMTERXDIwNFoAXDMxMCpc MjA3IiBbZW50LWFsaXN0IHBhY2stYWxpc3QgZGVwdGggcGFjay1lbnRyeSBlbnQtZW50cnkgZW50 LWluc3QtbGlzdCB2aGRsLXNwZWVkYmFyLW1ha2UtdGl0bGUtbGluZSAiTm8gZGVzaWduIHVuaXRz ISIgbmlsICJFbnRpdGllczoiIHNwZWVkYmFyLW1ha2UtdGFnLWxpbmUgYnJhY2tldCA0MyB2aGRs LXNwZWVkYmFyLWV4cGFuZC1lbnRpdHkgdmhkbC1zcGVlZGJhci1maW5kLWZpbGUgMiB2aGRsLXNw ZWVkYmFyLWVudGl0eS1mYWNlIDAgIiAodG9wKSIgMSAiUGFja2FnZXM6IiB2aGRsLXNwZWVkYmFy LW1ha2UtcGFjay1saW5lIDMgNF0gMTEgKCMkIC4gMjkzODkxKV0pCiNAMTE0IEluc2VydCBoaWVy YXJjaHkgb2YgcHJvamVjdC4gIFJlc2NhbiBkaXJlY3RvcmllcyBpZiBSRVNDQU4gaXMgbm9uLW5p bCwKb3RoZXJ3aXNlIHVzZSBjYWNoZWQgZGF0YSBvZiBkaXJlY3Rvcmllcy4fCihkZWZhbGlhcyAn dmhkbC1zcGVlZGJhci1pbnNlcnQtcHJvamVjdC1oaWVyYXJjaHkgI1socHJvamVjdCAmb3B0aW9u YWwgcmVzY2FuKSAiCFwyMDQSAFwzMDUJXG5cIlwyMDQXAFwzMDUJC1wiXDIwNBcAXDMwNgkIXCJc MjEwXDMwN1wzMTBcbglcIlwzMTALCVwiXDMxMFxmCVwiXDMxMSRcMjEwXDMxMgkhXDIwNyIgW3Jl c2NhbiBwcm9qZWN0IHZoZGwtcHJvamVjdC1lbnRpdHktYWxpc3QgdmhkbC1wcm9qZWN0LXBhY2th Z2UtYWxpc3QgdmhkbC1wcm9qZWN0LWVudC1pbnN0LWxpc3QgYXNzb2MgdmhkbC1zY2FuLXByb2pl Y3QtY29udGVudHMgdmhkbC1zcGVlZGJhci1pbnNlcnQtaGllcmFyY2h5IGFnZXQgMCB2aGRsLXNw ZWVkYmFyLWV4cGFuZC11bml0c10gNiAoIyQgLiAyOTQ2MjIpXSkKI0A5OSBJbnNlcnQgaGllcmFy Y2h5IG9mIERJUkVDVE9SWS4gIFJlc2NhbiBkaXJlY3RvcnkgaWYgUkVTQ0FOIGlzIG5vbi1uaWws Cm90aGVyd2lzZSB1c2UgY2FjaGVkIGRhdGEuHwooZGVmYWxpYXMgJ3ZoZGwtc3BlZWRiYXItaW5z ZXJ0LWRpci1oaWVyYXJjaHkgI1soZGlyZWN0b3J5IGRlcHRoICZvcHRpb25hbCByZXNjYW4pICII XDIwNBIAXDMwNglcblwiXDIwNBYAXDMwNgkLXCJcMjA0FgBcMzA3CSFcMjEwXDMxMFwzMTFcbglc IlwzMTELCVwiXDMxMVxmCVwiQA0kXDIxMFwzMTIJIVwyMDciIFtyZXNjYW4gZGlyZWN0b3J5IHZo ZGwtZW50aXR5LWFsaXN0IHZoZGwtcGFja2FnZS1hbGlzdCB2aGRsLWVudC1pbnN0LWFsaXN0IGRl cHRoIGFzc29jIHZoZGwtc2Nhbi1maWxlLWNvbnRlbnRzIHZoZGwtc3BlZWRiYXItaW5zZXJ0LWhp ZXJhcmNoeSBhZ2V0IHZoZGwtc3BlZWRiYXItZXhwYW5kLXVuaXRzXSA2ICgjJCAuIDI5NTEzMyld KQojQDc3IFJlc2NhbiBoaWVyYXJjaHkgZm9yIHRoZSBkaXJlY3RvcnkgdW5kZXIgdGhlIGN1cnNv ciBvciB0aGUgY3VycmVudCBwcm9qZWN0Lh8KKGRlZmFsaWFzICd2aGRsLXNwZWVkYmFyLXJlc2Nh bi1oaWVyYXJjaHkgI1tuaWwgIlwzMDMICVwiQUBcMjAzEQBcMzA0CVwzMDVcIlwyMTBcMzA2IFwy MDdcMjEyXDMwN3lcMjEwXDMxMFwzMTEhKVwyMDMsAFwzMTJcMzEzXDMxNFwzMDUjXDIxMFwzMTVc MzE2XDMxNyAhIVwyMTBcMzA2IFwyMDdcMzE3IBpcMzIwXDMyMVxuXCJcMjEwXDMxNVwzMTZcMzIy XDMyM1xuXCIhIVwyMTBcMzA2IClcMjA3IiBbdmhkbC1wcm9qZWN0LWFsaXN0IHZoZGwtcHJvamVj dCBwYXRoIGFnZXQgdmhkbC1zY2FuLXByb2plY3QtY29udGVudHMgdCBzcGVlZGJhci1yZWZyZXNo IDAgbG9va2luZy1hdCAiW14wLTldIiByZS1zZWFyY2gtZm9yd2FyZCAiWzAtOV0rOiIgbmlsIHZo ZGwtc2Nhbi1maWxlLWNvbnRlbnRzIGFiYnJldmlhdGUtZmlsZS1uYW1lIHNwZWVkYmFyLWxpbmUt cGF0aCBzdHJpbmctbWF0Y2ggIl5cXCguKy9cXCkiIG1hdGNoLXN0cmluZyAxXSA1ICgjJCAuIDI5 NTYwOSkgbmlsXSkKI0A4MCBFeHBhbmQgc3ViZGlyZWN0b3JpZXMgaW4gRElSRUNUT1JZIGFjY29y ZGluZyB0bwogYHNwZWVkYmFyLXNob3duLWRpcmVjdG9yaWVzJy4fCihkZWZhbGlhcyAndmhkbC1z cGVlZGJhci1leHBhbmQtZGlycyAjWyhkaXJlY3RvcnkpICJcMzA1CCFBGVwzMDZcbiFDEAlcMjA1 NwBcMzA3CUAhXDIwMy8AXDMxMHlcMjEwXDMxMVwzMTIhXDIwMy8AXDMxMFwyMjViXDIxMGAbXDMx M1wzMTRcMzE1ICEhHFwzMTYgXDIxMCoJQVwyMTERXDIwNA4AXDMxNylcMjA3IiBbc3BlZWRiYXIt c2hvd24tZGlyZWN0b3JpZXMgc2YgZGVmYXVsdC1kaXJlY3RvcnkgcG9zaXRpb24gZGlyZWN0b3J5 IHJldmVyc2UgZXhwYW5kLWZpbGUtbmFtZSBzcGVlZGJhci1nb3RvLXRoaXMtZmlsZSAwIGxvb2tp bmctYXQgIlswLTldKzpcXHMtKjwiIGFiYnJldmlhdGUtZmlsZS1uYW1lIGZpbGUtbmFtZS1hcy1k aXJlY3Rvcnkgc3BlZWRiYXItbGluZS1maWxlIHNwZWVkYmFyLWRvLWZ1bmN0aW9uLXBvaW50ZXIg bmlsXSA0ICgjJCAuIDI5NjE4OSldKQojQDgyIEV4cGFuZCBkZXNpZ24gdW5pdHMgaW4gRElSRUNU T1JZIGFjY29yZGluZyB0bwpgdmhkbC1zcGVlZGJhci1zaG93bi11bml0cy1hbGlzdCcuHwooZGVm YWxpYXMgJ3ZoZGwtc3BlZWRiYXItZXhwYW5kLXVuaXRzICNbKGRpcmVjdG9yeSkgIlwzMDUICVwi GlwzMDZcMzAwCVwiXDIxMFxuXDIwNV8AXDMwNwlcbkBAXCJcMjEwXDMxMHlcMjEwXG5AQUBcMzEx GxxcMzEyXDMxMyFcMjAzWABcMzEwXDIyNWJcMjEwYBNcMzE0IFwyMTBcZlwyMDNYAAtiXDIxMFwz MTVcMzE2XGZAXDMxN1FcMzExXDMyMCNcMjAzUQBcMzEweVwyMTBcMzEyXDMyMSFcMjAzUQBcMzEw XDIyNWJcMjEwXDMxNCBcMjEwXGZBXDIxMRRcMjA0MgBcbkESKlwyMDJcbgApXDIwNyIgW3ZoZGwt c3BlZWRiYXItc2hvd24tdW5pdHMtYWxpc3QgZGlyZWN0b3J5IGVudC1hbGlzdCBwb3NpdGlvbiBh cmNoLWFsaXN0IGFnZXQgYWRlbGV0ZSB2aGRsLXNwZWVkYmFyLWdvdG8tdGhpcy11bml0IDAgbmls IGxvb2tpbmctYXQgIlswLTldKzpcXHMtKlxcWyIgc3BlZWRiYXItZG8tZnVuY3Rpb24tcG9pbnRl ciByZS1zZWFyY2gtZm9yd2FyZCAiWzAtOV0rOlxccy0qXFwoXFxbXFx8ey59XFxzLSsiICJcXD5c XCkiIHQgIlswLTldKzpcXHMtKnsiXSA1ICgjJCAuIDI5NjcxMyldKQojQDQ2IEV4cGFuZC9jb250 cmFjdCB0aGUgZW50aXR5IHVuZGVyIHRoZSBjdXJzb3IuHwooZGVmYWxpYXMgJ3ZoZGwtc3BlZWRi YXItZXhwYW5kLWVudGl0eSAjWyh0ZXh0IHRva2VuIGluZGVudCkgIlwzMDZcMzA3CFwiXDIwM1gB XDMxMAlcblwiQUBcMjAzFwBcMzEwC1xuXCJcMjAyIQBcMzEwXGZcMzExXDMxMlwzMTMNISEhXCIe FFwzMTRcMzEwDhQOL1wiOB4wXDMxNVwzMTAOFA4vXCI4HjFcMzE2Di8NXCIeMlwzMTceM1wzMTce NFwzMTceNQ4wXDIwNF0ADjFcMjA0XQAOMlwyMDRdAFwzMjBcMzIxIVwyMTBcMjAyUwFcMzIwXDMy MiFcMjEwXDMxMAlcblwiQUBcMjAzbgBcblwyMDJ0AFwzMTFcMzEyXDMxMyAhIR42XDMxMA4WDjZc Ih4UXDMyM1wzMjRcMzI1IFwzMTcjXDIxMFwzMjNcMzI2DjYOFCNcMjEwKlwzMjceN1wyMTJcMzE3 f1wyMTBcMzMwdVwyMTAOMFwyMDNcMjQzAFwzMzFcMzMyDVRcIlwyMTAOMFwyMDNcMzIzAA4wQBYz XDMzM1wzMzRcMzM1XDMzNg4vDjNAQg4zQFwzMzcOM0FAXDMxNA4zOEJcMzQwDVQmCVwyMTAOMEFc MjExFjBcMjA0XDI1MAAOMVwyMDNcMzM2AFwzMzFcMzQxDVRcIlwyMTAOMVwyMDMOAQ4xQBY0XDMz M1wzMTdcMjExXDIxMQ4vDjRAQg40QFwzMzcONEFAXDMxNA40OEJcMzQyDVQmCVwyMTAOMUFcMjEx FjFcMjA0XDM0MwAOMlwyMDMZAVwzMzFcMzQzDVRcIlwyMTAOMlwyMDNKAQ4yQBY1XDM0NA41QA41 QUBcMzE0DjU4XDMxNQ41OFwzNDUONThcMzQ2DjU4DVRcMzQ3JghcMjEwDjJBXDIxMRYyXDIwNB4B KlwzMTcWOFwyMTJcMzUwIFwyMTApLgdcMjAyXDI1MAFcMzA2XDM1MQhcIlwyMDNcMjQ0AVwzMjBc MzM1IVwyMTBcMzEwCVxuXCJBQFwyMDNwAVxuXDIwMnYBXDMxMVwzMTJcMzEzICEhHjZcMzEwDhYO NlwiHhRcMzUyXDMyNFwzMjUgXCJcMjEwDhRcMjAzXDIyNgFcMzIzXDMyNg42DhQjXDIxMFwyMDJc MjM0AVwzNTJcMzI2DjZcIlwyMTAqXDM1Mw0hXDIxMFwyMDJcMjUwAVwzNTRcMzU1IVwyMTBcMzU2 IFwyMDciIFt0ZXh0IHZoZGwtcHJvamVjdC1hbGlzdCB2aGRsLXByb2plY3QgdmhkbC1wcm9qZWN0 LWVudGl0eS1hbGlzdCB2aGRsLWVudGl0eS1hbGlzdCBpbmRlbnQgc3RyaW5nLW1hdGNoICIrIiBh Z2V0IGFiYnJldmlhdGUtZmlsZS1uYW1lIGZpbGUtbmFtZS1hcy1kaXJlY3Rvcnkgc3BlZWRiYXIt bGluZS1wYXRoIDIgMyB2aGRsLWdldC1pbnN0YW50aWF0aW9ucyBuaWwgc3BlZWRiYXItY2hhbmdl LWV4cGFuZC1idXR0b24tY2hhciA2MyA0NSBhcHV0IGVudC1hbGlzdCBzcGVlZGJhci1saW5lLXRl eHQgdmhkbC1zcGVlZGJhci1zaG93bi11bml0cy1hbGlzdCB0IDEgdmhkbC1zcGVlZGJhci1tYWtl LXRpdGxlLWxpbmUgIkFyY2hpdGVjdHVyZXM6IiBzcGVlZGJhci1tYWtlLXRhZy1saW5lIGN1cmx5 IDQzIHZoZGwtc3BlZWRiYXItZXhwYW5kLWFyY2hpdGVjdHVyZSB2aGRsLXNwZWVkYmFyLWZpbmQt ZmlsZSB2aGRsLXNwZWVkYmFyLWFyY2hpdGVjdHVyZS1mYWNlICJDb25maWd1cmF0aW9uczoiIHZo ZGwtc3BlZWRiYXItY29uZmlndXJhdGlvbi1mYWNlICJJbnN0YW50aWF0aW9uczoiIHZoZGwtc3Bl ZWRiYXItbWFrZS1pbnN0LWxpbmUgNCA1IDAgc3BlZWRiYXItc3RlYWx0aHktdXBkYXRlcyAiLSIg YWRlbGV0ZSBzcGVlZGJhci1kZWxldGUtc3ViYmxvY2sgZXJyb3IgIk5vIGFyY2hpdGVjdHVyZXMs IGNvbmZpZ3VyYXRpb25zLCBub3IgaW5zdGFudGlhdGlvbnMgZXhpc3QgZm9yIHRoaXMgZW50aXR5 IiBzcGVlZGJhci1jZW50ZXItYnVmZmVyLXNtYXJ0bHkgdG9rZW4gYXJjaC1hbGlzdCBjb25mLWFs aXN0IGluc3QtYWxpc3QgYXJjaC1lbnRyeSBjb25mLWVudHJ5IGluc3QtZW50cnkgZGlyZWN0b3J5 IGluaGliaXQtcmVhZC1vbmx5IHNwZWVkYmFyLWxhc3Qtc2VsZWN0ZWQtZmlsZV0gMTEgKCMkIC4g Mjk3MzU4KV0pCiNANTIgRXhwYW5kL2NvbnRyYWN0IHRoZSBhcmNoaXRlY3R1cmUgdW5kZXIgdGhl IGN1cnNvci4fCihkZWZhbGlhcyAndmhkbC1zcGVlZGJhci1leHBhbmQtYXJjaGl0ZWN0dXJlICNb KHRleHQgdG9rZW4gaW5kZW50KSAiXDMwNlwzMDcIXCJcMjAzXDI3NgBcMzEwCUAJQVwzMTFcbiRc MjExG1wyMDQbAFwzMTJcMzEzIVwyMTBcMjAyXDI3MgBcMzEyXDMxNCFcMjEwXDMxNSAcXDMwNlwz MTZcZlwiHVwzMTdcMzIwXGZcIh4pXDMyMQ4qDitcIkFAXDIwMz0ADitcMjAyQwBcMzIyXDMxN1wz MjNcZlwiIR4sXDMyMQ4YDixcIh4WXDMyMQ4WDilcMzI0I0AeLVwzMjVcMzI2DilcMzI3IA4tQkMj XDIxMFwzMjVcMzMwDiwOFiNcMjEwLgZcMzI0Hi5cMjEyXDMzMX9cMjEwXDMyM3VcMjEwC1wyMDNc MjAxAFwzMzJcMzMzXG5UXCJcMjEwC1wyMDNcMjYxAAtAHi9cMzM0Di9ADi9BQFwzMjAOLzhcMzM1 Di84XDMzNg4vOFwzMzcOLzhcblRcMzQwDi84JghcMjEwC0ETKVwyMDJcMjAxACpcMzMxFjBcMjEy XDM0MSBcMjEwKSlcMjAyIwFcMzA2XDM0MghcIlwyMDMfAVwzMTJcMzQzIVwyMTBcMzE1IBxcMzA2 XDMxNlxmXCIdXDMxN1wzMjBcZlwiHilcMzIxDioOK1wiQUBcMjAzXDM0NwAOK1wyMDJcMzU1AFwz MjJcMzE3XDMyM1xmXCIhHixcMzIxDhgOLFwiHhZcMzIxDhYOKVwzMjQjQB4tXDMyNVwzMjYOKVwz NDRcMzI3IA4tXCJDI1wyMTBcMzI1XDMzMA4sDhYjXDIxMC4GXDM0NVxuIVwyMTBcMjAyIwFcMzQ2 XDM0NyFcMjEwXDM1MCBcMjA3IiBbdGV4dCB0b2tlbiBpbmRlbnQgaGllci1hbGlzdCBwYXRoIGR1 bW15IHN0cmluZy1tYXRjaCAiKyIgdmhkbC1nZXQtaGllcmFyY2h5IDAgc3BlZWRiYXItY2hhbmdl LWV4cGFuZC1idXR0b24tY2hhciA2MyA0NSBzcGVlZGJhci1saW5lLXBhdGggIl5cXCguKy9cXClc XChbXi8gXStcXCkiIG1hdGNoLXN0cmluZyAyIGFnZXQgYWJicmV2aWF0ZS1maWxlLW5hbWUgMSB0 IGFwdXQgZW50LWFsaXN0IHNwZWVkYmFyLWxpbmUtdGV4dCB2aGRsLXNwZWVkYmFyLXNob3duLXVu aXRzLWFsaXN0IG5pbCB2aGRsLXNwZWVkYmFyLW1ha2UtdGl0bGUtbGluZSAiU3ViY29tcG9uZW50 czoiIHZoZGwtc3BlZWRiYXItbWFrZS1pbnN0LWxpbmUgMyA0IDUgNiBzcGVlZGJhci1zdGVhbHRo eS11cGRhdGVzICItIiA0MyBkZWxldGUgc3BlZWRiYXItZGVsZXRlLXN1YmJsb2NrIGVycm9yICJO byBjb21wb25lbnQgaW5zdGFudGlhdGlvbnMgY29udGFpbmVkIGluIHRoaXMgYXJjaGl0ZWN0dXJl IiBzcGVlZGJhci1jZW50ZXItYnVmZmVyLXNtYXJ0bHkgZW50LW5hbWUgdmhkbC1wcm9qZWN0LWFs aXN0IHZoZGwtcHJvamVjdCBkaXJlY3RvcnkgYXJjaC1hbGlzdCBpbmhpYml0LXJlYWQtb25seSBl bnRyeSBzcGVlZGJhci1sYXN0LXNlbGVjdGVkLWZpbGVdIDExICgjJCAuIDI5OTI2NSldKQojQDEy MSBIaWdobGlnaHQgYWxsIGRlc2lnbiB1bml0cyB0aGF0IGFyZSBjb250YWluZWQgaW4gdGhlIGN1 cnJlbnQgZmlsZS4KTk8tUE9TSVRJT04gbm9uLW5pbCBtZWFucyBkbyBub3QgcmUtcG9zaXRpb24g Y3Vyc29yLh8KKGRlZmFsaWFzICd2aGRsLXNwZWVkYmFyLXVwZGF0ZS1jdXJyZW50LXVuaXQgI1so Jm9wdGlvbmFsIG5vLXBvc2l0aW9uKSAiXDMwNiBcMzA3XDIxMRgZGlwzMTALIVwyMTBcMzExXDMx MiBcMjA2EgBcMzEzIVwyMTERXGZcMjMyXDIwNFwzMTcAXDMxMA0hXDIxMA5cInFcMjEwXDMxNB4j XDIxMlwzMTUOJFxmXCIeJVwzMTZcMzE3DiVAXGZcMzIwJFwyMTBcMzE2XDMyMQ4lQUBcZlwzMjIk XDIxMFwzMTZcMzIzXDMyNA4lOFxmXDMyNSRcMjEwXDMxNlwzMjNcMzI2DiU4XGZcMzI3JFwyMTBc MzE2XDMyM1wzMzAOJThcZlwzMzEkXDIxMClcMzE1DiQJXCIeJVwzMTZcMzE3DiVACVwzMzIkXDIx MAhcMjA2dQBcMzMzIBBcMzE2XDMyMQ4lQUAJXDMzNCRcMjEwCFwyMDZcMjA2AFwzMzMgEFwzMTZc MzIzXDMyNA4lOAlcMzM1JFwyMTAIXDIwNlwyMjcAXDMzMyAQXDMxNlwzMjNcMzI2DiU4CVwzMzYk XDIxMAhcMjA2XDI1MABcMzMzIBBcMzE2XDMyM1wzMzAOJTgJXDMzNyRcMjEwKwhcMjA2XDI3MgBc MzMzIFwyMTEQXDIwM1wzMTUADiZcMjA0XDMxNQAIYlwyMTBcMzQwIFwyMTBcMzQxIFwyMTAJFFwz MTBcbiFcMjEwK1wzMTRcMjA3IiBbcG9zaXRpb24gZmlsZS1uYW1lIGxhc3QtZnJhbWUgc3BlZWRi YXItYXR0YWNoZWQtZnJhbWUgc3BlZWRiYXItbGFzdC1zZWxlY3RlZC1maWxlIHNwZWVkYmFyLWZy YW1lIHNlbGVjdGVkLWZyYW1lIG5pbCBzZWxlY3QtZnJhbWUgYWJicmV2aWF0ZS1maWxlLW5hbWUg YnVmZmVyLWZpbGUtbmFtZSAiIiB0IGFnZXQgdmhkbC1zcGVlZGJhci11cGRhdGUtdW5pdHMgIlxc Wy5cXF0iIHZoZGwtc3BlZWRiYXItZW50aXR5LWZhY2UgInsufSIgdmhkbC1zcGVlZGJhci1hcmNo aXRlY3R1cmUtZmFjZSAiPiIgMiB2aGRsLXNwZWVkYmFyLWNvbmZpZ3VyYXRpb24tZmFjZSAzIHZo ZGwtc3BlZWRiYXItcGFja2FnZS1mYWNlIDQgdmhkbC1zcGVlZGJhci1pbnN0YW50aWF0aW9uLWZh Y2UgdmhkbC1zcGVlZGJhci1lbnRpdHktc2VsZWN0ZWQtZmFjZSBwb2ludC1tYXJrZXIgdmhkbC1z cGVlZGJhci1hcmNoaXRlY3R1cmUtc2VsZWN0ZWQtZmFjZSB2aGRsLXNwZWVkYmFyLWNvbmZpZ3Vy YXRpb24tc2VsZWN0ZWQtZmFjZSB2aGRsLXNwZWVkYmFyLXBhY2thZ2Utc2VsZWN0ZWQtZmFjZSB2 aGRsLXNwZWVkYmFyLWluc3RhbnRpYXRpb24tc2VsZWN0ZWQtZmFjZSBzcGVlZGJhci1jZW50ZXIt YnVmZmVyLXNtYXJ0bHkgc3BlZWRiYXItcG9zaXRpb24tY3Vyc29yLW9uLWxpbmUgc3BlZWRiYXIt YnVmZmVyIGluaGliaXQtcmVhZC1vbmx5IHZoZGwtZmlsZS1hbGlzdCBmaWxlLWVudHJ5IG5vLXBv c2l0aW9uXSA2ICgjJCAuIDMwMDY3NyldKQojQDQyIEhlbHAgZnVuY3Rpb24gdG8gaGlnaGxpZ2h0 IGRlc2lnbiB1bml0cy4fCihkZWZhbGlhcyAndmhkbC1zcGVlZGJhci11cGRhdGUtdW5pdHMgI1so dGV4dCB1bml0LWxpc3QgZmlsZS1uYW1lIGZhY2UpICJcMzA1GAlcMjAzOwBlYlwyMTBcMzA2XG5c MzA3CUBcMzEwUlwzMDVcMzExI1wyMDM0AAtcMzEyXDMxM1wyMjRcMzE0XCJAXDIzMlwyMDMJAAhc MjA2JwBcMzE1IBBcMzE2XDMxM1wyMjRcMzEzXDIyNVwzMDRcZiRcMjEwXDIwMgkACUFcMjExEVwy MDQGAAhcMjA1QQAIYilcMjA3IiBbcG9zaXRpb24gdW5pdC1saXN0IHRleHQgZmlsZS1uYW1lIGZh Y2UgbmlsIHJlLXNlYXJjaC1mb3J3YXJkICIgXFwoIiAiXFwpXFw+IiB0IGdldC10ZXh0LXByb3Bl cnR5IDEgc3BlZWRiYXItdG9rZW4gcG9pbnQtbWFya2VyIHB1dC10ZXh0LXByb3BlcnR5XSA2ICgj JCAuIDMwMjEzMSldKQojQDI5IEluc2VydCBpbnN0YW50aWF0aW9uIGVudHJ5Lh8KKGRlZmFsaWFz ICd2aGRsLXNwZWVkYmFyLW1ha2UtaW5zdC1saW5lICNbKGluc3QtbmFtZSBpbnN0LWZpbGUtbWFy a2VyIGVudC1uYW1lIGVudC1maWxlLW1hcmtlciBhcmNoLW5hbWUgYXJjaC1maWxlLW1hcmtlciBk ZXB0aCBvZmZzZXQpICJgGFwzMDYJIVwzMDdcMjYxAlwyMTBcMzEwCGBcMzExXDMxMiRcMjEwYBBc MzEzXDMxNAlcbgtfXFxcIlwyMTBcMzE1Y1wyMTBcMzEwCGBcMzExXDMxNiRcMjEwYBBcZmNcMjEw XDMxNwhgXDMyMFwzMjFcMzIyDSYGXDIxMGAQXDMyM2NcMjEwXDMxMAhgXDMxMVwzMTYkXDIxMGAQ DhpjXDIxMFwzMTcIYFwzMjRcMzIxXDMyMg4bJgZcMjEwYBAOHFwyMDN4AFwzMjVjXDIxMFwzMTAI YFwzMTFcMzE2JFwyMTBgEA4cY1wyMTBcMzE3CGBcMzI2XDMyMVwzMjIOHSYGXDIxMGAQXDMyN2Nc MjEwXDMxMAhgXDMxMVwzMTYkXDIxMFwzMTNcMzMwXDMzMVwiXDIxMFwzMTBgU2BcMzExXDMxNiQp XDIwNyIgW3N0YXJ0IGRlcHRoIG9mZnNldCB2aGRsLXNwZWVkYmFyLWhpZXJhcmNoeS1pbmRlbnQg aW5zdC1uYW1lIGluc3QtZmlsZS1tYXJrZXIgaW50LXRvLXN0cmluZyAiOiIgcHV0LXRleHQtcHJv cGVydHkgaW52aXNpYmxlIHQgaW5zZXJ0LWNoYXIgMzIgIj4gIiBuaWwgc3BlZWRiYXItbWFrZS1i dXR0b24gdmhkbC1zcGVlZGJhci1pbnN0YW50aWF0aW9uLWZhY2Ugc3BlZWRiYXItaGlnaGxpZ2h0 LWZhY2UgdmhkbC1zcGVlZGJhci1maW5kLWZpbGUgIjogIiB2aGRsLXNwZWVkYmFyLWVudGl0eS1m YWNlICIgKCIgdmhkbC1zcGVlZGJhci1hcmNoaXRlY3R1cmUtZmFjZSAiKSIgMTAgMSBlbnQtbmFt ZSBlbnQtZmlsZS1tYXJrZXIgYXJjaC1uYW1lIGFyY2gtZmlsZS1tYXJrZXJdIDcgKCMkIC4gMzAy NTc1KV0pCiNAMjMgSW5zZXJ0IHBhY2thZ2UgZW50cnkuHwooZGVmYWxpYXMgJ3ZoZGwtc3BlZWRi YXItbWFrZS1wYWNrLWxpbmUgI1socGFjay1uYW1lIHBhY2stZmlsZS1tYXJrZXIgYm9keS1maWxl LW1hcmtlciBkZXB0aCkgImAYXDMwNQkhXDMwNlwyNjECXDIxMFwzMDcIYFwzMTBcMzExJFwyMTBg EFwzMTJcMzEzCVwiXDIxMFwzMTRjXDIxMFwzMDcIYFwzMTBcMzE1JFwyMTBgEFxuY1wyMTBcMzE2 CGBcMzE3XDMyMFwzMjELJgZcMjEwXGZAXDIwM1xcAGAQXDMyMmNcMjEwXDMwNwhgXDMxMFwzMTUk XDIxMGAQXDMyM2NcMjEwXDMxNghgXDMxN1wzMjBcMzIxXGYmBlwyMTBgEFwzMjRjXDIxMFwzMDcI YFwzMTBcMzE1JFwyMTBcMzEyXDMyNVwzMjZcIlwyMTBcMzA3YFNgXDMxMFwzMTUkKVwyMDciIFtz dGFydCBkZXB0aCBwYWNrLW5hbWUgcGFjay1maWxlLW1hcmtlciBib2R5LWZpbGUtbWFya2VyIGlu dC10by1zdHJpbmcgIjoiIHB1dC10ZXh0LXByb3BlcnR5IGludmlzaWJsZSB0IGluc2VydC1jaGFy IDMyICI+ICIgbmlsIHNwZWVkYmFyLW1ha2UtYnV0dG9uIHZoZGwtc3BlZWRiYXItcGFja2FnZS1m YWNlIHNwZWVkYmFyLWhpZ2hsaWdodC1mYWNlIHZoZGwtc3BlZWRiYXItZmluZC1maWxlICIgKCIg ImJvZHkiICIpIiAxMCAxXSA3ICgjJCAuIDMwMzQ4MCldKQojQDMzIEluc2VydCBkZXNpZ24gdW5p dCB0aXRsZSBlbnRyeS4fCihkZWZhbGlhcyAndmhkbC1zcGVlZGJhci1tYWtlLXRpdGxlLWxpbmUg I1sodGV4dCBkZXB0aCkgImAYXDMwMwkhXDMwNFwyNjECXDIxMFwzMDUIYFwzMDZcMzA3JFwyMTBg EFwzMTBcMzExCVwiXDIxMFwzMDUIYFwzMDZcMzEyJFwyMTBgEFxuY1wyMTBcMzEzCGBcMzEyXDIx MVwyMTFcMjExJgZcMjEwXDMxMFwzMTRcMzE1XCJcMjEwXDMwNQhgXDMwNlwzMTIkKVwyMDciIFtz dGFydCBkZXB0aCB0ZXh0IGludC10by1zdHJpbmcgIjoiIHB1dC10ZXh0LXByb3BlcnR5IGludmlz aWJsZSB0IGluc2VydC1jaGFyIDMyIG5pbCBzcGVlZGJhci1tYWtlLWJ1dHRvbiAxMCAxXSA3ICgj JCAuIDMwNDEzNSldKQojQDI0IEluc2VydCBzdWJkaXJlY3Rvcmllcy4fCihkZWZhbGlhcyAndmhk bC1zcGVlZGJhci1pbnNlcnQtZGlycyAjWyhmaWxlcyBsZXZlbCkgIghAXDIxMRlcMjA1HgBcMzAz XDMwNFwzMDVcMzA2CUAJQFwzMDdcMzEwXDMxMVxuJglcMjEwCUFcMjExEVwyMDQHAFwzMTApXDIw NyIgW2ZpbGVzIGRpcnMgbGV2ZWwgc3BlZWRiYXItbWFrZS10YWctbGluZSBhbmdsZSA0MyB2aGRs LXNwZWVkYmFyLWRpcmVkIHNwZWVkYmFyLWRpci1mb2xsb3cgbmlsIHNwZWVkYmFyLWRpcmVjdG9y eS1mYWNlXSAxMSAoIyQgLiAzMDQ1MTMpXSkKI0A3MSBTcGVlZGJhciBjbGljayBoYW5kbGVyIGZv ciBkaXJlY3RvcnkgZXhwYW5kIGJ1dHRvbiBpbiBoaWVyYXJjaHkgbW9kZS4fCihkZWZhbGlhcyAn dmhkbC1zcGVlZGJhci1kaXJlZCAjWyh0ZXh0IHRva2VuIGluZGVudCkgIlwzMDZcMzA3CFwiXDIw M0wAXDMxMFwzMTEJIVxuXDMxMlEhC0ITXDMxM1wzMTQhXDIxMFwzMTUgXDIxMFwzMTYcXDIxMlwz MTd/XDIxMFwzMjB1XDIxMFwzMjFcMzIyXDMxMQkhXG5cMzEyUSEJVFwiXDIxMFwzMTUgXDIxMFwz MjNcMzI0XDMxMQkhXG5cMzEyUSEJVA0jXDIxMCpcMzE3Fh5cMjEyXDMyNSBcMjEwKVwyMDJcMjM0 AFwzMDZcMzI2CFwiXDIwM1wyMzAAXDMxNSBcMjEwC1wzMTdcMzEwXDMxMQkhXG5QIR4fHiBcMjEx HiFcMjAzXDIxMABcMzA2XDMyN1wzMzAOHyFQDiFAXCJcMjA0fwAOIUAOIEIWIA4hQVwyMTEWIVwy MDRpAA4gXDIzNxMrXDMxM1wzMzEhXDIxMFwzMzIJIVwyMTBcMjAyXDIzNABcMzMzXDMzNCFcMjEw XDMzNSBcMjA3IiBbdGV4dCBpbmRlbnQgdG9rZW4gc3BlZWRiYXItc2hvd24tZGlyZWN0b3JpZXMg aW5oaWJpdC1yZWFkLW9ubHkgc3BlZWRiYXItcG93ZXItY2xpY2sgc3RyaW5nLW1hdGNoICIrIiBl eHBhbmQtZmlsZS1uYW1lIHNwZWVkYmFyLWxpbmUtcGF0aCAiLyIgc3BlZWRiYXItY2hhbmdlLWV4 cGFuZC1idXR0b24tY2hhciA0NSBzcGVlZGJhci1yZXNldC1zY2FubmVycyB0IG5pbCAxIHZoZGwt c3BlZWRiYXItaW5zZXJ0LWRpcnMgc3BlZWRiYXItZmlsZS1saXN0cyB2aGRsLXNwZWVkYmFyLWlu c2VydC1kaXItaGllcmFyY2h5IGFiYnJldmlhdGUtZmlsZS1uYW1lIHNwZWVkYmFyLXN0ZWFsdGh5 LXVwZGF0ZXMgIi0iICJeIiByZWdleHAtcXVvdGUgNDMgc3BlZWRiYXItZGVsZXRlLXN1YmJsb2Nr IGVycm9yICJPb29wcy4uLiAgbm90IHN1cmUgd2hhdCB0byBkbyIgc3BlZWRiYXItY2VudGVyLWJ1 ZmZlci1zbWFydGx5IHNwZWVkYmFyLWxhc3Qtc2VsZWN0ZWQtZmlsZSB0ZCBuZXdsIG9sZGxdIDYg KCMkIC4gMzA0ODExKV0pCiNANTQgRGVyaXZlIGFuZCBkaXNwbGF5IGluZm9ybWF0aW9uIGFib3V0 IHRoaXMgbGluZSBpdGVtLh8KKGRlZmFsaWFzICd2aGRsLXNwZWVkYmFyLWl0ZW0taW5mbyAjW25p bCAiXDIxMlwzMDN5XDIxMFwzMDRcMzA1IVwyMDMOAFwzMDNcMjI1YlwyMTBcMzA0XDMwNiFcMjAz HQBcMzA3XDMxMFwzMTEICVwiQFwiXDIxMFwzMDRcMzEyIVwyMDMoAFwzMTMgXDIwMlwyNDAAXDMw NFwzMTQhXDIwNVwyNDAAXDMwM1wyMjViXDIxMFwzMTVgXDMwMlwiGlwzMDdcMzE2XG5cMzE3PVwy MDRFAFxuXDMyMD1cMjAzSQBcMzIxXDIwMlwyMTIAXG5cMzIyPVwyMDRVAFxuXDMyMz1cMjAzWQBc MzI0XDIwMlwyMTIAXG5cMzI1PVwyMDRlAFxuXDMyNj1cMjAzaQBcMzI3XDIwMlwyMTIAXG5cMzMw PVwyMDR1AFxuXDMzMT1cMjAzeQBcMzMyXDIwMlwyMTIAXG5cMzMzPVwyMDRcMjA1AFxuXDMzND1c MjAzXDIxMQBcMzM1XDIwMlwyMTIAXDMzNlwzMzdgXDMwNFwzNDAhXDIxMFwzMDNcMjI1XCJcMzQx XDMxNWBcMzQyXCJAXDIwNlwyMzUAXDM0MyEkKSlcMjA3IiBbdmhkbC1wcm9qZWN0LWFsaXN0IHZo ZGwtcHJvamVjdCBmYWNlIDAgbG9va2luZy1hdCAiWzAtOV0rOiIgInA6IiBtZXNzYWdlICJQcm9q ZWN0IFwiJXNcIiIgYWdldCAiXFxzLSo8Wy0rP10+ICIgc3BlZWRiYXItZmlsZXMtaXRlbS1pbmZv ICJcXHMtKlxcKFtbe11bLSs/XVtdfV1cXHw+XFwpICIgZ2V0LXRleHQtcHJvcGVydHkgIiVzIFwi JXNcIiBpbiBcIiVzXCIiIHZoZGwtc3BlZWRiYXItZW50aXR5LWZhY2UgdmhkbC1zcGVlZGJhci1l bnRpdHktc2VsZWN0ZWQtZmFjZSAiRW50aXR5IiB2aGRsLXNwZWVkYmFyLWFyY2hpdGVjdHVyZS1m YWNlIHZoZGwtc3BlZWRiYXItYXJjaGl0ZWN0dXJlLXNlbGVjdGVkLWZhY2UgIkFyY2hpdGVjdHVy ZSIgdmhkbC1zcGVlZGJhci1jb25maWd1cmF0aW9uLWZhY2UgdmhkbC1zcGVlZGJhci1jb25maWd1 cmF0aW9uLXNlbGVjdGVkLWZhY2UgIkNvbmZpZ3VyYXRpb24iIHZoZGwtc3BlZWRiYXItcGFja2Fn ZS1mYWNlIHZoZGwtc3BlZWRiYXItcGFja2FnZS1zZWxlY3RlZC1mYWNlICJQYWNrYWdlIiB2aGRs LXNwZWVkYmFyLWluc3RhbnRpYXRpb24tZmFjZSB2aGRsLXNwZWVkYmFyLWluc3RhbnRpYXRpb24t c2VsZWN0ZWQtZmFjZSAiSW5zdGFudGlhdGlvbiIgIiIgYnVmZmVyLXN1YnN0cmluZy1uby1wcm9w ZXJ0aWVzICJcXChcXHdcXHxfXFwpKyIgYWJicmV2aWF0ZS1maWxlLW5hbWUgc3BlZWRiYXItdG9r ZW4gIj8iXSA4ICgjJCAuIDMwNTgyNildKQojQDQ2IFJlY3Vyc2l2ZWx5IGdldCBzdWJkaXJlY3Rv cmllcyBvZiBESVJFQ1RPUlkuHwooZGVmYWxpYXMgJ3ZoZGwtZ2V0LXN1YmRpcnMgI1soZGlyZWN0 b3J5KSAiXDMwNAghQ1wzMDVcMjExGRobXDMwNghcMzA3XDMxMCNcMjExEVwyMDMpAFwzMTEJQCFc MjAzXCIAXDMxMgtcMzEzCUAhXCITCUFcMjExEVwyMDQTAAsrXDIwNyIgW2RpcmVjdG9yeSBmaWxl LWxpc3Qgc3ViZGlyLWxpc3QgZGlyLWxpc3QgZmlsZS1uYW1lLWFzLWRpcmVjdG9yeSBuaWwgdmhk bC1kaXJlY3RvcnktZmlsZXMgdCAiXFx3LioiIGZpbGUtZGlyZWN0b3J5LXAgYXBwZW5kIHZoZGwt Z2V0LXN1YmRpcnNdIDUgKCMkIC4gMzA3MDkwKV0pCiNANjQgUmVzb2x2ZSBlbnZpcm9ubWVudCB2 YXJpYWJsZXMgYW5kIHBhdGggd2lsZGNhcmRzIGluIFBBVEgtTElTVC4fCihkZWZhbGlhcyAndmhk bC1yZXNvbHZlLXBhdGhzICNbKHBhdGgtbGlzdCkgIlwzMDZcMjExXDIxMVwyMTFcMjExXDIxMRgZ GhscHQ4cXDIwMzwADhxAEFwzMDdcMzEwCFwiXDIwMy8AXDMxMVwzMTIIXCJcMzEzXDMxMVwzMTQI XCIhXDMxMVwzMTUIXCJREFwyMDIVAAgNQhUOHEFcMjExFhxcMjA0EQANXDIwM2cADUAQXDMwN1wz MTYIXCJcMjEwXDMxN1wzMTFcMzE0CFwiIVwyMDNYAAhcZkIUXDIwMmAAXDMyMFwzMjFcMzExXDMx NAhcIlwiXDIxMA1BXDIxMRVcMjA0QABcZlwyMDNcMzMwAFxmQBBcMzA3XDMyMghcIlwyMDNcMjc3 AFwzMTFcMzEyCFwiElwzMTFcMzIzCFwiEVwzMjRcMzI1XDMyNlwzMjdcMzExXDMxNAhcIlwzMzBc MzMxXDMzMlwzMTFcMzE1CFwiIVAjXDMwNh4dXDIxMR4eXDIwM1wyNjMAXDMxNw4eQCFcMjAzXDI1 MgAOHkAOHUIWHQ4eQVwyMTEWHlwyMDRcMjMyAA4dKlwiXGZBXCJcMjExFFwyMDJoAFwzMDdcMzMz CFwiXDIxMFwzMTdcMzExXDMxNAhcIiFcMjAzXDMyMQAIC0ITXGZBXDIxMRRcMjA0awALLgZcMjA3 IiBbZGlyIHBhdGgtZW5kIHBhdGgtYmVnIHBhdGgtbGlzdC0zIHBhdGgtbGlzdC0yIHBhdGgtbGlz dC0xIG5pbCBzdHJpbmctbWF0Y2ggIlxcKC4qXFwpJHs/XFwoXFwoXFx3XFx8X1xcKStcXCl9P1xc KC4qXFwpIiBtYXRjaC1zdHJpbmcgMSBnZXRlbnYgMiA0ICJcXCgtciBcXCk/XFwoXFwoW14/Kl0q L1xcKSpcXCkiIGZpbGUtZGlyZWN0b3J5LXAgbWVzc2FnZSAiTm8gc3VjaCBkaXJlY3Rvcnk6IFwi JXNcIiIgIlxcKC1yIFxcKT9cXChcXChbXj8qXSovXFwpKlxcKVxcKFteL10qWz8qXVteL10qXFwp XFwoLy4qXFwpIiA1IGFwcGVuZCBtYXBjYXIgI1sodmFyKSAiCAlcblFcMjA3IiBbcGF0aC1iZWcg dmFyIHBhdGgtZW5kXSAzXSB2aGRsLWRpcmVjdG9yeS1maWxlcyB0ICJcXDwiIHdpbGRjYXJkLXRv LXJlZ2V4cCAiXFwoLXIgXFwpP1xcKC4qXFwpLy4qIiBwYXRoLWxpc3QgZGlyLWxpc3QgYWxsLWxp c3RdIDEyICgjJCAuIDMwNzQzNyldKQojQDExMSBBcHBlbmQgYSBrZXktdmFsdWUgcGFpciB0byBh biBhbGlzdC4KU2ltaWxhciB0byBgYXB1dCcgYnV0IG1vdmVzIHRoZSBrZXktdmFsdWUgcGFpciB0 byB0aGUgdGFpbCBvZiB0aGUgYWxpc3QuHwooZGVmYWxpYXMgJ3ZoZGwtYWFwcGVuZCAjWyhhbGlz dC1zeW1ib2wga2V5IHZhbHVlKSAiXDMwNQgJXCJcMzA2XG4IXCIbHFxuXDMwNwtcZlwiTCpcMjA3 IiBba2V5IHZhbHVlIGFsaXN0LXN5bWJvbCBhbGlzdCBlbGVtIGFlbGVtZW50IGFkZWxldGUgYXBw ZW5kXSA0ICgjJCAuIDMwODUxMyldKQojQDc1IElmIFVOSVQgaXMgZGlzcGxheWVkIGluIERJUkVD VE9SWSwgZ290byB0aGlzIGxpbmUgYW5kIHJldHVybiB0LCBlbHNlIG5pbC4fCihkZWZhbGlhcyAn dmhkbC1zcGVlZGJhci1nb3RvLXRoaXMtdW5pdCAjWyhkaXJlY3RvcnkgdW5pdCkgImAYXDMwNQlc blwiQUBcMjAzEQBlYlwyMTBcMjAyFwBcMzA2CyFcMjAzKQBcMzA3XDMxMFxmXDMxMVFcMzEyXDMx MyNcMjAzKQBcMzE0IFwyMTBcMzEzXDIwMi0ACGJcMjEwXDMxMilcMjA3IiBbZGVzdCB2aGRsLXBy b2plY3QtYWxpc3QgdmhkbC1wcm9qZWN0IGRpcmVjdG9yeSB1bml0IGFnZXQgc3BlZWRiYXItZ290 by10aGlzLWZpbGUgcmUtc2VhcmNoLWZvcndhcmQgIltdfV0gIiAiXFw+IiBuaWwgdCBzcGVlZGJh ci1wb3NpdGlvbi1jdXJzb3Itb24tbGluZV0gNCAoIyQgLiAzMDg3OTcpXSkKI0A3MCBXaGVuIHVz ZXIgY2xpY2tzIG9uIFRFWFQsIGxvYWQgZmlsZSB3aXRoIG5hbWUgYW5kIHBvc2l0aW9uIGluIFRP S0VOLh8KKGRlZmFsaWFzICd2aGRsLXNwZWVkYmFyLWZpbmQtZmlsZSAjWyh0ZXh0IHRva2VuIGlu ZGVudCkgIghAXDIwNAkAXDMwMlwzMDMhXDIwN1wzMDQIQCFcMjEwXDMwNQhBIVwyMTBcMzA2IFwy MTBcMzA3XDMxMCFcMjEwXDMxMQkhXDIxMFwzMTIgXDIwNyIgW3Rva2VuIHNwZWVkYmFyLXVwZGF0 ZS1zcGVlZCBlcnJvciAiRGVzaWduIHVuaXQgZG9lcyBub3QgZXhpc3QiIHNwZWVkYmFyLWZpbmQt ZmlsZS1pbi1mcmFtZSBnb3RvLWxpbmUgcmVjZW50ZXIgdmhkbC1zcGVlZGJhci11cGRhdGUtY3Vy cmVudC11bml0IHQgc3BlZWRiYXItc2V0LXRpbWVyIHNwZWVkYmFyLW1heWJlZS1qdW1wLXRvLWF0 dGFjaGVkLWZyYW1lXSAyICgjJCAuIDMwOTIxOCldKQojQDUwIFRvZ2dsZSBiZXR3ZWVuIGhpZXJh cmNoeSBhbmQgZmlsZSBicm93c2luZyBtb2RlLh8KKGRlZmFsaWFzICd2aGRsLXNwZWVkYmFyLXRv Z2dsZS1oaWVyYXJjaHkgI1tuaWwgIlwzMDFcMzAyIVwyMDRcbgBcMzAzXDMwNCFcMjA3CFwzMDVc MjMyXDIwMxQAXDMwNlwzMDchXDIwN1wzMDZcMzA1IVwyMDciIFtzcGVlZGJhci1pbml0aWFsLWV4 cGFuc2lvbi1saXN0LW5hbWUgYm91bmRwIHNwZWVkYmFyLW1vZGUtZnVuY3Rpb25zLWxpc3QgZXJy b3IgIldBUk5JTkc6ICBJbnN0YWxsIGluY2x1ZGVkIGBzcGVlZGJhci5lbCcgcGF0Y2ggZmlyc3Qi ICJ2aGRsIGhpZXJhcmNoeSIgc3BlZWRiYXItY2hhbmdlLWluaXRpYWwtZXhwYW5zaW9uLWxpc3Qg ImZpbGVzIl0gMiAoIyQgLiAzMDk2NjEpIG5pbF0pCiNANDcgQ29weSB0aGUgcG9ydCBvZiB0aGUg ZW50aXR5IHVuZGVyIHRoZSBjdXJzb3IuHwooZGVmYWxpYXMgJ3ZoZGwtc3BlZWRiYXItcG9ydC1j b3B5ICNbbmlsICJcMzAweVwyMTBcMzAxXDMwMlwyMTJcMzAzf1wyMTBgKVwzMDQjXDIwMxUAXDMw M1wzMDVcMzA2XDIxN1wyMDdcMzA3XDMxMCFcMjA3IiBbMCByZS1zZWFyY2gtZm9yd2FyZCAiXFwo WzAtOV1cXCkrOlxccy0qXFxbWy0rP11cXF0gXFwoXFwoXFx3XFx8XFxzX1xcKStcXCkiIG5pbCB0 IChieXRlLWNvZGUgIlwzMDZcMzA3XDMxMCEhGFwzMDdcMzExIRlcMzEyXG4LXCJBQFwyMDMaAFwz MTJcZgtcIlwyMDIkAFwzMTINXDMxM1wzMTRcMzE1CCEhIVwiHh1cMzEyDh0JXCJcMjExHh5AHh9c MzE2HiBcMzE3Dh8hXDIwM0QAXDMyMA4fIXFcMjEwXDIwMmQAXDMyMQ4fXDMxNlwzMjIjcVwyMTBc MzIzXDMyNFwzMjVcMzI2ICNcMjEwXDMyM1wzMjdcMzMwXDMyNiAjXDIxMFwzMjNcMzMxXDMzMFwz MjYgI1wyMTBcMzIyFiBcMzMyDh5BQCFcMjEwXDMxNn9cMjEwXDMzMyBcMjEwDiBcMjA1eQBcMzM0 cCEuBlwyMDciIFtpbmRlbnQgZW50LW5hbWUgdmhkbC1wcm9qZWN0LWFsaXN0IHZoZGwtcHJvamVj dCB2aGRsLXByb2plY3QtZW50aXR5LWFsaXN0IHZoZGwtZW50aXR5LWFsaXN0IHN0cmluZy10by1u dW1iZXIgbWF0Y2gtc3RyaW5nIDEgMiBhZ2V0IGFiYnJldmlhdGUtZmlsZS1uYW1lIGZpbGUtbmFt ZS1hcy1kaXJlY3Rvcnkgc3BlZWRiYXItbGluZS1wYXRoIG5pbCBmaW5kLWJ1ZmZlci12aXNpdGlu ZyBmaWxlLW5hbWUtbm9uZGlyZWN0b3J5IGZpbmQtZmlsZS1ub3NlbGVjdCB0IG1vZGlmeS1zeW50 YXgtZW50cnkgNDUgIi4gMTIiIHN5bnRheC10YWJsZSAxMCAiPiIgMTMgZ290by1saW5lIHZoZGwt cG9ydC1jb3B5IGtpbGwtYnVmZmVyIGVudC1hbGlzdCBlbnQtZW50cnkgZmlsZS1uYW1lIG9wZW5l ZF0gNykgKChlcnJvciAoZXJyb3IgIlBvcnQgbm90IHNjYW5uZWQgc3VjY2Vzc2Z1bGx5IikpKSBl cnJvciAiTm8gZW50aXR5IG9uIGN1cnJlbnQgbGluZSJdIDQgKCMkIC4gMzEwMDU5KSBuaWxdKQoo Ynl0ZS1jb2RlICJcMzAxXDMwMlwzMDNcMzA0CFwzMDUlXDIxMFwzMDFcMzA2XDMwN1wzMTAIXDMw NSVcMjEwXDMwMVwzMTFcMzEyXDMxMwhcMzA1JVwyMTBcMzAxXDMxNFwzMTVcMzE2CFwzMDUlXDIx MFwzMDFcMzE3XDMyMFwzMjEIXDMwNSVcMjEwXDMwMVwzMjJcMzIzXDMwNAhcMzA1JVwyMTBcMzAx XDMyNFwzMjVcMzEwCFwzMDUlXDIxMFwzMDFcMzI2XDMyN1wzMTMIXDMwNSVcMjEwXDMwMVwzMzBc MzMxXDMxNghcMzA1JVwyMTBcMzAxXDMzMlwzMzNcMzIxCFwzMDUlXDIwNyIgWzpncm91cCBjdXN0 b20tZGVjbGFyZS1mYWNlIHZoZGwtc3BlZWRiYXItZW50aXR5LWZhY2UgKCgoKGNsYXNzIGNvbG9y KSAoYmFja2dyb3VuZCBsaWdodCkpICg6Zm9yZWdyb3VuZCAiRm9yZXN0R3JlZW4iKSkgKCgoY2xh c3MgY29sb3IpIChiYWNrZ3JvdW5kIGRhcmspKSAoOmZvcmVncm91bmQgIlBhbGVHcmVlbiIpKSkg IkZhY2UgdXNlZCBmb3IgZGlzcGxheWluZyBlbnRpdHkgbmFtZXMuIiBzcGVlZGJhci1mYWNlcyB2 aGRsLXNwZWVkYmFyLWFyY2hpdGVjdHVyZS1mYWNlICgoKChjbGFzcyBjb2xvcikgKGJhY2tncm91 bmQgbGlnaHQpKSAoOmZvcmVncm91bmQgIkJsdWUiKSkgKCgoY2xhc3MgY29sb3IpIChiYWNrZ3Jv dW5kIGRhcmspKSAoOmZvcmVncm91bmQgIkxpZ2h0U2t5Qmx1ZSIpKSkgIkZhY2UgdXNlZCBmb3Ig ZGlzcGxheWluZyBhcmNoaXRlY3R1cmUgbmFtZXMuIiB2aGRsLXNwZWVkYmFyLWNvbmZpZ3VyYXRp b24tZmFjZSAoKCgoY2xhc3MgY29sb3IpIChiYWNrZ3JvdW5kIGxpZ2h0KSkgKDpmb3JlZ3JvdW5k ICJEYXJrR29sZGVucm9kIikpICgoKGNsYXNzIGNvbG9yKSAoYmFja2dyb3VuZCBkYXJrKSkgKDpm b3JlZ3JvdW5kICJTYWxtb24iKSkpICJGYWNlIHVzZWQgZm9yIGRpc3BsYXlpbmcgY29uZmlndXJh dGlvbiBuYW1lcy4iIHZoZGwtc3BlZWRiYXItcGFja2FnZS1mYWNlICgoKChjbGFzcyBjb2xvcikg KGJhY2tncm91bmQgbGlnaHQpKSAoOmZvcmVncm91bmQgIkdyZXk1MCIpKSAoKChjbGFzcyBjb2xv cikgKGJhY2tncm91bmQgZGFyaykpICg6Zm9yZWdyb3VuZCAiR3JleTgwIikpKSAiRmFjZSB1c2Vk IGZvciBkaXNwbGF5aW5nIHBhY2thZ2UgbmFtZXMuIiB2aGRsLXNwZWVkYmFyLWluc3RhbnRpYXRp b24tZmFjZSAoKCgoY2xhc3MgY29sb3IpIChiYWNrZ3JvdW5kIGxpZ2h0KSkgKDpmb3JlZ3JvdW5k ICJCcm93biIpKSAoKChjbGFzcyBjb2xvcikgKGJhY2tncm91bmQgZGFyaykpICg6Zm9yZWdyb3Vu ZCAiWWVsbG93IikpKSAiRmFjZSB1c2VkIGZvciBkaXNwbGF5aW5nIGluc3RhbnRpYXRpb24gbmFt ZXMuIiB2aGRsLXNwZWVkYmFyLWVudGl0eS1zZWxlY3RlZC1mYWNlICgoKChjbGFzcyBjb2xvcikg KGJhY2tncm91bmQgbGlnaHQpKSAoOmZvcmVncm91bmQgIkZvcmVzdEdyZWVuIiA6dW5kZXJsaW5l IHQpKSAoKChjbGFzcyBjb2xvcikgKGJhY2tncm91bmQgZGFyaykpICg6Zm9yZWdyb3VuZCAiUGFs ZUdyZWVuIiA6dW5kZXJsaW5lIHQpKSkgdmhkbC1zcGVlZGJhci1hcmNoaXRlY3R1cmUtc2VsZWN0 ZWQtZmFjZSAoKCgoY2xhc3MgY29sb3IpIChiYWNrZ3JvdW5kIGxpZ2h0KSkgKDpmb3JlZ3JvdW5k ICJCbHVlIiA6dW5kZXJsaW5lIHQpKSAoKChjbGFzcyBjb2xvcikgKGJhY2tncm91bmQgZGFyaykp ICg6Zm9yZWdyb3VuZCAiTGlnaHRTa3lCbHVlIiA6dW5kZXJsaW5lIHQpKSkgdmhkbC1zcGVlZGJh ci1jb25maWd1cmF0aW9uLXNlbGVjdGVkLWZhY2UgKCgoKGNsYXNzIGNvbG9yKSAoYmFja2dyb3Vu ZCBsaWdodCkpICg6Zm9yZWdyb3VuZCAiRGFya0dvbGRlbnJvZCIgOnVuZGVybGluZSB0KSkgKCgo Y2xhc3MgY29sb3IpIChiYWNrZ3JvdW5kIGRhcmspKSAoOmZvcmVncm91bmQgIlNhbG1vbiIgOnVu ZGVybGluZSB0KSkpIHZoZGwtc3BlZWRiYXItcGFja2FnZS1zZWxlY3RlZC1mYWNlICgoKChjbGFz cyBjb2xvcikgKGJhY2tncm91bmQgbGlnaHQpKSAoOmZvcmVncm91bmQgIkdyZXk1MCIgOnVuZGVy bGluZSB0KSkgKCgoY2xhc3MgY29sb3IpIChiYWNrZ3JvdW5kIGRhcmspKSAoOmZvcmVncm91bmQg IkdyZXk4MCIgOnVuZGVybGluZSB0KSkpIHZoZGwtc3BlZWRiYXItaW5zdGFudGlhdGlvbi1zZWxl Y3RlZC1mYWNlICgoKChjbGFzcyBjb2xvcikgKGJhY2tncm91bmQgbGlnaHQpKSAoOmZvcmVncm91 bmQgIkJyb3duIiA6dW5kZXJsaW5lIHQpKSAoKChjbGFzcyBjb2xvcikgKGJhY2tncm91bmQgZGFy aykpICg6Zm9yZWdyb3VuZCAiWWVsbG93IiA6dW5kZXJsaW5lIHQpKSldIDYpCiNAMzYgQWRkcmVz cyBmb3IgVkhETCBNb2RlIGJ1ZyByZXBvcnRzLh8KKGRlZmNvbnN0IHZoZGwtbW9kZS1oZWxwLWFk ZHJlc3MgInZoZGwtbW9kZUBnZW9jaXRpZXMuY29tIiAoIyQgLiAzMTMzODApKQojQDU4IEVjaG8g dGhlIGN1cnJlbnQgdmVyc2lvbiBvZiBWSERMIE1vZGUgaW4gdGhlIG1pbmlidWZmZXIuHwooZGVm YWxpYXMgJ3ZoZGwtdmVyc2lvbiAjW25pbCAiXDMwMVwzMDIIXCJcMjEwXDMwMyBcMjA3IiBbdmhk bC12ZXJzaW9uIG1lc3NhZ2UgIlVzaW5nIFZIREwgTW9kZSB2ZXJzaW9uICVzIiB2aGRsLWtlZXAt cmVnaW9uLWFjdGl2ZV0gMyAoIyQgLiAzMTM0OTUpIG5pbF0pCiNANDQgU3VibWl0IHZpYSBtYWls IGEgYnVnIHJlcG9ydCBvbiBWSERMIE1vZGUuHwooZGVmYWxpYXMgJ3ZoZGwtc3VibWl0LWJ1Zy1y ZXBvcnQgI1tuaWwgIlwzMDJcMzAzIVwyMDVcMjUyAFwzMDRcMzA1IVwyMDVcMjUyAFwzMDYIXDMw NwlQXDMxMFwzMTFcMzEyXDMxM1wzMTRcMzE1XDMxNlwzMTdcMzIwXDMyMVwzMjJcMzIzXDMyNFwz MjVcMzI2XDMyN1wzMzBcMzMxXDMzMlwzMzNcMzM0XDMzNVwzMzZcMzM3XDM0MFwzNDFcMzQyXDM0 M1wzNDRcMzQ1XDM0NlwzNDdcMzUwXDM1MVwzNTJcMzUzXDM1NFwzNTVcMzU2XDM1N1wzNjBcMzYx XDM2MlwzNjNcMzY0XDM2NVwzNjZcMzY3XDM3MFwzNzFcMzcyXDM3M1wzNzRcMzc1XDM3NlwzNzdc MjAxQABcMjAxQQBcMjAxQgBcMjAxQwBcMjAxRABcMjAxRQBcMjAxRgBcMjAxRwBcMjAxSABcMjAx SQBcMjAxSgBcMjAxSwBcMjAxTABcMjAxTQBcMjAxTgBcMjAxTwBcMjAxUABcMjAxUQBcMjAxUgBc MjAxUwBcMjAxVABcMjAxVQBcMjAxVgBcMjAxVwBcMjAxWABcMjAxWQBcMjAxWgBcMjAxWwBcMjU3 VFwyMDFcXABcMjAxXQBcMjAxXgAmBlwyMDciIFt2aGRsLW1vZGUtaGVscC1hZGRyZXNzIHZoZGwt dmVyc2lvbiB5LW9yLW4tcCAiRG8geW91IHdhbnQgdG8gc3VibWl0IGEgcmVwb3J0IG9uIFZIREwg TW9kZT8gIiByZXF1aXJlIHJlcG9ydGVyIHJlcG9ydGVyLXN1Ym1pdC1idWctcmVwb3J0ICJWSERM IE1vZGUgIiB2aGRsLW9mZnNldHMtYWxpc3QgdmhkbC1jb21tZW50LW9ubHktbGluZS1vZmZzZXQg dGFiLXdpZHRoIHZoZGwtZWxlY3RyaWMtbW9kZSB2aGRsLXN0dXR0ZXItbW9kZSB2aGRsLWluZGVu dC10YWJzLW1vZGUgdmhkbC1wcm9qZWN0LWFsaXN0IHZoZGwtcHJvamVjdCB2aGRsLWNvbXBpbGVy LWFsaXN0IHZoZGwtY29tcGlsZXIgdmhkbC1jb21waWxlci1vcHRpb25zIHZoZGwtc3RhbmRhcmQg dmhkbC1iYXNpYy1vZmZzZXQgdmhkbC11cHBlci1jYXNlLWtleXdvcmRzIHZoZGwtdXBwZXItY2Fz ZS10eXBlcyB2aGRsLXVwcGVyLWNhc2UtYXR0cmlidXRlcyB2aGRsLXVwcGVyLWNhc2UtZW51bS12 YWx1ZXMgdmhkbC11cHBlci1jYXNlLWNvbnN0YW50cyB2aGRsLWVsZWN0cmljLWtleXdvcmRzIHZo ZGwtb3B0aW9uYWwtbGFiZWxzIHZoZGwtaW5zZXJ0LWVtcHR5LWxpbmVzIHZoZGwtYXJndW1lbnQt bGlzdC1pbmRlbnQgdmhkbC1hc3NvY2lhdGlvbi1saXN0LXdpdGgtZm9ybWFscyB2aGRsLWNvbmRp dGlvbnMtaW4tcGFyZW50aGVzaXMgdmhkbC16ZXJvLXN0cmluZyB2aGRsLW9uZS1zdHJpbmcgdmhk bC1maWxlLWhlYWRlciB2aGRsLWZpbGUtZm9vdGVyIHZoZGwtY29tcGFueS1uYW1lIHZoZGwtcGxh dGZvcm0tc3BlYyB2aGRsLWRhdGUtZm9ybWF0IHZoZGwtbW9kaWZ5LWRhdGUtcHJlZml4LXN0cmlu ZyB2aGRsLW1vZGlmeS1kYXRlLW9uLXNhdmluZyB2aGRsLXJlc2V0LWtpbmQgdmhkbC1yZXNldC1h Y3RpdmUtaGlnaCB2aGRsLWNsb2NrLXJpc2luZy1lZGdlIHZoZGwtY2xvY2stZWRnZS1jb25kaXRp b24gdmhkbC1jbG9jay1uYW1lIHZoZGwtcmVzZXQtbmFtZSB2aGRsLW1vZGVsLWFsaXN0IHZoZGwt aW5jbHVkZS1wb3J0LWNvbW1lbnRzIHZoZGwtaW5jbHVkZS1kaXJlY3Rpb24tY29tbWVudHMgdmhk bC1hY3R1YWwtcG9ydC1uYW1lIHZoZGwtaW5zdGFuY2UtbmFtZSB2aGRsLXRlc3RiZW5jaC1lbnRp dHktbmFtZSB2aGRsLXRlc3RiZW5jaC1hcmNoaXRlY3R1cmUtbmFtZSB2aGRsLXRlc3RiZW5jaC1k dXQtbmFtZSB2aGRsLXRlc3RiZW5jaC1lbnRpdHktaGVhZGVyIHZoZGwtdGVzdGJlbmNoLWFyY2hp dGVjdHVyZS1oZWFkZXIgdmhkbC10ZXN0YmVuY2gtZGVjbGFyYXRpb25zIHZoZGwtdGVzdGJlbmNo LXN0YXRlbWVudHMgdmhkbC10ZXN0YmVuY2gtaW5pdGlhbGl6ZS1zaWduYWxzIHZoZGwtdGVzdGJl bmNoLWNyZWF0ZS1maWxlcyB2aGRsLXNlbGYtaW5zZXJ0LWNvbW1lbnRzIHZoZGwtcHJvbXB0LWZv ci1jb21tZW50cyB2aGRsLWlubGluZS1jb21tZW50LWNvbHVtbiB2aGRsLWVuZC1jb21tZW50LWNv bHVtbiB2aGRsLWF1dG8tYWxpZ24gdmhkbC1hbGlnbi1ncm91cHMgdmhkbC1oaWdobGlnaHQta2V5 d29yZHMgdmhkbC1oaWdobGlnaHQtbmFtZXMgdmhkbC1oaWdobGlnaHQtc3BlY2lhbC13b3JkcyB2 aGRsLWhpZ2hsaWdodC1mb3JiaWRkZW4td29yZHMgdmhkbC1oaWdobGlnaHQtdmVyaWxvZy1rZXl3 b3JkcyB2aGRsLWhpZ2hsaWdodC10cmFuc2xhdGUtb2ZmIHZoZGwtaGlnaGxpZ2h0LWNhc2Utc2Vu c2l0aXZlIHZoZGwtc3BlY2lhbC1zeW50YXgtYWxpc3QgdmhkbC1mb3JiaWRkZW4td29yZHMgdmhk bC1mb3JiaWRkZW4tc3ludGF4IHZoZGwtc3BlZWRiYXIgdmhkbC1zcGVlZGJhci1zaG93LWhpZXJh cmNoeSB2aGRsLXNwZWVkYmFyLWhpZXJhcmNoeS1pbmRlbnQgdmhkbC1pbmRleC1tZW51IHZoZGwt c291cmNlLWZpbGUtbWVudSB2aGRsLWhpZGVzaG93LW1lbnUgdmhkbC1oaWRlLWFsbC1pbml0IHZo ZGwtcHJpbnQtdHdvLWNvbHVtbiB2aGRsLXByaW50LWN1c3RvbWl6ZS1mYWNlcyB2aGRsLWludGVs bGlnZW50LXRhYiB2aGRsLXdvcmQtY29tcGxldGlvbi1jYXNlLXNlbnNpdGl2ZSB2aGRsLXdvcmQt Y29tcGxldGlvbi1pbi1taW5pYnVmZmVyIHZoZGwtdW5kZXJzY29yZS1pcy1wYXJ0LW9mLXdvcmQg dmhkbC1tb2RlLWhvb2sgdmhkbC1zdGFydHVwLXdhcm5pbmdzICNbbmlsICIIXDIwMxEAXDMwMVwz MDJcMzAzXDMwNAhcIlwzMDVcMzA2XDI2MAVcMjAyEgBcMzA3Y1wyMDciIFt2aGRsLXNwZWNpYWwt aW5kZW50LWhvb2sgIlxuQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAXG4iICJ2aGRs LXNwZWNpYWwtaW5kZW50LWhvb2sgaXMgc2V0IHRvICciIGZvcm1hdCAiJXMiICIuXG5QZXJoYXBz IHRoaXMgaXMgeW91ciBwcm9ibGVtP1xuIiAiQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA QEBAXG5cbiIgIlxuIl0gNV0gbmlsICJEZWFyIFZIREwgTW9kZSBtYWludGFpbmVycywiXSA4NyAo IyQgLiAzMTM3MTMpIG5pbF0pCihwcm92aWRlICd2aGRsLW1vZGUpCg== ------=_Part_252221_12725027.1199450567569 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ help-gnu-emacs mailing list help-gnu-emacs@gnu.org http://lists.gnu.org/mailman/listinfo/help-gnu-emacs ------=_Part_252221_12725027.1199450567569--