From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Michael Kerrisk (man-pages)" Subject: Re: richacl(7) man page review comments Date: Sun, 14 Feb 2016 22:31:40 +0100 Message-ID: <56C0F23C.7030902@gmail.com> References: <56B770B6.7040803@gmail.com> <56B77262.7090107@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: QUOTED-PRINTABLE Return-path: In-Reply-To: Sender: linux-cifs-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org To: Andreas Gruenbacher Cc: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org, "J. Bruce Fields" , linux-ext4 , XFS Developers , lkml , linux-fsdevel , Linux NFS Mailing List , linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux API , Dave Chinner , Christoph Hellwig , Anna Schumaker , Trond Myklebust , Jeff Layton , Andreas Dilger List-Id: linux-api@vger.kernel.org Hi Andreas, Here's a few more comments on the current richacl(7) page that I fetched from the git repo. > .\" > .\" RichACL Manual Pages > .\" > .\" Copyright (C) 2015,2016 Red Hat, Inc. > .\" Written by Andreas Gruenbacher > .\" This is free documentation; 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 of > .\" the License, or (at your option) any later version. > .\" > .\" The GNU General Public License's references to "object code" > .\" and "executables" are to be interpreted as the output of any > .\" document formatting or typesetting system, including > .\" intermediate and printed output. > .\" > .\" This manual 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 this manual. If not, see > .\" . > .\" > .de URL > \\$2 \(laURL: \\$1 \(ra\\$3 > .. > .if \n[.g] .mso www.tmac > .TH RICHACL 7 2015-09-01 "Linux" "Rich Access Control Lists" > .SH NAME > richacl \- Rich Access Control Lists > .SH DESCRIPTION > Rich Access Control Lists (RichACLs) are an extension of the POSIX fi= le > permission model (see > .BR acl (5)) > to support > .URL https://tools.ietf.org/rfc/rfc5661.txt "NFSv4 Access Control Lis= ts" > on local and remote-mounted filesystems. Having read the following paragraph a number of times (and being ignorant of NFS ACLs), I find that I'm none the wiser about what you ar= e trying to say. What does it mean to "apply a file mode to an... ACL"? Likewise, how does "the file mode determine the values of the file masks"? This isn't clear in the following paragraph, and doesn't seem t= o be alborated in the rest of the page. Could you add some text somehwere to explain these points? > RichACLs support file masks which can be used to apply a file mode to= an existing > NFSv4 ACL without destructive side effects: the file mode determines = the values > of the file masks; the file masks restrict the permissions granted by= the NFSv4 > ACL. When a less restrictive file mode is applied later, the file ma= sks become > less restrictive, and more of the original permissions can become eff= ective. >=20 > A RichACL can always be translated into an equivalent NFSv4 ACL which= grants > the same permissions. >=20 > RichACLs can be enabled on supported filesystems. This disables POSIX= Access I think it might be helpful here to list which filesystems so far support RichACLs. > Control Lists; the two ACL models cannot coexist on the same filesyst= em. >=20 > When used on a filesystem that does not support RichACLs, the > .BR getrichacl (1) > and > .BR setrichacl (1) > utilities will operate on the file permission bits instead: > .BR getrichacl (1) > will display the file permission bits as a RichACL; when a RichACL > is set with > .BR setrichacl (1) > which can be represented exactly by the file permission bits, > .BR setrichacl (1) > will set the file permission bits instead. An attempt to set a RichA= CL that > cannot be represented exactly by the file permission bits results in = an error. >=20 > .SS Structure of RichACLs >=20 > RichACLs consist of a number of ACL entries, three file masks, and so= me flags > specifying attributes of the ACL as whole (by contrast with the per-A= CL-entry > flags described below). Insert a blank line here, to start a new paragraph. > Each of the ACL entries allows or denies some permissions to a partic= ular user, > group, or special entity. Each entry consists of: In the previous line you write "entity". In the lines below you use "identifier". The terminology switch is confusing. Use just one term. =20 > .IP \(bu 4 > A tag which specifies the user (with prefix > .B user: > or > .BR u: ), > group (with prefix > .B group: > or > .BR g: ), > or special identifier the entry applies to. Special > identifiers can be the file owner > .RB ( owner@ ), > the owning group > .RB ( group@ ), > or everyone > .RB ( everyone@ ). > .IP \(bu > A set of permissions the entry allows or denies. > .IP \(bu > A set of flags that indicate whether the user or group identifier is = mapped or > unmapped, and whether the entry has been and can be inherited. > .IP \(bu 4 > A field indicating whether the entry allows or denies access. Does this field have a name? It would make dicussing it easier to give it a name. That is, an ACL entry consists of four fields: * a tag * permissions * flags * ??? ("type"?) > .PP > The owner, group, and other file masks further control which permissi= ons the > ACL grants, subject to the > .BR masked "\ (" m ) > and > .BR write_through "\ (" w ) > ACL flags. >=20 > Note that entries with the identifier > .B everyone@ > apply to all processes, whereas the \(lqother\(rq file permissions an= d > \(lqother\(rq entries in POSIX ACLs apply to all processes which are = not the > owner, are not in the owning group, and do not match a user or group = mentioned > in the ACL. >=20 > Unlike POSIX ACLs, RichACLs do not have separate \(lqaccess\(rq ACLs = that > define the access permissions and \(lqdefault\(rq ACLs that define th= e > inheritable permissions. Instead, flags on each ACL entry determine = whether > the entry is effective during access checks and/or inheritable. >=20 >=20 > .SS ACL flags >=20 > The following flags on ACLs are defined: >=20 > .RS > .HP I don't think the heavy indentation here is helpful, and it narrors the text considerably. I suggest replacing the preceding .RS+.HP with .TP, and changing ewach .HP below to .TP, and remove the colon at the end of each line that follows the .TP lines. > .BR masked "\ (" m ): > When set, the file masks define upper limits on the permissions the A= CL may > grant. > .HP > .BR write_through "\ (" w ): > When this flag and the > .B masked > flag are both set, the owner and other file masks define the actual p= ermissions > granted to the file owner and to others instead of an upper limit. There needs to be a statement here about what 'write_through' does if 'masked' is not set. > .HP > .BR auto_inherit "\ (" a ): > Automatic Inheritance is enabled for the file the ACL is > attached to. See > .IR "Automatic Inheritance" . > .HP > .BR protected "\ (" p ): > The ACL is protected from modification by Automatic > Inheritance. > .HP > .BR defaulted "\ (" d ): > The ACL has been assigned by default. Automatic Inheritance should co= mpletely What does "assigned by default" mean? That it was inherited because of 'dir_inherit' or 'file_inherit' in the pareent directory? This needs to be clearer. > replace the ACL. > .RE If you follow my suggestion above, delete the preceding .RE > .SS ACL entry flags >=20 > The following flags on ACL entries are defined: >=20 > .RS > .HP See above. Possibly change .RS+.HP to .TP > .BR file_inherit "\ (" f ): > The entry is inheritable for files. Maybe this would be better as: "When this flag appears in the ACL entry of a directory, then that entr= y is inherited by new files created in the directory." Is that text that I propose correct? > .HP > .BR dir_inherit "\ (" d ): > The entry is inheritable for directories. "When this flag appears in the ACL entry of a directory, then that entr= y is inherited by new subdirectories created in the directory." Is that text that I propose correct? > .HP > .BR no_propagate "\ (" n ): > Inheritance stops at the next subdirectory level. > .HP > .BR inherit_only "\ (" i ): > The entry defines inheritable permissions only and is ignored for acc= ess > checking. > .HP > .BR inherited "\ (" a ): > The entry has been automatically inherited from the parent directory;= the > ACL's > .B auto_inherit > flag should be on. > .HP > .BR unmapped "\ (" u ): > The user or group identifier is a textual string and is not mapped to= a numeric > user or group identifier. ACLs with unmapped identifiers can occur o= n NFSv4 > mounted filesystems when the client cannot determine numeric user or = group > identifiers for some of the NFSv4 user@domain or group@domain who val= ues. They > cannot be assigned to local files or directories. > .RE If you follow my suggestion above, delete the preceding .RE >=20 > .SS Permissions >=20 > The following permissions are defined for RichACL entries and for the= three > file masks: >=20 > .RS > .HP See above. Possibly change .RS+.HP yo .TP > .BR read_data " / " list_directory "\ (" r ): > For a file: read the data of the file. > For a directory: list the contents of the directory. > .HP > .BR write_data " / " add_file "\ (" w ): > For a file: modify the data of the file; does not include opening the= file in > append mode. > For a directory: add a new file in the directory. > .HP > .BR append_data " / " add_subdirectory "\ (" p ): > For a file: open the file in append mode. > For a directory: create a subdirectory in the directory. > .HP > .BR execute "\ (" x ): > For a file: execute the file. > For a directory: traverse / search the directory. > .HP > .BR delete_child "\ (" d ): > Delete a file or directory within a directory. > .HP > .BR delete "\ (" D ): > Delete the file or directory. > .HP > .BR read_attributes "\ (" a ): > Read basic attributes of a file or directory (see > .BR stat (2)). > This permission is always implicitly granted. So, can this permission ever be taken away? If yes, say so. If not, why does this permission exist? (And maybe say something about that.) > .HP > .BR write_attributes "\ (" A ): > Change the times associated with a file or directory to an arbitrary = value. > This permission is always implicitly granted to the file owner. > .HP > .BR read_acl "\ (" c ): > Read the ACL of a file or directory. This permission is always > implicitly granted. > .HP > .BR write_acl "\ (" C ): > Change the ACL or file mode of a file or directory. > .HP > .BR write_owner "\ (" o ): > Take ownership of a file or directory. Change the owning group of a = file or > directory to a group of which the calling process is a member. > .HP > .BR read_named_attrs "\ (" R ), > .BR write_named_attrs "\ (" W ), > .BR synchronize "\ (" S ), > .BR write_retention "\ (" e ), > .BR write_retention_hold "\ (" E ): If you follow my .TP suggestion above, then the above lines would need to be rewritten sometinh like: =2EBR read_named_attrs "\ (" R "), " write_named_attrs "\ (" W "), " \ synchronize "\ (" S "), " write_retention "\ (" e "), " \ write_retention_hold "\ (" E ) > These permissions are defined by NFSv4 / NFSv4.1. They can be stored= , but are > not used. > .RE If you follow my suggestion above, delete the preceding .RE and add .PP >=20 > For the > .BR r ", " w ", and " p > permissions which have different long forms for files and directories= , the > .BR getrichacl (1) > utility will output the appropriate form(s) depending on the context. > The > .BR setrichacl (1) > utility will accept either form for any file type. >=20 > .SS Text form > The common textual representation of a RichACL consists of the colon-= separated > fields of the the ACL flags, file masks, and ACL entries in the follo= wing s/the the/the/ > format: > .TP > \fBflags:\fR\fIacl_flags\fR > The ACL flags. > .TP > \fBowner:\fR\fIperm\fR\fB::mask\fR, \fBgroup:\fR\fIperm\fR\fB::mask\f= R, \fBother:\fR\fIperm\fR\fB::mask\fR > The file masks and their permissions. > .TP > \fIwho\fR\fB:\fR\fIperm\fR\fB:\fR\fIflags\fR\fB:allow\fR, \fIwho\fR\f= B:\fR\fIperm\fR\fB:\fR\fIflags\fR\fB:deny\fR > For each ACL entry, who the entry applies to, the permissions of the = entry, the > entry flags, and whether the entry allows or denies permissions. The= \fIwho\fR > field has no prefix for special identifiers, a > .B user: > or > .B u: > prefix for regular users, and a > .B group: > or > .B g: > prefix for regular groups. I think the preceding sentence could be clearer. How about something like the following (if correct): [[ The who field is one of the following: * One of the special identifiers: owner@, group@, or everyone@ * A user: or u: prefix followed by a [user name, user ID?] that designa= tes s specific user * A group: or g: prefix followed by a [group name, group ID?] that desi= gnates s specific group ]] > .PP > The entries are comma, whitespace, or newline separated. >=20 > Flags and permissions have single-letter as well as long forms, as li= sted under > .IR "ACL flags" , > .IR "ACL entry flags" , > and > .IR Permissions . > When the single-letter forms are used, the flags or permissions are > concatenated. When the long forms are used, the flags or permissions = are > separated by slashes. To align permissions or flags vertically, dash= es can be > used for padding. >=20 > .SS Setting and modifying file permissions > The access permissions for a file can either be set by assigning an a= ccess > control list > .RB ( setrichacl (1)) > or by changing the file mode permission bits > .RB ( chmod (1)). > In addition, a file can inherit an ACL from its parent directory at c= reation > time as described under > .IR "Permissions at file-creation time" . >=20 > .SS Assigning an Access Control List > When assigning an ACL to a file, unless explicitly specified, the own= er, group, > and other file masks will be computed from the ACL entries as describ= ed in > the section > .IR "Computing the maximum file masks" . > The owner, group, and other file mode permission bits are then each s= et from > the owner, group, and other file mask as follows: > .IP \(bu 4 > If the file mask includes the > .B r > permission, the read > file mode permission bit will be set. > .IP \(bu > If the file mask includes the > .B w > or > .B p > permission, the write file mode permission bit will be set. > .IP \(bu > If the file mask includes the > .B x > permission, the execute file mode permission bit will be set. > .PP > If the ACL can be represented exactly by the file mode > permission bits, the file permission bits are set to match the ACL an= d the ACL > is not stored. (When the ACL of a file is requested which doesn't ha= ve an ACL, > the file mode permission bits are converted into an equivalent ACL.) >=20 > .SS Changing the file mode permission bits > When changing the file mode permission bits with > .BR chmod (1), > the owner, group, > and other file permission bits are set to the permission bits in the = new mode, > and the file masks each are set based on the new mode bits as follows= : > .IP \(bu 4 > If the read bit in a set of permissions is set, the > .B r > permission in the corresponding file mask will be set. > .IP \(bu > If the write bit in a set of permissions is set, the > .B w > and > .B p > permissions in the corresponding file mask will be set. > .IP \(bu > If the execute bit in a set of permissions is set, the > .B x > permission in the corresponding file mask will be set. > .PP > In addition, the > .B masked > and > .B write_through > ACL flags are set. This has the > effect of limiting the permissions granted by the ACL to the file mod= e > permission bits; in addition, the owner is granted the owner mode bit= s and > others are granted the other mode bits. If the > .B auto_inherit > flag is set, the > .B protected > flag is also set to prevent the Automatic Inheritance algorithm from = modifying > the ACL. >=20 > .SS Permissions at file-creation time > When a directory has inheritable ACL entries, the following > happens when a file or directory is created inside that directory: > .RS 4 > .IP 1. 4 > A file created inside that directory will inherit all of the ACL entr= ies that > have the > .B file_inherit > flag set, and all inheritance-related flags in the inherited entries = will be > cleared. >=20 > A subdirectory created inside that directory will inherit all of the = ACL > entries that have the > .B file_inherit > or > .B dir_inherit > flag set. Entries whose > .B no_propagate > flag is set will have all inheritance-related flags cleared. Entries= whose > .B no_propagate > and > .B dir_inherit > flags are not set and whose > .B file_inherit > is set will have their > .B inherit_only > flag set. > .IP 2. > If the parent directory's ACL has the > .B auto_inherit > flag set, the inherited ACL will have its > .B auto_inherit > flag set, and all entries will have their > .B inherited > flag set. > .IP 3. > The three file masks are computed from the inherited ACL as described= in > the section > .IR "Computing the maximum file masks" . > .IP 4. > The three sets of permissions for the owner, the group, and for other= s in > the \fImode\fR parameter as given to > .BR open (2), > .BR mkdir (2), > and similar are converted into sets of RichACL permissions as describ= ed in > the section > .IR "Changing the file mode permission bits" . > Any RichACL permissions not included in those sets are > removed from the owner, group, and other file masks. The file mode pe= rmission > bits are then computed from the file masks as described in the sectio= n > .IR "Assigning an Access Control List" . > The process umask (see > .BR umask (2)) > is ignored. > .IP 5. > The > .B masked > ACL flag is set. The > .B write_through > ACL flag remains cleared. In addition, if the > .B auto_inherit > flag of the inherited ACL is set, the > .B protected > flag is also set to prevent the Automatic Inheritance algorithm from = modifying > the ACL. > .RE > .PP > When a directory does not have inheritable ACL entries, files and dir= ectories > created inside that directory will not be assigned access control lis= ts and the > file mode permission bits will be set to (\fImode\fR\ &\ ~\fIumask\fR= ) where > \fImode\fR is the mode argument of the relevant system call and \fIum= ask\fR is > the process umask (see > .BR umask (2)). >=20 > .SS Automatic Inheritance > Automatic Inheritance is a mechanism that allows permission changes t= o > propagate from a directory to files and subdirectories inside that di= rectory, > recursively. Propagation is carried out by the process changing the = directory > permissions (usually, > .BR setrichacl (1)); > it happens without user intervention albeit not entirely automaticall= y. >=20 > A significant limitation is that this mechanism works only as long as= files > are created without explicitly specifying the file permissions to use= =2E The > standard system calls for creating files an directories ( s/an /and / s/ ($// > .BR creat (2), Make that last line: =2ERM ( creat (2), > .BR open (2), > .BR mkdir (2), > .BR mknod (2)) > all have mandatory mode parameters which define the maximum allowed p= ermissions > of the new files. To take account of this restriction, the > .B protected > ACL flag must be set if the > .B inherited > flag is set. This effectively disables Automatic Inheritance for that > particular file. >=20 > Automatic Inheritance still remains useful for network protocols like= NFSv4 and > SMB, which both support creating files and directories without defini= ng which s/which$/their/ > permissions: they can implement those operations by using the standar= d system > calls and by then undoing the effect of applying the mode parameters. >=20 > When the ACL of a directory is changed, the following happens for eac= h entry > (\(lqchild\(rq) inside that directory: > .IP 1. 4 > If the entry is a symblic link, skip the child. > .IP 2. > If the > .B auto_inherit > flag of the entry's ACL is not set or the > .B protected > flag is set, skip the child. > .IP 3. > With the child's ACL: > .RS 4 > .IP a) 4 > If the > .B defaulted > flag is set, replace the ACL with an empty ACL > with the > .B auto_inherit > flag set. > .IP b) > Delete all entries which have the > .B inherited > flag set. > .IP c) > Append all entries inherited from the parent directory according to s= tep 1 of > the algorithm described under > .IR "Permissions at file-creation time". > Set the > .B inherited > flag of each of these entries. > .IP d) > Recompute the file masks. > .RE > .IP 4. > If the child is a directory, recursively apply this algorithm. >=20 > .SS Access check algorithm >=20 > When a process requests a particular kind of access (expressed as a s= et of > RichACL permissions) to a file, the following algorithm determines wh= ether the > access is granted or denied: >=20 > .IP 1. 4 > If the > .B masked > ACL flag is set, then: > .RS 4 > .IP a) 4 > If the > .B write_through > ACL flag is set, then: > .RS 4 > .IP \(bu 4 > If the requesting process is the file owner, then access is granted i= f the > owner mask includes the requested permissions, and is otherwise denie= d. > .IP \(bu > If the requesting process is not the file owner, is not in the owning= group, > and no ACL entries other than > .B everyone@ > match the process, then access is granted if the other mask includes = the > requested permissions, and is otherwise denied. > .RE > .IP b) > If any of the following is true: > .RS 4 > .IP \(bu 4 > the requesting process is the file owner and the owner mask does not = include all > requested permissions, > .IP \(bu 4 > the requesting process is not the file owner and it is in the owning = group or > matches any ACL entries other than > .BR everyone@ , > and the group mask does not include all requested permissions, > .IP \(bu 4 > the requesting process is not the file owner, not in the owning group= , it > matches no ACL entries other than > .BR everyone@ , > and the other mask does not include all requested permissions, > .PP > then access is denied. > .RE > .RE > .IP 2. > Set the remaining permissions to the requested permissions. Go throu= gh all ACL > entries. For each entry: > .RS 4 > .IP a) 4 > If the > .B inherit_only > or > .B unmapped > flags are set, continue with the next ACL entry. > .IP b) > If any of the following is true: > .RS 4 > .IP \(bu 4 > the entry's identifier is > .B owner@ > and the requesting process is the file owner, > .IP \(bu > the entry's identifier is > .B group@ > and the requesting process is in the owning group, > .IP \(bu > the entry's identifier is a user and the requesting process is owned = by that > user, > .IP \(bu > the entry's identifier is a group and the requesting process is a mem= ber in > that group, > .IP \(bu > the entry's identifier is > .BR everyone@ , > .PP > then the entry matches the process; proceed to the next step. Otherwi= se, > continue with the next ACL entry. > .RE > .IP c) > If the entry denies any of the remaining permissions, access is denie= d. > .IP d) > If the entry allows any of the remaining permissions, then: > .RS 4 > .IP \(bu 4 > If the > .B masked > ACL flag is set and the entry's identifier is not > .B owner@ > or > .BR everyone@ > or is a user entry matching the file owner, remove all permissions fr= om the > remaining permissions which are both allowed by the entry and include= d in the > group mask, > .IP \(bu > Otherwise, remove all permissions from the remaining permissions wich= are > allowed by the entry. > .RE > .RE > .IP 3. > If there are no more remaining permissions, access is allowed. Otherw= ise, > access is denied. >=20 > .SS Computing the maximum file masks > When setting an ACL and no file masks have been explicitly specified = and when > inheriting an ACL from the parent directory, the following algorithm = is used > for computing the file masks: >=20 > .IP 1. 4 > Clear the owner, group, and other file masks. Remember which permissi= ons have > already been processed (initially, the empty set). > .IP 2. > For each ACL entry: > .RS 4 > .IP \(bu 4 > If the > .B inherit_only > flag is set, skip the entry. > .IP \(bu 4 > Otherwise, compute which permissions the entry allows or denies that = have not > been processed yet (the remaining permissions). > .IP \(bu > If the entry is an > .B owner@ > entry, add the remaining permissions to the owner mask for > .B allow > entries, and remove the remaining permissions from the owner mask for > .B deny > entries. > .IP \(bu > Otherwise, if the entry is an > .B everyone@ > entry, proceed as with > .B owner@ > entries but add or remove the remaining permissions from the owner, g= roup, and > other file masks. > .IP \(bu > Otherwise, proceed as with > .B owner@ > entries but add or remove the remaining permissions from the owner an= d group > file masks. > .IP \(bu > Add the entry's permissions to the processed permissions. > .RE > .PP > The resulting file masks represent the ACL as closely as possible. Wi= th these > file masks, if the > .B masked > ACL flag is set, the effective permissions still stay the same. >=20 > .\" .SH BUGS > .SH AUTHOR > Written by Andreas Gr=C3=BCnbacher . >=20 > Please send your bug reports, suggested features and comments to the = above address. Could we start with just a few simple examples already, and build up over future iterations of this page? > .SH CONFORMING TO > Rich Access Control Lists are Linux-specific. > .SH SEE ALSO > .BR acl (5), > .BR chmod (1), > .BR getrichacl (1), > .BR ls (1), > .BR setrichacl (1) > .BR stat (2), > .BR umask (2) > .\" librichacl Thanks, Michael --=20 Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/ From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f41.google.com ([74.125.82.41]:36862 "EHLO mail-wm0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751283AbcBNVbr (ORCPT ); Sun, 14 Feb 2016 16:31:47 -0500 Subject: Re: richacl(7) man page review comments To: Andreas Gruenbacher References: <56B770B6.7040803@gmail.com> <56B77262.7090107@gmail.com> Cc: mtk.manpages@gmail.com, "J. Bruce Fields" , linux-ext4 , XFS Developers , lkml , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , Dave Chinner , Christoph Hellwig , Anna Schumaker , Trond Myklebust , Jeff Layton , Andreas Dilger From: "Michael Kerrisk (man-pages)" Message-ID: <56C0F23C.7030902@gmail.com> Date: Sun, 14 Feb 2016 22:31:40 +0100 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Sender: linux-nfs-owner@vger.kernel.org List-ID: Hi Andreas, Here's a few more comments on the current richacl(7) page that I fetched from the git repo. > .\" > .\" RichACL Manual Pages > .\" > .\" Copyright (C) 2015,2016 Red Hat, Inc. > .\" Written by Andreas Gruenbacher > .\" This is free documentation; 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 of > .\" the License, or (at your option) any later version. > .\" > .\" The GNU General Public License's references to "object code" > .\" and "executables" are to be interpreted as the output of any > .\" document formatting or typesetting system, including > .\" intermediate and printed output. > .\" > .\" This manual 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 this manual. If not, see > .\" . > .\" > .de URL > \\$2 \(laURL: \\$1 \(ra\\$3 > .. > .if \n[.g] .mso www.tmac > .TH RICHACL 7 2015-09-01 "Linux" "Rich Access Control Lists" > .SH NAME > richacl \- Rich Access Control Lists > .SH DESCRIPTION > Rich Access Control Lists (RichACLs) are an extension of the POSIX file > permission model (see > .BR acl (5)) > to support > .URL https://tools.ietf.org/rfc/rfc5661.txt "NFSv4 Access Control Lists" > on local and remote-mounted filesystems. Having read the following paragraph a number of times (and being ignorant of NFS ACLs), I find that I'm none the wiser about what you are trying to say. What does it mean to "apply a file mode to an... ACL"? Likewise, how does "the file mode determine the values of the file masks"? This isn't clear in the following paragraph, and doesn't seem to be alborated in the rest of the page. Could you add some text somehwere to explain these points? > RichACLs support file masks which can be used to apply a file mode to an existing > NFSv4 ACL without destructive side effects: the file mode determines the values > of the file masks; the file masks restrict the permissions granted by the NFSv4 > ACL. When a less restrictive file mode is applied later, the file masks become > less restrictive, and more of the original permissions can become effective. > > A RichACL can always be translated into an equivalent NFSv4 ACL which grants > the same permissions. > > RichACLs can be enabled on supported filesystems. This disables POSIX Access I think it might be helpful here to list which filesystems so far support RichACLs. > Control Lists; the two ACL models cannot coexist on the same filesystem. > > When used on a filesystem that does not support RichACLs, the > .BR getrichacl (1) > and > .BR setrichacl (1) > utilities will operate on the file permission bits instead: > .BR getrichacl (1) > will display the file permission bits as a RichACL; when a RichACL > is set with > .BR setrichacl (1) > which can be represented exactly by the file permission bits, > .BR setrichacl (1) > will set the file permission bits instead. An attempt to set a RichACL that > cannot be represented exactly by the file permission bits results in an error. > > .SS Structure of RichACLs > > RichACLs consist of a number of ACL entries, three file masks, and some flags > specifying attributes of the ACL as whole (by contrast with the per-ACL-entry > flags described below). Insert a blank line here, to start a new paragraph. > Each of the ACL entries allows or denies some permissions to a particular user, > group, or special entity. Each entry consists of: In the previous line you write "entity". In the lines below you use "identifier". The terminology switch is confusing. Use just one term. > .IP \(bu 4 > A tag which specifies the user (with prefix > .B user: > or > .BR u: ), > group (with prefix > .B group: > or > .BR g: ), > or special identifier the entry applies to. Special > identifiers can be the file owner > .RB ( owner@ ), > the owning group > .RB ( group@ ), > or everyone > .RB ( everyone@ ). > .IP \(bu > A set of permissions the entry allows or denies. > .IP \(bu > A set of flags that indicate whether the user or group identifier is mapped or > unmapped, and whether the entry has been and can be inherited. > .IP \(bu 4 > A field indicating whether the entry allows or denies access. Does this field have a name? It would make dicussing it easier to give it a name. That is, an ACL entry consists of four fields: * a tag * permissions * flags * ??? ("type"?) > .PP > The owner, group, and other file masks further control which permissions the > ACL grants, subject to the > .BR masked "\ (" m ) > and > .BR write_through "\ (" w ) > ACL flags. > > Note that entries with the identifier > .B everyone@ > apply to all processes, whereas the \(lqother\(rq file permissions and > \(lqother\(rq entries in POSIX ACLs apply to all processes which are not the > owner, are not in the owning group, and do not match a user or group mentioned > in the ACL. > > Unlike POSIX ACLs, RichACLs do not have separate \(lqaccess\(rq ACLs that > define the access permissions and \(lqdefault\(rq ACLs that define the > inheritable permissions. Instead, flags on each ACL entry determine whether > the entry is effective during access checks and/or inheritable. > > > .SS ACL flags > > The following flags on ACLs are defined: > > .RS > .HP I don't think the heavy indentation here is helpful, and it narrors the text considerably. I suggest replacing the preceding .RS+.HP with .TP, and changing ewach .HP below to .TP, and remove the colon at the end of each line that follows the .TP lines. > .BR masked "\ (" m ): > When set, the file masks define upper limits on the permissions the ACL may > grant. > .HP > .BR write_through "\ (" w ): > When this flag and the > .B masked > flag are both set, the owner and other file masks define the actual permissions > granted to the file owner and to others instead of an upper limit. There needs to be a statement here about what 'write_through' does if 'masked' is not set. > .HP > .BR auto_inherit "\ (" a ): > Automatic Inheritance is enabled for the file the ACL is > attached to. See > .IR "Automatic Inheritance" . > .HP > .BR protected "\ (" p ): > The ACL is protected from modification by Automatic > Inheritance. > .HP > .BR defaulted "\ (" d ): > The ACL has been assigned by default. Automatic Inheritance should completely What does "assigned by default" mean? That it was inherited because of 'dir_inherit' or 'file_inherit' in the pareent directory? This needs to be clearer. > replace the ACL. > .RE If you follow my suggestion above, delete the preceding .RE > .SS ACL entry flags > > The following flags on ACL entries are defined: > > .RS > .HP See above. Possibly change .RS+.HP to .TP > .BR file_inherit "\ (" f ): > The entry is inheritable for files. Maybe this would be better as: "When this flag appears in the ACL entry of a directory, then that entry is inherited by new files created in the directory." Is that text that I propose correct? > .HP > .BR dir_inherit "\ (" d ): > The entry is inheritable for directories. "When this flag appears in the ACL entry of a directory, then that entry is inherited by new subdirectories created in the directory." Is that text that I propose correct? > .HP > .BR no_propagate "\ (" n ): > Inheritance stops at the next subdirectory level. > .HP > .BR inherit_only "\ (" i ): > The entry defines inheritable permissions only and is ignored for access > checking. > .HP > .BR inherited "\ (" a ): > The entry has been automatically inherited from the parent directory; the > ACL's > .B auto_inherit > flag should be on. > .HP > .BR unmapped "\ (" u ): > The user or group identifier is a textual string and is not mapped to a numeric > user or group identifier. ACLs with unmapped identifiers can occur on NFSv4 > mounted filesystems when the client cannot determine numeric user or group > identifiers for some of the NFSv4 user@domain or group@domain who values. They > cannot be assigned to local files or directories. > .RE If you follow my suggestion above, delete the preceding .RE > > .SS Permissions > > The following permissions are defined for RichACL entries and for the three > file masks: > > .RS > .HP See above. Possibly change .RS+.HP yo .TP > .BR read_data " / " list_directory "\ (" r ): > For a file: read the data of the file. > For a directory: list the contents of the directory. > .HP > .BR write_data " / " add_file "\ (" w ): > For a file: modify the data of the file; does not include opening the file in > append mode. > For a directory: add a new file in the directory. > .HP > .BR append_data " / " add_subdirectory "\ (" p ): > For a file: open the file in append mode. > For a directory: create a subdirectory in the directory. > .HP > .BR execute "\ (" x ): > For a file: execute the file. > For a directory: traverse / search the directory. > .HP > .BR delete_child "\ (" d ): > Delete a file or directory within a directory. > .HP > .BR delete "\ (" D ): > Delete the file or directory. > .HP > .BR read_attributes "\ (" a ): > Read basic attributes of a file or directory (see > .BR stat (2)). > This permission is always implicitly granted. So, can this permission ever be taken away? If yes, say so. If not, why does this permission exist? (And maybe say something about that.) > .HP > .BR write_attributes "\ (" A ): > Change the times associated with a file or directory to an arbitrary value. > This permission is always implicitly granted to the file owner. > .HP > .BR read_acl "\ (" c ): > Read the ACL of a file or directory. This permission is always > implicitly granted. > .HP > .BR write_acl "\ (" C ): > Change the ACL or file mode of a file or directory. > .HP > .BR write_owner "\ (" o ): > Take ownership of a file or directory. Change the owning group of a file or > directory to a group of which the calling process is a member. > .HP > .BR read_named_attrs "\ (" R ), > .BR write_named_attrs "\ (" W ), > .BR synchronize "\ (" S ), > .BR write_retention "\ (" e ), > .BR write_retention_hold "\ (" E ): If you follow my .TP suggestion above, then the above lines would need to be rewritten sometinh like: .BR read_named_attrs "\ (" R "), " write_named_attrs "\ (" W "), " \ synchronize "\ (" S "), " write_retention "\ (" e "), " \ write_retention_hold "\ (" E ) > These permissions are defined by NFSv4 / NFSv4.1. They can be stored, but are > not used. > .RE If you follow my suggestion above, delete the preceding .RE and add .PP > > For the > .BR r ", " w ", and " p > permissions which have different long forms for files and directories, the > .BR getrichacl (1) > utility will output the appropriate form(s) depending on the context. > The > .BR setrichacl (1) > utility will accept either form for any file type. > > .SS Text form > The common textual representation of a RichACL consists of the colon-separated > fields of the the ACL flags, file masks, and ACL entries in the following s/the the/the/ > format: > .TP > \fBflags:\fR\fIacl_flags\fR > The ACL flags. > .TP > \fBowner:\fR\fIperm\fR\fB::mask\fR, \fBgroup:\fR\fIperm\fR\fB::mask\fR, \fBother:\fR\fIperm\fR\fB::mask\fR > The file masks and their permissions. > .TP > \fIwho\fR\fB:\fR\fIperm\fR\fB:\fR\fIflags\fR\fB:allow\fR, \fIwho\fR\fB:\fR\fIperm\fR\fB:\fR\fIflags\fR\fB:deny\fR > For each ACL entry, who the entry applies to, the permissions of the entry, the > entry flags, and whether the entry allows or denies permissions. The \fIwho\fR > field has no prefix for special identifiers, a > .B user: > or > .B u: > prefix for regular users, and a > .B group: > or > .B g: > prefix for regular groups. I think the preceding sentence could be clearer. How about something like the following (if correct): [[ The who field is one of the following: * One of the special identifiers: owner@, group@, or everyone@ * A user: or u: prefix followed by a [user name, user ID?] that designates s specific user * A group: or g: prefix followed by a [group name, group ID?] that designates s specific group ]] > .PP > The entries are comma, whitespace, or newline separated. > > Flags and permissions have single-letter as well as long forms, as listed under > .IR "ACL flags" , > .IR "ACL entry flags" , > and > .IR Permissions . > When the single-letter forms are used, the flags or permissions are > concatenated. When the long forms are used, the flags or permissions are > separated by slashes. To align permissions or flags vertically, dashes can be > used for padding. > > .SS Setting and modifying file permissions > The access permissions for a file can either be set by assigning an access > control list > .RB ( setrichacl (1)) > or by changing the file mode permission bits > .RB ( chmod (1)). > In addition, a file can inherit an ACL from its parent directory at creation > time as described under > .IR "Permissions at file-creation time" . > > .SS Assigning an Access Control List > When assigning an ACL to a file, unless explicitly specified, the owner, group, > and other file masks will be computed from the ACL entries as described in > the section > .IR "Computing the maximum file masks" . > The owner, group, and other file mode permission bits are then each set from > the owner, group, and other file mask as follows: > .IP \(bu 4 > If the file mask includes the > .B r > permission, the read > file mode permission bit will be set. > .IP \(bu > If the file mask includes the > .B w > or > .B p > permission, the write file mode permission bit will be set. > .IP \(bu > If the file mask includes the > .B x > permission, the execute file mode permission bit will be set. > .PP > If the ACL can be represented exactly by the file mode > permission bits, the file permission bits are set to match the ACL and the ACL > is not stored. (When the ACL of a file is requested which doesn't have an ACL, > the file mode permission bits are converted into an equivalent ACL.) > > .SS Changing the file mode permission bits > When changing the file mode permission bits with > .BR chmod (1), > the owner, group, > and other file permission bits are set to the permission bits in the new mode, > and the file masks each are set based on the new mode bits as follows: > .IP \(bu 4 > If the read bit in a set of permissions is set, the > .B r > permission in the corresponding file mask will be set. > .IP \(bu > If the write bit in a set of permissions is set, the > .B w > and > .B p > permissions in the corresponding file mask will be set. > .IP \(bu > If the execute bit in a set of permissions is set, the > .B x > permission in the corresponding file mask will be set. > .PP > In addition, the > .B masked > and > .B write_through > ACL flags are set. This has the > effect of limiting the permissions granted by the ACL to the file mode > permission bits; in addition, the owner is granted the owner mode bits and > others are granted the other mode bits. If the > .B auto_inherit > flag is set, the > .B protected > flag is also set to prevent the Automatic Inheritance algorithm from modifying > the ACL. > > .SS Permissions at file-creation time > When a directory has inheritable ACL entries, the following > happens when a file or directory is created inside that directory: > .RS 4 > .IP 1. 4 > A file created inside that directory will inherit all of the ACL entries that > have the > .B file_inherit > flag set, and all inheritance-related flags in the inherited entries will be > cleared. > > A subdirectory created inside that directory will inherit all of the ACL > entries that have the > .B file_inherit > or > .B dir_inherit > flag set. Entries whose > .B no_propagate > flag is set will have all inheritance-related flags cleared. Entries whose > .B no_propagate > and > .B dir_inherit > flags are not set and whose > .B file_inherit > is set will have their > .B inherit_only > flag set. > .IP 2. > If the parent directory's ACL has the > .B auto_inherit > flag set, the inherited ACL will have its > .B auto_inherit > flag set, and all entries will have their > .B inherited > flag set. > .IP 3. > The three file masks are computed from the inherited ACL as described in > the section > .IR "Computing the maximum file masks" . > .IP 4. > The three sets of permissions for the owner, the group, and for others in > the \fImode\fR parameter as given to > .BR open (2), > .BR mkdir (2), > and similar are converted into sets of RichACL permissions as described in > the section > .IR "Changing the file mode permission bits" . > Any RichACL permissions not included in those sets are > removed from the owner, group, and other file masks. The file mode permission > bits are then computed from the file masks as described in the section > .IR "Assigning an Access Control List" . > The process umask (see > .BR umask (2)) > is ignored. > .IP 5. > The > .B masked > ACL flag is set. The > .B write_through > ACL flag remains cleared. In addition, if the > .B auto_inherit > flag of the inherited ACL is set, the > .B protected > flag is also set to prevent the Automatic Inheritance algorithm from modifying > the ACL. > .RE > .PP > When a directory does not have inheritable ACL entries, files and directories > created inside that directory will not be assigned access control lists and the > file mode permission bits will be set to (\fImode\fR\ &\ ~\fIumask\fR) where > \fImode\fR is the mode argument of the relevant system call and \fIumask\fR is > the process umask (see > .BR umask (2)). > > .SS Automatic Inheritance > Automatic Inheritance is a mechanism that allows permission changes to > propagate from a directory to files and subdirectories inside that directory, > recursively. Propagation is carried out by the process changing the directory > permissions (usually, > .BR setrichacl (1)); > it happens without user intervention albeit not entirely automatically. > > A significant limitation is that this mechanism works only as long as files > are created without explicitly specifying the file permissions to use. The > standard system calls for creating files an directories ( s/an /and / s/ ($// > .BR creat (2), Make that last line: .RM ( creat (2), > .BR open (2), > .BR mkdir (2), > .BR mknod (2)) > all have mandatory mode parameters which define the maximum allowed permissions > of the new files. To take account of this restriction, the > .B protected > ACL flag must be set if the > .B inherited > flag is set. This effectively disables Automatic Inheritance for that > particular file. > > Automatic Inheritance still remains useful for network protocols like NFSv4 and > SMB, which both support creating files and directories without defining which s/which$/their/ > permissions: they can implement those operations by using the standard system > calls and by then undoing the effect of applying the mode parameters. > > When the ACL of a directory is changed, the following happens for each entry > (\(lqchild\(rq) inside that directory: > .IP 1. 4 > If the entry is a symblic link, skip the child. > .IP 2. > If the > .B auto_inherit > flag of the entry's ACL is not set or the > .B protected > flag is set, skip the child. > .IP 3. > With the child's ACL: > .RS 4 > .IP a) 4 > If the > .B defaulted > flag is set, replace the ACL with an empty ACL > with the > .B auto_inherit > flag set. > .IP b) > Delete all entries which have the > .B inherited > flag set. > .IP c) > Append all entries inherited from the parent directory according to step 1 of > the algorithm described under > .IR "Permissions at file-creation time". > Set the > .B inherited > flag of each of these entries. > .IP d) > Recompute the file masks. > .RE > .IP 4. > If the child is a directory, recursively apply this algorithm. > > .SS Access check algorithm > > When a process requests a particular kind of access (expressed as a set of > RichACL permissions) to a file, the following algorithm determines whether the > access is granted or denied: > > .IP 1. 4 > If the > .B masked > ACL flag is set, then: > .RS 4 > .IP a) 4 > If the > .B write_through > ACL flag is set, then: > .RS 4 > .IP \(bu 4 > If the requesting process is the file owner, then access is granted if the > owner mask includes the requested permissions, and is otherwise denied. > .IP \(bu > If the requesting process is not the file owner, is not in the owning group, > and no ACL entries other than > .B everyone@ > match the process, then access is granted if the other mask includes the > requested permissions, and is otherwise denied. > .RE > .IP b) > If any of the following is true: > .RS 4 > .IP \(bu 4 > the requesting process is the file owner and the owner mask does not include all > requested permissions, > .IP \(bu 4 > the requesting process is not the file owner and it is in the owning group or > matches any ACL entries other than > .BR everyone@ , > and the group mask does not include all requested permissions, > .IP \(bu 4 > the requesting process is not the file owner, not in the owning group, it > matches no ACL entries other than > .BR everyone@ , > and the other mask does not include all requested permissions, > .PP > then access is denied. > .RE > .RE > .IP 2. > Set the remaining permissions to the requested permissions. Go through all ACL > entries. For each entry: > .RS 4 > .IP a) 4 > If the > .B inherit_only > or > .B unmapped > flags are set, continue with the next ACL entry. > .IP b) > If any of the following is true: > .RS 4 > .IP \(bu 4 > the entry's identifier is > .B owner@ > and the requesting process is the file owner, > .IP \(bu > the entry's identifier is > .B group@ > and the requesting process is in the owning group, > .IP \(bu > the entry's identifier is a user and the requesting process is owned by that > user, > .IP \(bu > the entry's identifier is a group and the requesting process is a member in > that group, > .IP \(bu > the entry's identifier is > .BR everyone@ , > .PP > then the entry matches the process; proceed to the next step. Otherwise, > continue with the next ACL entry. > .RE > .IP c) > If the entry denies any of the remaining permissions, access is denied. > .IP d) > If the entry allows any of the remaining permissions, then: > .RS 4 > .IP \(bu 4 > If the > .B masked > ACL flag is set and the entry's identifier is not > .B owner@ > or > .BR everyone@ > or is a user entry matching the file owner, remove all permissions from the > remaining permissions which are both allowed by the entry and included in the > group mask, > .IP \(bu > Otherwise, remove all permissions from the remaining permissions wich are > allowed by the entry. > .RE > .RE > .IP 3. > If there are no more remaining permissions, access is allowed. Otherwise, > access is denied. > > .SS Computing the maximum file masks > When setting an ACL and no file masks have been explicitly specified and when > inheriting an ACL from the parent directory, the following algorithm is used > for computing the file masks: > > .IP 1. 4 > Clear the owner, group, and other file masks. Remember which permissions have > already been processed (initially, the empty set). > .IP 2. > For each ACL entry: > .RS 4 > .IP \(bu 4 > If the > .B inherit_only > flag is set, skip the entry. > .IP \(bu 4 > Otherwise, compute which permissions the entry allows or denies that have not > been processed yet (the remaining permissions). > .IP \(bu > If the entry is an > .B owner@ > entry, add the remaining permissions to the owner mask for > .B allow > entries, and remove the remaining permissions from the owner mask for > .B deny > entries. > .IP \(bu > Otherwise, if the entry is an > .B everyone@ > entry, proceed as with > .B owner@ > entries but add or remove the remaining permissions from the owner, group, and > other file masks. > .IP \(bu > Otherwise, proceed as with > .B owner@ > entries but add or remove the remaining permissions from the owner and group > file masks. > .IP \(bu > Add the entry's permissions to the processed permissions. > .RE > .PP > The resulting file masks represent the ACL as closely as possible. With these > file masks, if the > .B masked > ACL flag is set, the effective permissions still stay the same. > > .\" .SH BUGS > .SH AUTHOR > Written by Andreas Grünbacher . > > Please send your bug reports, suggested features and comments to the above address. Could we start with just a few simple examples already, and build up over future iterations of this page? > .SH CONFORMING TO > Rich Access Control Lists are Linux-specific. > .SH SEE ALSO > .BR acl (5), > .BR chmod (1), > .BR getrichacl (1), > .BR ls (1), > .BR setrichacl (1) > .BR stat (2), > .BR umask (2) > .\" librichacl Thanks, Michael -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/ From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 7175A7CA2 for ; Sun, 14 Feb 2016 15:31:52 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 297E8304051 for ; Sun, 14 Feb 2016 13:31:52 -0800 (PST) Received: from mail-wm0-f52.google.com (mail-wm0-f52.google.com [74.125.82.52]) by cuda.sgi.com with ESMTP id v2nWhXmwadnDAF50 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 14 Feb 2016 13:31:46 -0800 (PST) Received: by mail-wm0-f52.google.com with SMTP id c200so88223459wme.0 for ; Sun, 14 Feb 2016 13:31:45 -0800 (PST) Subject: Re: richacl(7) man page review comments References: <56B770B6.7040803@gmail.com> <56B77262.7090107@gmail.com> From: "Michael Kerrisk (man-pages)" Message-ID: <56C0F23C.7030902@gmail.com> Date: Sun, 14 Feb 2016 22:31:40 +0100 MIME-Version: 1.0 In-Reply-To: List-Id: XFS Filesystem from SGI List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: xfs-bounces@oss.sgi.com Sender: xfs-bounces@oss.sgi.com To: Andreas Gruenbacher Cc: Andreas Dilger , linux-cifs@vger.kernel.org, Linux NFS Mailing List , Christoph Hellwig , Linux API , Trond Myklebust , lkml , XFS Developers , "J. Bruce Fields" , mtk.manpages@gmail.com, linux-fsdevel , Jeff Layton , linux-ext4 , Anna Schumaker SGkgQW5kcmVhcywKCkhlcmUncyBhIGZldyBtb3JlIGNvbW1lbnRzIG9uIHRoZSBjdXJyZW50IHJp Y2hhY2woNykgcGFnZQp0aGF0IEkgZmV0Y2hlZCBmcm9tIHRoZSBnaXQgcmVwby4KCj4gLlwiCj4g LlwiIFJpY2hBQ0wgTWFudWFsIFBhZ2VzCj4gLlwiCj4gLlwiIENvcHlyaWdodCAoQykgMjAxNSwy MDE2ICBSZWQgSGF0LCBJbmMuCj4gLlwiIFdyaXR0ZW4gYnkgQW5kcmVhcyBHcnVlbmJhY2hlciA8 YWdydWVuYmFAcmVkaGF0LmNvbT4KPiAuXCIgVGhpcyBpcyBmcmVlIGRvY3VtZW50YXRpb247IHlv dSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgo+IC5cIiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRl cm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcwo+IC5cIiBwdWJsaXNoZWQg YnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZgo+IC5c IiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KPiAu XCIKPiAuXCIgVGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlJ3MgcmVmZXJlbmNlcyB0byAi b2JqZWN0IGNvZGUiCj4gLlwiIGFuZCAiZXhlY3V0YWJsZXMiIGFyZSB0byBiZSBpbnRlcnByZXRl ZCBhcyB0aGUgb3V0cHV0IG9mIGFueQo+IC5cIiBkb2N1bWVudCBmb3JtYXR0aW5nIG9yIHR5cGVz ZXR0aW5nIHN5c3RlbSwgaW5jbHVkaW5nCj4gLlwiIGludGVybWVkaWF0ZSBhbmQgcHJpbnRlZCBv dXRwdXQuCj4gLlwiCj4gLlwiIFRoaXMgbWFudWFsIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3Bl IHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCj4gLlwiIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsg d2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCj4gLlwiIE1FUkNIQU5UQUJJTElU WSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKPiAuXCIgR05V IEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KPiAuXCIKPiAuXCIgWW91 IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljCj4g LlwiIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIG1hbnVhbC4gIElmIG5vdCwgc2VlCj4gLlwiIDxo dHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4KPiAuXCIKPiAuZGUgVVJMCj4gXFwkMiBcKGxh VVJMOiBcXCQxIFwocmFcXCQzCj4gLi4KPiAuaWYgXG5bLmddIC5tc28gd3d3LnRtYWMKPiAuVEgg UklDSEFDTCA3IDIwMTUtMDktMDEgIkxpbnV4IiAiUmljaCBBY2Nlc3MgQ29udHJvbCBMaXN0cyIK PiAuU0ggTkFNRQo+IHJpY2hhY2wgXC0gUmljaCBBY2Nlc3MgQ29udHJvbCBMaXN0cwo+IC5TSCBE RVNDUklQVElPTgo+IFJpY2ggQWNjZXNzIENvbnRyb2wgTGlzdHMgKFJpY2hBQ0xzKSBhcmUgYW4g ZXh0ZW5zaW9uIG9mIHRoZSBQT1NJWCBmaWxlCj4gcGVybWlzc2lvbiBtb2RlbCAoc2VlCj4gLkJS IGFjbCAoNSkpCj4gdG8gc3VwcG9ydAo+IC5VUkwgaHR0cHM6Ly90b29scy5pZXRmLm9yZy9yZmMv cmZjNTY2MS50eHQgIk5GU3Y0IEFjY2VzcyBDb250cm9sIExpc3RzIgo+IG9uIGxvY2FsIGFuZCBy ZW1vdGUtbW91bnRlZCBmaWxlc3lzdGVtcy4KCkhhdmluZyByZWFkIHRoZSBmb2xsb3dpbmcgcGFy YWdyYXBoIGEgbnVtYmVyIG9mIHRpbWVzIChhbmQgYmVpbmcKaWdub3JhbnQgb2YgTkZTIEFDTHMp LCBJIGZpbmQgdGhhdCBJJ20gbm9uZSB0aGUgd2lzZXIgYWJvdXQgd2hhdCB5b3UgYXJlCnRyeWlu ZyB0byBzYXkuIFdoYXQgZG9lcyBpdCBtZWFuIHRvICJhcHBseSBhIGZpbGUgbW9kZSB0byBhbi4u LiBBQ0wiPwpMaWtld2lzZSwgaG93IGRvZXMgInRoZSBmaWxlIG1vZGUgZGV0ZXJtaW5lIHRoZSB2 YWx1ZXMgb2YgdGhlIGZpbGUKbWFza3MiPyBUaGlzIGlzbid0IGNsZWFyIGluIHRoZSBmb2xsb3dp bmcgcGFyYWdyYXBoLCBhbmQgZG9lc24ndCBzZWVtIHRvCmJlIGFsYm9yYXRlZCBpbiB0aGUgcmVz dCBvZiB0aGUgcGFnZS4gQ291bGQgeW91IGFkZCBzb21lIHRleHQgc29tZWh3ZXJlCnRvIGV4cGxh aW4gdGhlc2UgcG9pbnRzPwoKPiBSaWNoQUNMcyBzdXBwb3J0IGZpbGUgbWFza3Mgd2hpY2ggY2Fu IGJlIHVzZWQgdG8gYXBwbHkgYSBmaWxlIG1vZGUgdG8gYW4gZXhpc3RpbmcKPiBORlN2NCBBQ0wg d2l0aG91dCBkZXN0cnVjdGl2ZSBzaWRlIGVmZmVjdHM6IHRoZSBmaWxlIG1vZGUgZGV0ZXJtaW5l cyB0aGUgdmFsdWVzCj4gb2YgdGhlIGZpbGUgbWFza3M7IHRoZSBmaWxlIG1hc2tzIHJlc3RyaWN0 IHRoZSBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoZSBORlN2NAo+IEFDTC4gIFdoZW4gYSBsZXNz IHJlc3RyaWN0aXZlIGZpbGUgbW9kZSBpcyBhcHBsaWVkIGxhdGVyLCB0aGUgZmlsZSBtYXNrcyBi ZWNvbWUKPiBsZXNzIHJlc3RyaWN0aXZlLCBhbmQgbW9yZSBvZiB0aGUgb3JpZ2luYWwgcGVybWlz c2lvbnMgY2FuIGJlY29tZSBlZmZlY3RpdmUuCj4gCj4gQSBSaWNoQUNMIGNhbiBhbHdheXMgYmUg dHJhbnNsYXRlZCBpbnRvIGFuIGVxdWl2YWxlbnQgTkZTdjQgQUNMIHdoaWNoIGdyYW50cwo+IHRo ZSBzYW1lIHBlcm1pc3Npb25zLgo+IAo+IFJpY2hBQ0xzIGNhbiBiZSBlbmFibGVkIG9uIHN1cHBv cnRlZCBmaWxlc3lzdGVtcy4gVGhpcyBkaXNhYmxlcyBQT1NJWCBBY2Nlc3MKCkkgdGhpbmsgaXQg bWlnaHQgYmUgaGVscGZ1bCBoZXJlIHRvIGxpc3Qgd2hpY2ggZmlsZXN5c3RlbXMgc28gZmFyCnN1 cHBvcnQgUmljaEFDTHMuCgo+IENvbnRyb2wgTGlzdHM7IHRoZSB0d28gQUNMIG1vZGVscyBjYW5u b3QgY29leGlzdCBvbiB0aGUgc2FtZSBmaWxlc3lzdGVtLgo+IAo+IFdoZW4gdXNlZCBvbiBhIGZp bGVzeXN0ZW0gdGhhdCBkb2VzIG5vdCBzdXBwb3J0IFJpY2hBQ0xzLCB0aGUKPiAuQlIgZ2V0cmlj aGFjbCAoMSkKPiBhbmQKPiAuQlIgc2V0cmljaGFjbCAoMSkKPiB1dGlsaXRpZXMgd2lsbCBvcGVy YXRlIG9uIHRoZSBmaWxlIHBlcm1pc3Npb24gYml0cyBpbnN0ZWFkOgo+IC5CUiBnZXRyaWNoYWNs ICgxKQo+IHdpbGwgZGlzcGxheSB0aGUgZmlsZSBwZXJtaXNzaW9uIGJpdHMgYXMgYSBSaWNoQUNM OyB3aGVuIGEgUmljaEFDTAo+IGlzIHNldCB3aXRoCj4gLkJSIHNldHJpY2hhY2wgKDEpCj4gd2hp Y2ggY2FuIGJlIHJlcHJlc2VudGVkIGV4YWN0bHkgYnkgdGhlIGZpbGUgcGVybWlzc2lvbiBiaXRz LAo+IC5CUiBzZXRyaWNoYWNsICgxKQo+IHdpbGwgc2V0IHRoZSBmaWxlIHBlcm1pc3Npb24gYml0 cyBpbnN0ZWFkLiAgQW4gYXR0ZW1wdCB0byBzZXQgYSBSaWNoQUNMIHRoYXQKPiBjYW5ub3QgYmUg cmVwcmVzZW50ZWQgZXhhY3RseSBieSB0aGUgZmlsZSBwZXJtaXNzaW9uIGJpdHMgcmVzdWx0cyBp biBhbiBlcnJvci4KPiAKPiAuU1MgU3RydWN0dXJlIG9mIFJpY2hBQ0xzCj4gCj4gUmljaEFDTHMg Y29uc2lzdCBvZiBhIG51bWJlciBvZiBBQ0wgZW50cmllcywgdGhyZWUgZmlsZSBtYXNrcywgYW5k IHNvbWUgZmxhZ3MKPiBzcGVjaWZ5aW5nIGF0dHJpYnV0ZXMgb2YgdGhlIEFDTCBhcyB3aG9sZSAo YnkgY29udHJhc3Qgd2l0aCB0aGUgcGVyLUFDTC1lbnRyeQo+IGZsYWdzIGRlc2NyaWJlZCBiZWxv dykuCgpJbnNlcnQgYSBibGFuayBsaW5lIGhlcmUsIHRvIHN0YXJ0IGEgbmV3IHBhcmFncmFwaC4K Cj4gRWFjaCBvZiB0aGUgQUNMIGVudHJpZXMgYWxsb3dzIG9yIGRlbmllcyBzb21lIHBlcm1pc3Np b25zIHRvIGEgcGFydGljdWxhciB1c2VyLAo+IGdyb3VwLCBvciBzcGVjaWFsIGVudGl0eS4gRWFj aCBlbnRyeSBjb25zaXN0cyBvZjoKCkluIHRoZSBwcmV2aW91cyBsaW5lIHlvdSB3cml0ZSAiZW50 aXR5Ii4gSW4gdGhlIGxpbmVzIGJlbG93IHlvdSB1c2UKImlkZW50aWZpZXIiLiBUaGUgdGVybWlu b2xvZ3kgc3dpdGNoIGlzIGNvbmZ1c2luZy4gVXNlIGp1c3Qgb25lCnRlcm0uCiAKPiAuSVAgXChi dSA0Cj4gQSB0YWcgd2hpY2ggc3BlY2lmaWVzIHRoZSB1c2VyICh3aXRoIHByZWZpeAo+IC5CIHVz ZXI6Cj4gb3IKPiAuQlIgdTogKSwKPiBncm91cCAod2l0aCBwcmVmaXgKPiAuQiBncm91cDoKPiBv cgo+IC5CUiBnOiApLAo+IG9yIHNwZWNpYWwgaWRlbnRpZmllciB0aGUgZW50cnkgYXBwbGllcyB0 by4gU3BlY2lhbAo+IGlkZW50aWZpZXJzIGNhbiBiZSB0aGUgZmlsZSBvd25lcgo+IC5SQiAoIG93 bmVyQCApLAo+IHRoZSBvd25pbmcgZ3JvdXAKPiAuUkIgKCBncm91cEAgKSwKPiBvciBldmVyeW9u ZQo+IC5SQiAoIGV2ZXJ5b25lQCApLgo+IC5JUCBcKGJ1Cj4gQSBzZXQgb2YgcGVybWlzc2lvbnMg dGhlIGVudHJ5IGFsbG93cyBvciBkZW5pZXMuCj4gLklQIFwoYnUKPiBBIHNldCBvZiBmbGFncyB0 aGF0IGluZGljYXRlIHdoZXRoZXIgdGhlIHVzZXIgb3IgZ3JvdXAgaWRlbnRpZmllciBpcyBtYXBw ZWQgb3IKPiB1bm1hcHBlZCwgYW5kIHdoZXRoZXIgdGhlIGVudHJ5IGhhcyBiZWVuIGFuZCBjYW4g YmUgaW5oZXJpdGVkLgo+IC5JUCBcKGJ1IDQKPiBBIGZpZWxkIGluZGljYXRpbmcgd2hldGhlciB0 aGUgZW50cnkgYWxsb3dzIG9yIGRlbmllcyBhY2Nlc3MuCgpEb2VzIHRoaXMgZmllbGQgaGF2ZSBh IG5hbWU/IEl0IHdvdWxkIG1ha2UgZGljdXNzaW5nIGl0IGVhc2llcgp0byBnaXZlIGl0IGEgbmFt ZS4gVGhhdCBpcywgYW4gQUNMIGVudHJ5IGNvbnNpc3RzIG9mIGZvdXIgZmllbGRzOgoKKiBhIHRh ZwoqIHBlcm1pc3Npb25zCiogZmxhZ3MKKiA/Pz8gKCJ0eXBlIj8pCgo+IC5QUAo+IFRoZSBvd25l ciwgZ3JvdXAsIGFuZCBvdGhlciBmaWxlIG1hc2tzIGZ1cnRoZXIgY29udHJvbCB3aGljaCBwZXJt aXNzaW9ucyB0aGUKPiBBQ0wgZ3JhbnRzLCBzdWJqZWN0IHRvIHRoZQo+IC5CUiBtYXNrZWQgIlwg KCIgbSApCj4gYW5kCj4gLkJSIHdyaXRlX3Rocm91Z2ggIlwgKCIgdyApCj4gQUNMIGZsYWdzLgo+ IAo+IE5vdGUgdGhhdCBlbnRyaWVzIHdpdGggdGhlIGlkZW50aWZpZXIKPiAuQiBldmVyeW9uZUAK PiBhcHBseSB0byBhbGwgcHJvY2Vzc2VzLCB3aGVyZWFzIHRoZSBcKGxxb3RoZXJcKHJxIGZpbGUg cGVybWlzc2lvbnMgYW5kCj4gXChscW90aGVyXChycSBlbnRyaWVzIGluIFBPU0lYIEFDTHMgYXBw bHkgdG8gYWxsIHByb2Nlc3NlcyB3aGljaCBhcmUgbm90IHRoZQo+IG93bmVyLCBhcmUgbm90IGlu IHRoZSBvd25pbmcgZ3JvdXAsIGFuZCBkbyBub3QgbWF0Y2ggYSB1c2VyIG9yIGdyb3VwIG1lbnRp b25lZAo+IGluIHRoZSBBQ0wuCj4gCj4gVW5saWtlIFBPU0lYIEFDTHMsIFJpY2hBQ0xzIGRvIG5v dCBoYXZlIHNlcGFyYXRlIFwobHFhY2Nlc3NcKHJxIEFDTHMgdGhhdAo+IGRlZmluZSB0aGUgYWNj ZXNzIHBlcm1pc3Npb25zIGFuZCBcKGxxZGVmYXVsdFwocnEgQUNMcyB0aGF0IGRlZmluZSB0aGUK PiBpbmhlcml0YWJsZSBwZXJtaXNzaW9ucy4gIEluc3RlYWQsIGZsYWdzIG9uIGVhY2ggQUNMIGVu dHJ5IGRldGVybWluZSB3aGV0aGVyCj4gdGhlIGVudHJ5IGlzIGVmZmVjdGl2ZSBkdXJpbmcgYWNj ZXNzIGNoZWNrcyBhbmQvb3IgaW5oZXJpdGFibGUuCj4gCj4gCj4gLlNTIEFDTCBmbGFncwo+IAo+ IFRoZSBmb2xsb3dpbmcgZmxhZ3Mgb24gQUNMcyBhcmUgZGVmaW5lZDoKPiAKPiAuUlMKPiAuSFAK CkkgZG9uJ3QgdGhpbmsgdGhlIGhlYXZ5IGluZGVudGF0aW9uIGhlcmUgaXMgaGVscGZ1bCwgYW5k IGl0IG5hcnJvcnMgdGhlCnRleHQgY29uc2lkZXJhYmx5LiBJIHN1Z2dlc3QgcmVwbGFjaW5nIHRo ZSBwcmVjZWRpbmcgLlJTKy5IUCB3aXRoIC5UUCwKYW5kIGNoYW5naW5nIGV3YWNoIC5IUCBiZWxv dyB0byAuVFAsIGFuZCByZW1vdmUgdGhlIGNvbG9uIGF0IHRoZSBlbmQgb2YKZWFjaCBsaW5lIHRo YXQgZm9sbG93cyB0aGUgLlRQIGxpbmVzLgoKPiAuQlIgbWFza2VkICJcICgiIG0gKToKPiBXaGVu IHNldCwgdGhlIGZpbGUgbWFza3MgZGVmaW5lIHVwcGVyIGxpbWl0cyBvbiB0aGUgcGVybWlzc2lv bnMgdGhlIEFDTCBtYXkKPiBncmFudC4KPiAuSFAKPiAuQlIgd3JpdGVfdGhyb3VnaCAiXCAoIiB3 ICk6Cj4gV2hlbiB0aGlzIGZsYWcgYW5kIHRoZQo+IC5CIG1hc2tlZAo+IGZsYWcgYXJlIGJvdGgg c2V0LCB0aGUgb3duZXIgYW5kIG90aGVyIGZpbGUgbWFza3MgZGVmaW5lIHRoZSBhY3R1YWwgcGVy bWlzc2lvbnMKPiBncmFudGVkIHRvIHRoZSBmaWxlIG93bmVyIGFuZCB0byBvdGhlcnMgaW5zdGVh ZCBvZiBhbiB1cHBlciBsaW1pdC4KClRoZXJlIG5lZWRzIHRvIGJlIGEgc3RhdGVtZW50IGhlcmUg YWJvdXQgd2hhdCAnd3JpdGVfdGhyb3VnaCcgZG9lcyBpZgonbWFza2VkJyBpcyBub3Qgc2V0LgoK PiAuSFAKPiAuQlIgYXV0b19pbmhlcml0ICJcICgiIGEgKToKPiBBdXRvbWF0aWMgSW5oZXJpdGFu Y2UgaXMgZW5hYmxlZCBmb3IgdGhlIGZpbGUgdGhlIEFDTCBpcwo+IGF0dGFjaGVkIHRvLiBTZWUK PiAuSVIgIkF1dG9tYXRpYyBJbmhlcml0YW5jZSIgLgo+IC5IUAo+IC5CUiBwcm90ZWN0ZWQgIlwg KCIgcCApOgo+IFRoZSBBQ0wgaXMgcHJvdGVjdGVkIGZyb20gbW9kaWZpY2F0aW9uIGJ5IEF1dG9t YXRpYwo+IEluaGVyaXRhbmNlLgo+IC5IUAo+IC5CUiBkZWZhdWx0ZWQgIlwgKCIgZCApOgo+IFRo ZSBBQ0wgaGFzIGJlZW4gYXNzaWduZWQgYnkgZGVmYXVsdC4gQXV0b21hdGljIEluaGVyaXRhbmNl IHNob3VsZCBjb21wbGV0ZWx5CgpXaGF0IGRvZXMgImFzc2lnbmVkIGJ5IGRlZmF1bHQiIG1lYW4/ IFRoYXQgaXQgd2FzIGluaGVyaXRlZCBiZWNhdXNlIG9mCidkaXJfaW5oZXJpdCcgb3IgJ2ZpbGVf aW5oZXJpdCcgaW4gdGhlIHBhcmVlbnQgZGlyZWN0b3J5PyBUaGlzIG5lZWRzIHRvCmJlIGNsZWFy ZXIuCgoKPiByZXBsYWNlIHRoZSBBQ0wuCj4gLlJFCgpJZiB5b3UgZm9sbG93IG15IHN1Z2dlc3Rp b24gYWJvdmUsIGRlbGV0ZSB0aGUgcHJlY2VkaW5nIC5SRQoKPiAuU1MgQUNMIGVudHJ5IGZsYWdz Cj4gCj4gVGhlIGZvbGxvd2luZyBmbGFncyBvbiBBQ0wgZW50cmllcyBhcmUgZGVmaW5lZDoKPiAK PiAuUlMKPiAuSFAKClNlZSBhYm92ZS4gUG9zc2libHkgY2hhbmdlIC5SUysuSFAgdG8gLlRQCgo+ IC5CUiBmaWxlX2luaGVyaXQgIlwgKCIgZiApOgo+IFRoZSBlbnRyeSBpcyBpbmhlcml0YWJsZSBm b3IgZmlsZXMuCgpNYXliZSB0aGlzIHdvdWxkIGJlIGJldHRlciBhczoKCiJXaGVuIHRoaXMgZmxh ZyBhcHBlYXJzIGluIHRoZSBBQ0wgZW50cnkgb2YgYSBkaXJlY3RvcnksIHRoZW4gdGhhdCBlbnRy eSBpcwppbmhlcml0ZWQgYnkgbmV3IGZpbGVzIGNyZWF0ZWQgaW4gdGhlIGRpcmVjdG9yeS4iCgpJ cyB0aGF0IHRleHQgdGhhdCBJIHByb3Bvc2UgY29ycmVjdD8KCj4gLkhQCj4gLkJSIGRpcl9pbmhl cml0ICJcICgiIGQgKToKPiBUaGUgZW50cnkgaXMgaW5oZXJpdGFibGUgZm9yIGRpcmVjdG9yaWVz LgoKIldoZW4gdGhpcyBmbGFnIGFwcGVhcnMgaW4gdGhlIEFDTCBlbnRyeSBvZiBhIGRpcmVjdG9y eSwgdGhlbiB0aGF0IGVudHJ5IGlzCmluaGVyaXRlZCBieSBuZXcgc3ViZGlyZWN0b3JpZXMgY3Jl YXRlZCBpbiB0aGUgZGlyZWN0b3J5LiIKCklzIHRoYXQgdGV4dCB0aGF0IEkgcHJvcG9zZSBjb3Jy ZWN0PwoKPiAuSFAKPiAuQlIgbm9fcHJvcGFnYXRlICJcICgiIG4gKToKPiBJbmhlcml0YW5jZSBz dG9wcyBhdCB0aGUgbmV4dCBzdWJkaXJlY3RvcnkgbGV2ZWwuCj4gLkhQCj4gLkJSIGluaGVyaXRf b25seSAiXCAoIiBpICk6Cj4gVGhlIGVudHJ5IGRlZmluZXMgaW5oZXJpdGFibGUgcGVybWlzc2lv bnMgb25seSBhbmQgaXMgaWdub3JlZCBmb3IgYWNjZXNzCj4gY2hlY2tpbmcuCj4gLkhQCj4gLkJS IGluaGVyaXRlZCAiXCAoIiBhICk6Cj4gVGhlIGVudHJ5IGhhcyBiZWVuIGF1dG9tYXRpY2FsbHkg aW5oZXJpdGVkIGZyb20gdGhlIHBhcmVudCBkaXJlY3Rvcnk7IHRoZQo+IEFDTCdzCj4gLkIgYXV0 b19pbmhlcml0Cj4gZmxhZyBzaG91bGQgYmUgb24uCj4gLkhQCj4gLkJSIHVubWFwcGVkICJcICgi IHUgKToKPiBUaGUgdXNlciBvciBncm91cCBpZGVudGlmaWVyIGlzIGEgdGV4dHVhbCBzdHJpbmcg YW5kIGlzIG5vdCBtYXBwZWQgdG8gYSBudW1lcmljCj4gdXNlciBvciBncm91cCBpZGVudGlmaWVy LiAgQUNMcyB3aXRoIHVubWFwcGVkIGlkZW50aWZpZXJzIGNhbiBvY2N1ciBvbiBORlN2NAo+IG1v dW50ZWQgZmlsZXN5c3RlbXMgd2hlbiB0aGUgY2xpZW50IGNhbm5vdCBkZXRlcm1pbmUgbnVtZXJp YyB1c2VyIG9yIGdyb3VwCj4gaWRlbnRpZmllcnMgZm9yIHNvbWUgb2YgdGhlIE5GU3Y0IHVzZXJA ZG9tYWluIG9yIGdyb3VwQGRvbWFpbiB3aG8gdmFsdWVzLiAgVGhleQo+IGNhbm5vdCBiZSBhc3Np Z25lZCB0byBsb2NhbCBmaWxlcyBvciBkaXJlY3Rvcmllcy4KPiAuUkUKCklmIHlvdSBmb2xsb3cg bXkgc3VnZ2VzdGlvbiBhYm92ZSwgZGVsZXRlIHRoZSBwcmVjZWRpbmcgLlJFCgo+IAo+IC5TUyBQ ZXJtaXNzaW9ucwo+IAo+IFRoZSBmb2xsb3dpbmcgcGVybWlzc2lvbnMgYXJlIGRlZmluZWQgZm9y IFJpY2hBQ0wgZW50cmllcyBhbmQgZm9yIHRoZSB0aHJlZQo+IGZpbGUgbWFza3M6Cj4gCj4gLlJT Cj4gLkhQCgpTZWUgYWJvdmUuIFBvc3NpYmx5IGNoYW5nZSAuUlMrLkhQIHlvIC5UUAoKPiAuQlIg cmVhZF9kYXRhICIgLyAiIGxpc3RfZGlyZWN0b3J5ICJcICgiIHIgKToKPiBGb3IgYSBmaWxlOiBy ZWFkIHRoZSBkYXRhIG9mIHRoZSBmaWxlLgo+IEZvciBhIGRpcmVjdG9yeTogbGlzdCB0aGUgY29u dGVudHMgb2YgdGhlIGRpcmVjdG9yeS4KPiAuSFAKPiAuQlIgd3JpdGVfZGF0YSAiIC8gIiBhZGRf ZmlsZSAiXCAoIiB3ICk6Cj4gRm9yIGEgZmlsZTogbW9kaWZ5IHRoZSBkYXRhIG9mIHRoZSBmaWxl OyBkb2VzIG5vdCBpbmNsdWRlIG9wZW5pbmcgdGhlIGZpbGUgaW4KPiBhcHBlbmQgbW9kZS4KPiBG b3IgYSBkaXJlY3Rvcnk6IGFkZCBhIG5ldyBmaWxlIGluIHRoZSBkaXJlY3RvcnkuCj4gLkhQCj4g LkJSIGFwcGVuZF9kYXRhICIgLyAiIGFkZF9zdWJkaXJlY3RvcnkgIlwgKCIgcCApOgo+IEZvciBh IGZpbGU6IG9wZW4gdGhlIGZpbGUgaW4gYXBwZW5kIG1vZGUuCj4gRm9yIGEgZGlyZWN0b3J5OiBj cmVhdGUgYSBzdWJkaXJlY3RvcnkgaW4gdGhlIGRpcmVjdG9yeS4KPiAuSFAKPiAuQlIgZXhlY3V0 ZSAiXCAoIiB4ICk6Cj4gRm9yIGEgZmlsZTogZXhlY3V0ZSB0aGUgZmlsZS4KPiBGb3IgYSBkaXJl Y3Rvcnk6IHRyYXZlcnNlIC8gc2VhcmNoIHRoZSBkaXJlY3RvcnkuCj4gLkhQCj4gLkJSIGRlbGV0 ZV9jaGlsZCAiXCAoIiBkICk6Cj4gRGVsZXRlIGEgZmlsZSBvciBkaXJlY3Rvcnkgd2l0aGluIGEg ZGlyZWN0b3J5Lgo+IC5IUAo+IC5CUiBkZWxldGUgIlwgKCIgRCApOgo+IERlbGV0ZSB0aGUgZmls ZSBvciBkaXJlY3RvcnkuCj4gLkhQCj4gLkJSIHJlYWRfYXR0cmlidXRlcyAiXCAoIiBhICk6Cj4g UmVhZCBiYXNpYyBhdHRyaWJ1dGVzIG9mIGEgZmlsZSBvciBkaXJlY3RvcnkgKHNlZQo+IC5CUiBz dGF0ICgyKSkuCj4gVGhpcyBwZXJtaXNzaW9uIGlzIGFsd2F5cyBpbXBsaWNpdGx5IGdyYW50ZWQu CgpTbywgY2FuIHRoaXMgcGVybWlzc2lvbiBldmVyIGJlIHRha2VuIGF3YXk/IElmIHllcywgc2F5 IHNvLiBJZiBub3QsIHdoeQpkb2VzIHRoaXMgcGVybWlzc2lvbiBleGlzdD8gKEFuZCBtYXliZSBz YXkgc29tZXRoaW5nIGFib3V0IHRoYXQuKQoKPiAuSFAKPiAuQlIgd3JpdGVfYXR0cmlidXRlcyAi XCAoIiBBICk6Cj4gQ2hhbmdlIHRoZSB0aW1lcyBhc3NvY2lhdGVkIHdpdGggYSBmaWxlIG9yIGRp cmVjdG9yeSB0byBhbiBhcmJpdHJhcnkgdmFsdWUuCj4gVGhpcyBwZXJtaXNzaW9uIGlzIGFsd2F5 cyBpbXBsaWNpdGx5IGdyYW50ZWQgdG8gdGhlIGZpbGUgb3duZXIuCj4gLkhQCj4gLkJSIHJlYWRf YWNsICJcICgiIGMgKToKPiBSZWFkIHRoZSBBQ0wgb2YgYSBmaWxlIG9yIGRpcmVjdG9yeS4gVGhp cyBwZXJtaXNzaW9uIGlzIGFsd2F5cwo+IGltcGxpY2l0bHkgZ3JhbnRlZC4KPiAuSFAKPiAuQlIg d3JpdGVfYWNsICJcICgiIEMgKToKPiBDaGFuZ2UgdGhlIEFDTCBvciBmaWxlIG1vZGUgb2YgYSBm aWxlIG9yIGRpcmVjdG9yeS4KPiAuSFAKPiAuQlIgd3JpdGVfb3duZXIgIlwgKCIgbyApOgo+IFRh a2Ugb3duZXJzaGlwIG9mIGEgZmlsZSBvciBkaXJlY3RvcnkuICBDaGFuZ2UgdGhlIG93bmluZyBn cm91cCBvZiBhIGZpbGUgb3IKPiBkaXJlY3RvcnkgdG8gYSBncm91cCBvZiB3aGljaCB0aGUgY2Fs bGluZyBwcm9jZXNzIGlzIGEgbWVtYmVyLgo+IC5IUAo+IC5CUiByZWFkX25hbWVkX2F0dHJzICJc ICgiIFIgKSwKPiAuQlIgd3JpdGVfbmFtZWRfYXR0cnMgIlwgKCIgVyApLAo+IC5CUiBzeW5jaHJv bml6ZSAiXCAoIiBTICksCj4gLkJSIHdyaXRlX3JldGVudGlvbiAiXCAoIiBlICksCj4gLkJSIHdy aXRlX3JldGVudGlvbl9ob2xkICJcICgiIEUgKToKCklmIHlvdSBmb2xsb3cgbXkgLlRQIHN1Z2dl c3Rpb24gYWJvdmUsIHRoZW4gdGhlIGFib3ZlIGxpbmVzIHdvdWxkIG5lZWQKdG8gYmUgcmV3cml0 dGVuIHNvbWV0aW5oIGxpa2U6CgouQlIgcmVhZF9uYW1lZF9hdHRycyAiXCAoIiBSICIpLCAiIHdy aXRlX25hbWVkX2F0dHJzICJcICgiIFcgIiksICIgXApzeW5jaHJvbml6ZSAiXCAoIiBTICIpLCAi IHdyaXRlX3JldGVudGlvbiAiXCAoIiBlICIpLCAiIFwKd3JpdGVfcmV0ZW50aW9uX2hvbGQgIlwg KCIgRSApCgo+IFRoZXNlIHBlcm1pc3Npb25zIGFyZSBkZWZpbmVkIGJ5IE5GU3Y0IC8gTkZTdjQu MS4gIFRoZXkgY2FuIGJlIHN0b3JlZCwgYnV0IGFyZQo+IG5vdCB1c2VkLgo+IC5SRQoKSWYgeW91 IGZvbGxvdyBteSBzdWdnZXN0aW9uIGFib3ZlLCBkZWxldGUgdGhlIHByZWNlZGluZyAuUkUgYW5k CmFkZCAuUFAKCj4gCj4gRm9yIHRoZQo+IC5CUiByICIsICIgdyAiLCBhbmQgIiBwCj4gcGVybWlz c2lvbnMgd2hpY2ggaGF2ZSBkaWZmZXJlbnQgbG9uZyBmb3JtcyBmb3IgZmlsZXMgYW5kIGRpcmVj dG9yaWVzLCB0aGUKPiAuQlIgZ2V0cmljaGFjbCAoMSkKPiB1dGlsaXR5IHdpbGwgb3V0cHV0IHRo ZSBhcHByb3ByaWF0ZSBmb3JtKHMpIGRlcGVuZGluZyBvbiB0aGUgY29udGV4dC4KPiBUaGUKPiAu QlIgc2V0cmljaGFjbCAoMSkKPiB1dGlsaXR5IHdpbGwgYWNjZXB0IGVpdGhlciBmb3JtIGZvciBh bnkgZmlsZSB0eXBlLgo+IAo+IC5TUyBUZXh0IGZvcm0KPiBUaGUgY29tbW9uIHRleHR1YWwgcmVw cmVzZW50YXRpb24gb2YgYSBSaWNoQUNMIGNvbnNpc3RzIG9mIHRoZSBjb2xvbi1zZXBhcmF0ZWQK PiBmaWVsZHMgb2YgdGhlIHRoZSBBQ0wgZmxhZ3MsIGZpbGUgbWFza3MsIGFuZCBBQ0wgZW50cmll cyBpbiB0aGUgZm9sbG93aW5nCgpzL3RoZSB0aGUvdGhlLwoKPiBmb3JtYXQ6Cj4gLlRQCj4gXGZC ZmxhZ3M6XGZSXGZJYWNsX2ZsYWdzXGZSCj4gVGhlIEFDTCBmbGFncy4KPiAuVFAKPiBcZkJvd25l cjpcZlJcZklwZXJtXGZSXGZCOjptYXNrXGZSLCBcZkJncm91cDpcZlJcZklwZXJtXGZSXGZCOjpt YXNrXGZSLCBcZkJvdGhlcjpcZlJcZklwZXJtXGZSXGZCOjptYXNrXGZSCj4gVGhlIGZpbGUgbWFz a3MgYW5kIHRoZWlyIHBlcm1pc3Npb25zLgo+IC5UUAo+IFxmSXdob1xmUlxmQjpcZlJcZklwZXJt XGZSXGZCOlxmUlxmSWZsYWdzXGZSXGZCOmFsbG93XGZSLCBcZkl3aG9cZlJcZkI6XGZSXGZJcGVy bVxmUlxmQjpcZlJcZklmbGFnc1xmUlxmQjpkZW55XGZSCj4gRm9yIGVhY2ggQUNMIGVudHJ5LCB3 aG8gdGhlIGVudHJ5IGFwcGxpZXMgdG8sIHRoZSBwZXJtaXNzaW9ucyBvZiB0aGUgZW50cnksIHRo ZQo+IGVudHJ5IGZsYWdzLCBhbmQgd2hldGhlciB0aGUgZW50cnkgYWxsb3dzIG9yIGRlbmllcyBw ZXJtaXNzaW9ucy4gIFRoZSBcZkl3aG9cZlIKPiBmaWVsZCBoYXMgbm8gcHJlZml4IGZvciBzcGVj aWFsIGlkZW50aWZpZXJzLCBhCj4gLkIgdXNlcjoKPiBvcgo+IC5CIHU6Cj4gcHJlZml4IGZvciBy ZWd1bGFyIHVzZXJzLCBhbmQgYQo+IC5CIGdyb3VwOgo+IG9yCj4gLkIgZzoKPiBwcmVmaXggZm9y IHJlZ3VsYXIgZ3JvdXBzLgoKSSB0aGluayB0aGUgcHJlY2VkaW5nIHNlbnRlbmNlIGNvdWxkIGJl IGNsZWFyZXIuIEhvdyBhYm91dCBzb21ldGhpbmcKbGlrZSB0aGUgZm9sbG93aW5nIChpZiBjb3Jy ZWN0KToKCltbClRoZSB3aG8gZmllbGQgaXMgb25lIG9mIHRoZSBmb2xsb3dpbmc6CgoqIE9uZSBv ZiB0aGUgc3BlY2lhbCBpZGVudGlmaWVyczogb3duZXJALCBncm91cEAsIG9yIGV2ZXJ5b25lQAoq IEEgdXNlcjogb3IgdTogcHJlZml4IGZvbGxvd2VkIGJ5IGEgW3VzZXIgbmFtZSwgdXNlciBJRD9d IHRoYXQgZGVzaWduYXRlcwogIHMgc3BlY2lmaWMgdXNlcgoqIEEgZ3JvdXA6IG9yIGc6IHByZWZp eCBmb2xsb3dlZCBieSBhIFtncm91cCBuYW1lLCBncm91cCBJRD9dIHRoYXQgZGVzaWduYXRlcwog IHMgc3BlY2lmaWMgZ3JvdXAKXV0KCj4gLlBQCj4gVGhlIGVudHJpZXMgYXJlIGNvbW1hLCB3aGl0 ZXNwYWNlLCBvciBuZXdsaW5lIHNlcGFyYXRlZC4KPiAKPiBGbGFncyBhbmQgcGVybWlzc2lvbnMg aGF2ZSBzaW5nbGUtbGV0dGVyIGFzIHdlbGwgYXMgbG9uZyBmb3JtcywgYXMgbGlzdGVkIHVuZGVy Cj4gLklSICJBQ0wgZmxhZ3MiICwKPiAuSVIgIkFDTCBlbnRyeSBmbGFncyIgLAo+IGFuZAo+IC5J UiBQZXJtaXNzaW9ucyAuCj4gV2hlbiB0aGUgc2luZ2xlLWxldHRlciBmb3JtcyBhcmUgdXNlZCwg dGhlIGZsYWdzIG9yIHBlcm1pc3Npb25zIGFyZQo+IGNvbmNhdGVuYXRlZC4gV2hlbiB0aGUgbG9u ZyBmb3JtcyBhcmUgdXNlZCwgdGhlIGZsYWdzIG9yIHBlcm1pc3Npb25zIGFyZQo+IHNlcGFyYXRl ZCBieSBzbGFzaGVzLiAgVG8gYWxpZ24gcGVybWlzc2lvbnMgb3IgZmxhZ3MgdmVydGljYWxseSwg ZGFzaGVzIGNhbiBiZQo+IHVzZWQgZm9yIHBhZGRpbmcuCj4gCj4gLlNTIFNldHRpbmcgYW5kIG1v ZGlmeWluZyBmaWxlIHBlcm1pc3Npb25zCj4gVGhlIGFjY2VzcyBwZXJtaXNzaW9ucyBmb3IgYSBm aWxlIGNhbiBlaXRoZXIgYmUgc2V0IGJ5IGFzc2lnbmluZyBhbiBhY2Nlc3MKPiBjb250cm9sIGxp c3QKPiAuUkIgKCBzZXRyaWNoYWNsICgxKSkKPiBvciBieSBjaGFuZ2luZyB0aGUgZmlsZSBtb2Rl IHBlcm1pc3Npb24gYml0cwo+IC5SQiAoIGNobW9kICgxKSkuCj4gSW4gYWRkaXRpb24sIGEgZmls ZSBjYW4gaW5oZXJpdCBhbiBBQ0wgZnJvbSBpdHMgcGFyZW50IGRpcmVjdG9yeSBhdCBjcmVhdGlv bgo+IHRpbWUgYXMgZGVzY3JpYmVkIHVuZGVyCj4gLklSICJQZXJtaXNzaW9ucyBhdCBmaWxlLWNy ZWF0aW9uIHRpbWUiIC4KPiAKPiAuU1MgQXNzaWduaW5nIGFuIEFjY2VzcyBDb250cm9sIExpc3QK PiBXaGVuIGFzc2lnbmluZyBhbiBBQ0wgdG8gYSBmaWxlLCB1bmxlc3MgZXhwbGljaXRseSBzcGVj aWZpZWQsIHRoZSBvd25lciwgZ3JvdXAsCj4gYW5kIG90aGVyIGZpbGUgbWFza3Mgd2lsbCBiZSBj b21wdXRlZCBmcm9tIHRoZSBBQ0wgZW50cmllcyBhcyBkZXNjcmliZWQgaW4KPiB0aGUgc2VjdGlv bgo+IC5JUiAiQ29tcHV0aW5nIHRoZSBtYXhpbXVtIGZpbGUgbWFza3MiIC4KPiBUaGUgb3duZXIs IGdyb3VwLCBhbmQgb3RoZXIgZmlsZSBtb2RlIHBlcm1pc3Npb24gYml0cyBhcmUgdGhlbiBlYWNo IHNldCBmcm9tCj4gdGhlIG93bmVyLCBncm91cCwgYW5kIG90aGVyIGZpbGUgbWFzayBhcyBmb2xs b3dzOgo+IC5JUCBcKGJ1IDQKPiBJZiB0aGUgZmlsZSBtYXNrIGluY2x1ZGVzIHRoZQo+IC5CIHIK PiBwZXJtaXNzaW9uLCB0aGUgcmVhZAo+IGZpbGUgbW9kZSBwZXJtaXNzaW9uIGJpdCB3aWxsIGJl IHNldC4KPiAuSVAgXChidQo+IElmIHRoZSBmaWxlIG1hc2sgaW5jbHVkZXMgdGhlCj4gLkIgdwo+ IG9yCj4gLkIgcAo+IHBlcm1pc3Npb24sIHRoZSB3cml0ZSBmaWxlIG1vZGUgcGVybWlzc2lvbiBi aXQgd2lsbCBiZSBzZXQuCj4gLklQIFwoYnUKPiBJZiB0aGUgZmlsZSBtYXNrIGluY2x1ZGVzIHRo ZQo+IC5CIHgKPiBwZXJtaXNzaW9uLCB0aGUgZXhlY3V0ZSBmaWxlIG1vZGUgcGVybWlzc2lvbiBi aXQgd2lsbCBiZSBzZXQuCj4gLlBQCj4gSWYgdGhlIEFDTCBjYW4gYmUgcmVwcmVzZW50ZWQgZXhh Y3RseSBieSB0aGUgZmlsZSBtb2RlCj4gcGVybWlzc2lvbiBiaXRzLCB0aGUgZmlsZSBwZXJtaXNz aW9uIGJpdHMgYXJlIHNldCB0byBtYXRjaCB0aGUgQUNMIGFuZCB0aGUgQUNMCj4gaXMgbm90IHN0 b3JlZC4gIChXaGVuIHRoZSBBQ0wgb2YgYSBmaWxlIGlzIHJlcXVlc3RlZCB3aGljaCBkb2Vzbid0 IGhhdmUgYW4gQUNMLAo+IHRoZSBmaWxlIG1vZGUgcGVybWlzc2lvbiBiaXRzIGFyZSBjb252ZXJ0 ZWQgaW50byBhbiBlcXVpdmFsZW50IEFDTC4pCj4gCj4gLlNTIENoYW5naW5nIHRoZSBmaWxlIG1v ZGUgcGVybWlzc2lvbiBiaXRzCj4gV2hlbiBjaGFuZ2luZyB0aGUgZmlsZSBtb2RlIHBlcm1pc3Np b24gYml0cyB3aXRoCj4gLkJSIGNobW9kICgxKSwKPiB0aGUgb3duZXIsIGdyb3VwLAo+IGFuZCBv dGhlciBmaWxlIHBlcm1pc3Npb24gYml0cyBhcmUgc2V0IHRvIHRoZSBwZXJtaXNzaW9uIGJpdHMg aW4gdGhlIG5ldyBtb2RlLAo+IGFuZCB0aGUgZmlsZSBtYXNrcyBlYWNoIGFyZSBzZXQgYmFzZWQg b24gdGhlIG5ldyBtb2RlIGJpdHMgYXMgZm9sbG93czoKPiAuSVAgXChidSA0Cj4gSWYgdGhlIHJl YWQgYml0IGluIGEgc2V0IG9mIHBlcm1pc3Npb25zIGlzIHNldCwgdGhlCj4gLkIgcgo+IHBlcm1p c3Npb24gaW4gdGhlIGNvcnJlc3BvbmRpbmcgZmlsZSBtYXNrIHdpbGwgYmUgc2V0Lgo+IC5JUCBc KGJ1Cj4gSWYgdGhlIHdyaXRlIGJpdCBpbiBhIHNldCBvZiBwZXJtaXNzaW9ucyBpcyBzZXQsIHRo ZQo+IC5CIHcKPiBhbmQKPiAuQiBwCj4gcGVybWlzc2lvbnMgaW4gdGhlIGNvcnJlc3BvbmRpbmcg ZmlsZSBtYXNrIHdpbGwgYmUgc2V0Lgo+IC5JUCBcKGJ1Cj4gSWYgdGhlIGV4ZWN1dGUgYml0IGlu IGEgc2V0IG9mIHBlcm1pc3Npb25zIGlzIHNldCwgdGhlCj4gLkIgeAo+IHBlcm1pc3Npb24gaW4g dGhlIGNvcnJlc3BvbmRpbmcgZmlsZSBtYXNrIHdpbGwgYmUgc2V0Lgo+IC5QUAo+IEluIGFkZGl0 aW9uLCB0aGUKPiAuQiBtYXNrZWQKPiBhbmQKPiAuQiB3cml0ZV90aHJvdWdoCj4gQUNMIGZsYWdz IGFyZSBzZXQuIFRoaXMgaGFzIHRoZQo+IGVmZmVjdCBvZiBsaW1pdGluZyB0aGUgcGVybWlzc2lv bnMgZ3JhbnRlZCBieSB0aGUgQUNMIHRvIHRoZSBmaWxlIG1vZGUKPiBwZXJtaXNzaW9uIGJpdHM7 IGluIGFkZGl0aW9uLCB0aGUgb3duZXIgaXMgZ3JhbnRlZCB0aGUgb3duZXIgbW9kZSBiaXRzIGFu ZAo+IG90aGVycyBhcmUgZ3JhbnRlZCB0aGUgb3RoZXIgbW9kZSBiaXRzLiBJZiB0aGUKPiAuQiBh dXRvX2luaGVyaXQKPiBmbGFnIGlzIHNldCwgdGhlCj4gLkIgcHJvdGVjdGVkCj4gZmxhZyBpcyBh bHNvIHNldCB0byBwcmV2ZW50IHRoZSBBdXRvbWF0aWMgSW5oZXJpdGFuY2UgYWxnb3JpdGhtIGZy b20gbW9kaWZ5aW5nCj4gdGhlIEFDTC4KPiAKPiAuU1MgUGVybWlzc2lvbnMgYXQgZmlsZS1jcmVh dGlvbiB0aW1lCj4gV2hlbiBhIGRpcmVjdG9yeSBoYXMgaW5oZXJpdGFibGUgQUNMIGVudHJpZXMs IHRoZSBmb2xsb3dpbmcKPiBoYXBwZW5zIHdoZW4gYSBmaWxlIG9yIGRpcmVjdG9yeSBpcyBjcmVh dGVkIGluc2lkZSB0aGF0IGRpcmVjdG9yeToKPiAuUlMgNAo+IC5JUCAxLiA0Cj4gQSBmaWxlIGNy ZWF0ZWQgaW5zaWRlIHRoYXQgZGlyZWN0b3J5IHdpbGwgaW5oZXJpdCBhbGwgb2YgdGhlIEFDTCBl bnRyaWVzIHRoYXQKPiBoYXZlIHRoZQo+IC5CIGZpbGVfaW5oZXJpdAo+IGZsYWcgc2V0LCBhbmQg YWxsIGluaGVyaXRhbmNlLXJlbGF0ZWQgZmxhZ3MgaW4gdGhlIGluaGVyaXRlZCBlbnRyaWVzIHdp bGwgYmUKPiBjbGVhcmVkLgo+IAo+IEEgc3ViZGlyZWN0b3J5IGNyZWF0ZWQgaW5zaWRlIHRoYXQg ZGlyZWN0b3J5IHdpbGwgaW5oZXJpdCBhbGwgb2YgdGhlIEFDTAo+IGVudHJpZXMgdGhhdCBoYXZl IHRoZQo+IC5CIGZpbGVfaW5oZXJpdAo+IG9yCj4gLkIgZGlyX2luaGVyaXQKPiBmbGFnIHNldC4g IEVudHJpZXMgd2hvc2UKPiAuQiBub19wcm9wYWdhdGUKPiBmbGFnIGlzIHNldCB3aWxsIGhhdmUg YWxsIGluaGVyaXRhbmNlLXJlbGF0ZWQgZmxhZ3MgY2xlYXJlZC4gIEVudHJpZXMgd2hvc2UKPiAu QiBub19wcm9wYWdhdGUKPiBhbmQKPiAuQiBkaXJfaW5oZXJpdAo+IGZsYWdzIGFyZSBub3Qgc2V0 IGFuZCB3aG9zZQo+IC5CIGZpbGVfaW5oZXJpdAo+IGlzIHNldCB3aWxsIGhhdmUgdGhlaXIKPiAu QiBpbmhlcml0X29ubHkKPiBmbGFnIHNldC4KPiAuSVAgMi4KPiBJZiB0aGUgcGFyZW50IGRpcmVj dG9yeSdzIEFDTCBoYXMgdGhlCj4gLkIgYXV0b19pbmhlcml0Cj4gZmxhZyBzZXQsIHRoZSBpbmhl cml0ZWQgQUNMIHdpbGwgaGF2ZSBpdHMKPiAuQiBhdXRvX2luaGVyaXQKPiBmbGFnIHNldCwgYW5k IGFsbCBlbnRyaWVzIHdpbGwgaGF2ZSB0aGVpcgo+IC5CIGluaGVyaXRlZAo+IGZsYWcgc2V0Lgo+ IC5JUCAzLgo+IFRoZSB0aHJlZSBmaWxlIG1hc2tzIGFyZSBjb21wdXRlZCBmcm9tIHRoZSBpbmhl cml0ZWQgQUNMIGFzIGRlc2NyaWJlZCBpbgo+IHRoZSBzZWN0aW9uCj4gLklSICJDb21wdXRpbmcg dGhlIG1heGltdW0gZmlsZSBtYXNrcyIgLgo+IC5JUCA0Lgo+IFRoZSB0aHJlZSBzZXRzIG9mIHBl cm1pc3Npb25zIGZvciB0aGUgb3duZXIsIHRoZSBncm91cCwgYW5kIGZvciBvdGhlcnMgaW4KPiB0 aGUgXGZJbW9kZVxmUiBwYXJhbWV0ZXIgYXMgZ2l2ZW4gdG8KPiAuQlIgb3BlbiAoMiksCj4gLkJS IG1rZGlyICgyKSwKPiBhbmQgc2ltaWxhciBhcmUgY29udmVydGVkIGludG8gc2V0cyBvZiBSaWNo QUNMIHBlcm1pc3Npb25zIGFzIGRlc2NyaWJlZCBpbgo+IHRoZSBzZWN0aW9uCj4gLklSICJDaGFu Z2luZyB0aGUgZmlsZSBtb2RlIHBlcm1pc3Npb24gYml0cyIgLgo+IEFueSBSaWNoQUNMIHBlcm1p c3Npb25zIG5vdCBpbmNsdWRlZCBpbiB0aG9zZSBzZXRzIGFyZQo+IHJlbW92ZWQgZnJvbSB0aGUg b3duZXIsIGdyb3VwLCBhbmQgb3RoZXIgZmlsZSBtYXNrcy4gVGhlIGZpbGUgbW9kZSBwZXJtaXNz aW9uCj4gYml0cyBhcmUgdGhlbiBjb21wdXRlZCBmcm9tIHRoZSBmaWxlIG1hc2tzIGFzIGRlc2Ny aWJlZCBpbiB0aGUgc2VjdGlvbgo+IC5JUiAiQXNzaWduaW5nIGFuIEFjY2VzcyBDb250cm9sIExp c3QiIC4KPiBUaGUgcHJvY2VzcyB1bWFzayAoc2VlCj4gLkJSIHVtYXNrICgyKSkKPiBpcyBpZ25v cmVkLgo+IC5JUCA1Lgo+IFRoZQo+IC5CIG1hc2tlZAo+IEFDTCBmbGFnIGlzIHNldC4gVGhlCj4g LkIgd3JpdGVfdGhyb3VnaAo+IEFDTCBmbGFnIHJlbWFpbnMgY2xlYXJlZC4gSW4gYWRkaXRpb24s IGlmIHRoZQo+IC5CIGF1dG9faW5oZXJpdAo+IGZsYWcgb2YgdGhlIGluaGVyaXRlZCBBQ0wgaXMg c2V0LCB0aGUKPiAuQiBwcm90ZWN0ZWQKPiBmbGFnIGlzIGFsc28gc2V0IHRvIHByZXZlbnQgdGhl IEF1dG9tYXRpYyBJbmhlcml0YW5jZSBhbGdvcml0aG0gZnJvbSBtb2RpZnlpbmcKPiB0aGUgQUNM Lgo+IC5SRQo+IC5QUAo+IFdoZW4gYSBkaXJlY3RvcnkgZG9lcyBub3QgaGF2ZSBpbmhlcml0YWJs ZSBBQ0wgZW50cmllcywgZmlsZXMgYW5kIGRpcmVjdG9yaWVzCj4gY3JlYXRlZCBpbnNpZGUgdGhh dCBkaXJlY3Rvcnkgd2lsbCBub3QgYmUgYXNzaWduZWQgYWNjZXNzIGNvbnRyb2wgbGlzdHMgYW5k IHRoZQo+IGZpbGUgbW9kZSBwZXJtaXNzaW9uIGJpdHMgd2lsbCBiZSBzZXQgdG8gKFxmSW1vZGVc ZlJcICZcIH5cZkl1bWFza1xmUikgd2hlcmUKPiBcZkltb2RlXGZSIGlzIHRoZSBtb2RlIGFyZ3Vt ZW50IG9mIHRoZSByZWxldmFudCBzeXN0ZW0gY2FsbCBhbmQgXGZJdW1hc2tcZlIgaXMKPiB0aGUg cHJvY2VzcyB1bWFzayAoc2VlCj4gLkJSIHVtYXNrICgyKSkuCj4gCj4gLlNTIEF1dG9tYXRpYyBJ bmhlcml0YW5jZQo+IEF1dG9tYXRpYyBJbmhlcml0YW5jZSBpcyBhIG1lY2hhbmlzbSB0aGF0IGFs bG93cyBwZXJtaXNzaW9uIGNoYW5nZXMgdG8KPiBwcm9wYWdhdGUgZnJvbSBhIGRpcmVjdG9yeSB0 byBmaWxlcyBhbmQgc3ViZGlyZWN0b3JpZXMgaW5zaWRlIHRoYXQgZGlyZWN0b3J5LAo+IHJlY3Vy c2l2ZWx5LiAgUHJvcGFnYXRpb24gaXMgY2FycmllZCBvdXQgYnkgdGhlIHByb2Nlc3MgY2hhbmdp bmcgdGhlIGRpcmVjdG9yeQo+IHBlcm1pc3Npb25zICh1c3VhbGx5LAo+IC5CUiBzZXRyaWNoYWNs ICgxKSk7Cj4gaXQgaGFwcGVucyB3aXRob3V0IHVzZXIgaW50ZXJ2ZW50aW9uIGFsYmVpdCBub3Qg ZW50aXJlbHkgYXV0b21hdGljYWxseS4KPiAKPiBBIHNpZ25pZmljYW50IGxpbWl0YXRpb24gaXMg dGhhdCB0aGlzIG1lY2hhbmlzbSB3b3JrcyBvbmx5IGFzIGxvbmcgYXMgZmlsZXMKPiBhcmUgY3Jl YXRlZCB3aXRob3V0IGV4cGxpY2l0bHkgc3BlY2lmeWluZyB0aGUgZmlsZSBwZXJtaXNzaW9ucyB0 byB1c2UuIFRoZQo+IHN0YW5kYXJkIHN5c3RlbSBjYWxscyBmb3IgY3JlYXRpbmcgZmlsZXMgYW4g ZGlyZWN0b3JpZXMgKAoKcy9hbiAvYW5kIC8Kcy8gKCQvLwoKPiAuQlIgY3JlYXQgKDIpLAoKTWFr ZSB0aGF0IGxhc3QgbGluZToKCi5STSAoIGNyZWF0ICgyKSwKCj4gLkJSIG9wZW4gKDIpLAo+IC5C UiBta2RpciAoMiksCj4gLkJSIG1rbm9kICgyKSkKPiBhbGwgaGF2ZSBtYW5kYXRvcnkgbW9kZSBw YXJhbWV0ZXJzIHdoaWNoIGRlZmluZSB0aGUgbWF4aW11bSBhbGxvd2VkIHBlcm1pc3Npb25zCj4g b2YgdGhlIG5ldyBmaWxlcy4gVG8gdGFrZSBhY2NvdW50IG9mIHRoaXMgcmVzdHJpY3Rpb24sIHRo ZQo+IC5CIHByb3RlY3RlZAo+IEFDTCBmbGFnIG11c3QgYmUgc2V0IGlmIHRoZQo+IC5CIGluaGVy aXRlZAo+IGZsYWcgaXMgc2V0LiBUaGlzIGVmZmVjdGl2ZWx5IGRpc2FibGVzIEF1dG9tYXRpYyBJ bmhlcml0YW5jZSBmb3IgdGhhdAo+IHBhcnRpY3VsYXIgZmlsZS4KPiAKPiBBdXRvbWF0aWMgSW5o ZXJpdGFuY2Ugc3RpbGwgcmVtYWlucyB1c2VmdWwgZm9yIG5ldHdvcmsgcHJvdG9jb2xzIGxpa2Ug TkZTdjQgYW5kCj4gU01CLCB3aGljaCBib3RoIHN1cHBvcnQgY3JlYXRpbmcgZmlsZXMgYW5kIGRp cmVjdG9yaWVzIHdpdGhvdXQgZGVmaW5pbmcgd2hpY2gKCnMvd2hpY2gkL3RoZWlyLwoKPiBwZXJt aXNzaW9uczogdGhleSBjYW4gaW1wbGVtZW50IHRob3NlIG9wZXJhdGlvbnMgYnkgdXNpbmcgdGhl IHN0YW5kYXJkIHN5c3RlbQo+IGNhbGxzIGFuZCBieSB0aGVuIHVuZG9pbmcgdGhlIGVmZmVjdCBv ZiBhcHBseWluZyB0aGUgbW9kZSBwYXJhbWV0ZXJzLgo+IAo+IFdoZW4gdGhlIEFDTCBvZiBhIGRp cmVjdG9yeSBpcyBjaGFuZ2VkLCB0aGUgZm9sbG93aW5nIGhhcHBlbnMgZm9yIGVhY2ggZW50cnkK PiAoXChscWNoaWxkXChycSkgaW5zaWRlIHRoYXQgZGlyZWN0b3J5Ogo+IC5JUCAxLiA0Cj4gSWYg dGhlIGVudHJ5IGlzIGEgc3ltYmxpYyBsaW5rLCBza2lwIHRoZSBjaGlsZC4KPiAuSVAgMi4KPiBJ ZiB0aGUKPiAuQiBhdXRvX2luaGVyaXQKPiBmbGFnIG9mIHRoZSBlbnRyeSdzIEFDTCBpcyBub3Qg c2V0IG9yIHRoZQo+IC5CIHByb3RlY3RlZAo+IGZsYWcgaXMgc2V0LCBza2lwIHRoZSBjaGlsZC4K PiAuSVAgMy4KPiBXaXRoIHRoZSBjaGlsZCdzIEFDTDoKPiAuUlMgNAo+IC5JUCBhKSA0Cj4gSWYg dGhlCj4gLkIgZGVmYXVsdGVkCj4gZmxhZyBpcyBzZXQsIHJlcGxhY2UgdGhlIEFDTCB3aXRoIGFu IGVtcHR5IEFDTAo+IHdpdGggdGhlCj4gLkIgYXV0b19pbmhlcml0Cj4gZmxhZyBzZXQuCj4gLklQ IGIpCj4gRGVsZXRlIGFsbCBlbnRyaWVzIHdoaWNoIGhhdmUgdGhlCj4gLkIgaW5oZXJpdGVkCj4g ZmxhZyBzZXQuCj4gLklQIGMpCj4gQXBwZW5kIGFsbCBlbnRyaWVzIGluaGVyaXRlZCBmcm9tIHRo ZSBwYXJlbnQgZGlyZWN0b3J5IGFjY29yZGluZyB0byBzdGVwIDEgb2YKPiB0aGUgYWxnb3JpdGht IGRlc2NyaWJlZCB1bmRlcgo+IC5JUiAiUGVybWlzc2lvbnMgYXQgZmlsZS1jcmVhdGlvbiB0aW1l Ii4KPiBTZXQgdGhlCj4gLkIgaW5oZXJpdGVkCj4gZmxhZyBvZiBlYWNoIG9mIHRoZXNlIGVudHJp ZXMuCj4gLklQIGQpCj4gUmVjb21wdXRlIHRoZSBmaWxlIG1hc2tzLgo+IC5SRQo+IC5JUCA0Lgo+ IElmIHRoZSBjaGlsZCBpcyBhIGRpcmVjdG9yeSwgcmVjdXJzaXZlbHkgYXBwbHkgdGhpcyBhbGdv cml0aG0uCj4gCj4gLlNTIEFjY2VzcyBjaGVjayBhbGdvcml0aG0KPiAKPiBXaGVuIGEgcHJvY2Vz cyByZXF1ZXN0cyBhIHBhcnRpY3VsYXIga2luZCBvZiBhY2Nlc3MgKGV4cHJlc3NlZCBhcyBhIHNl dCBvZgo+IFJpY2hBQ0wgcGVybWlzc2lvbnMpIHRvIGEgZmlsZSwgdGhlIGZvbGxvd2luZyBhbGdv cml0aG0gZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZQo+IGFjY2VzcyBpcyBncmFudGVkIG9yIGRlbmll ZDoKPiAKPiAuSVAgMS4gNAo+IElmIHRoZQo+IC5CIG1hc2tlZAo+IEFDTCBmbGFnIGlzIHNldCwg dGhlbjoKPiAuUlMgNAo+IC5JUCBhKSA0Cj4gSWYgdGhlCj4gLkIgd3JpdGVfdGhyb3VnaAo+IEFD TCBmbGFnIGlzIHNldCwgdGhlbjoKPiAuUlMgNAo+IC5JUCBcKGJ1IDQKPiBJZiB0aGUgcmVxdWVz dGluZyBwcm9jZXNzIGlzIHRoZSBmaWxlIG93bmVyLCB0aGVuIGFjY2VzcyBpcyBncmFudGVkIGlm IHRoZQo+IG93bmVyIG1hc2sgaW5jbHVkZXMgdGhlIHJlcXVlc3RlZCBwZXJtaXNzaW9ucywgYW5k IGlzIG90aGVyd2lzZSBkZW5pZWQuCj4gLklQIFwoYnUKPiBJZiB0aGUgcmVxdWVzdGluZyBwcm9j ZXNzIGlzIG5vdCB0aGUgZmlsZSBvd25lciwgaXMgbm90IGluIHRoZSBvd25pbmcgZ3JvdXAsCj4g YW5kIG5vIEFDTCBlbnRyaWVzIG90aGVyIHRoYW4KPiAuQiBldmVyeW9uZUAKPiBtYXRjaCB0aGUg cHJvY2VzcywgdGhlbiBhY2Nlc3MgaXMgZ3JhbnRlZCBpZiB0aGUgb3RoZXIgbWFzayBpbmNsdWRl cyB0aGUKPiByZXF1ZXN0ZWQgcGVybWlzc2lvbnMsIGFuZCBpcyBvdGhlcndpc2UgZGVuaWVkLgo+ IC5SRQo+IC5JUCBiKQo+IElmIGFueSBvZiB0aGUgZm9sbG93aW5nIGlzIHRydWU6Cj4gLlJTIDQK PiAuSVAgXChidSA0Cj4gdGhlIHJlcXVlc3RpbmcgcHJvY2VzcyBpcyB0aGUgZmlsZSBvd25lciBh bmQgdGhlIG93bmVyIG1hc2sgZG9lcyBub3QgaW5jbHVkZSBhbGwKPiByZXF1ZXN0ZWQgcGVybWlz c2lvbnMsCj4gLklQIFwoYnUgNAo+IHRoZSByZXF1ZXN0aW5nIHByb2Nlc3MgaXMgbm90IHRoZSBm aWxlIG93bmVyIGFuZCBpdCBpcyBpbiB0aGUgb3duaW5nIGdyb3VwIG9yCj4gbWF0Y2hlcyBhbnkg QUNMIGVudHJpZXMgb3RoZXIgdGhhbgo+IC5CUiBldmVyeW9uZUAgLAo+IGFuZCB0aGUgZ3JvdXAg bWFzayBkb2VzIG5vdCBpbmNsdWRlIGFsbCByZXF1ZXN0ZWQgcGVybWlzc2lvbnMsCj4gLklQIFwo YnUgNAo+IHRoZSByZXF1ZXN0aW5nIHByb2Nlc3MgaXMgbm90IHRoZSBmaWxlIG93bmVyLCBub3Qg aW4gdGhlIG93bmluZyBncm91cCwgaXQKPiBtYXRjaGVzIG5vIEFDTCBlbnRyaWVzIG90aGVyIHRo YW4KPiAuQlIgZXZlcnlvbmVAICwKPiBhbmQgdGhlIG90aGVyIG1hc2sgZG9lcyBub3QgaW5jbHVk ZSBhbGwgcmVxdWVzdGVkIHBlcm1pc3Npb25zLAo+IC5QUAo+IHRoZW4gYWNjZXNzIGlzIGRlbmll ZC4KPiAuUkUKPiAuUkUKPiAuSVAgMi4KPiBTZXQgdGhlIHJlbWFpbmluZyBwZXJtaXNzaW9ucyB0 byB0aGUgcmVxdWVzdGVkIHBlcm1pc3Npb25zLiAgR28gdGhyb3VnaCBhbGwgQUNMCj4gZW50cmll cy4gRm9yIGVhY2ggZW50cnk6Cj4gLlJTIDQKPiAuSVAgYSkgNAo+IElmIHRoZQo+IC5CIGluaGVy aXRfb25seQo+IG9yCj4gLkIgdW5tYXBwZWQKPiBmbGFncyBhcmUgc2V0LCBjb250aW51ZSB3aXRo IHRoZSBuZXh0IEFDTCBlbnRyeS4KPiAuSVAgYikKPiBJZiBhbnkgb2YgdGhlIGZvbGxvd2luZyBp cyB0cnVlOgo+IC5SUyA0Cj4gLklQIFwoYnUgNAo+IHRoZSBlbnRyeSdzIGlkZW50aWZpZXIgaXMK PiAuQiBvd25lckAKPiBhbmQgdGhlIHJlcXVlc3RpbmcgcHJvY2VzcyBpcyB0aGUgZmlsZSBvd25l ciwKPiAuSVAgXChidQo+IHRoZSBlbnRyeSdzIGlkZW50aWZpZXIgaXMKPiAuQiBncm91cEAKPiBh bmQgdGhlIHJlcXVlc3RpbmcgcHJvY2VzcyBpcyBpbiB0aGUgb3duaW5nIGdyb3VwLAo+IC5JUCBc KGJ1Cj4gdGhlIGVudHJ5J3MgaWRlbnRpZmllciBpcyBhIHVzZXIgYW5kIHRoZSByZXF1ZXN0aW5n IHByb2Nlc3MgaXMgb3duZWQgYnkgdGhhdAo+IHVzZXIsCj4gLklQIFwoYnUKPiB0aGUgZW50cnkn cyBpZGVudGlmaWVyIGlzIGEgZ3JvdXAgYW5kIHRoZSByZXF1ZXN0aW5nIHByb2Nlc3MgaXMgYSBt ZW1iZXIgaW4KPiB0aGF0IGdyb3VwLAo+IC5JUCBcKGJ1Cj4gdGhlIGVudHJ5J3MgaWRlbnRpZmll ciBpcwo+IC5CUiBldmVyeW9uZUAgLAo+IC5QUAo+IHRoZW4gdGhlIGVudHJ5IG1hdGNoZXMgdGhl IHByb2Nlc3M7IHByb2NlZWQgdG8gdGhlIG5leHQgc3RlcC4gT3RoZXJ3aXNlLAo+IGNvbnRpbnVl IHdpdGggdGhlIG5leHQgQUNMIGVudHJ5Lgo+IC5SRQo+IC5JUCBjKQo+IElmIHRoZSBlbnRyeSBk ZW5pZXMgYW55IG9mIHRoZSByZW1haW5pbmcgcGVybWlzc2lvbnMsIGFjY2VzcyBpcyBkZW5pZWQu Cj4gLklQIGQpCj4gSWYgdGhlIGVudHJ5IGFsbG93cyBhbnkgb2YgdGhlIHJlbWFpbmluZyBwZXJt aXNzaW9ucywgdGhlbjoKPiAuUlMgNAo+IC5JUCBcKGJ1IDQKPiBJZiB0aGUKPiAuQiBtYXNrZWQK PiBBQ0wgZmxhZyBpcyBzZXQgYW5kIHRoZSBlbnRyeSdzIGlkZW50aWZpZXIgaXMgbm90Cj4gLkIg b3duZXJACj4gb3IKPiAuQlIgZXZlcnlvbmVACj4gb3IgaXMgYSB1c2VyIGVudHJ5IG1hdGNoaW5n IHRoZSBmaWxlIG93bmVyLCByZW1vdmUgYWxsIHBlcm1pc3Npb25zIGZyb20gdGhlCj4gcmVtYWlu aW5nIHBlcm1pc3Npb25zIHdoaWNoIGFyZSBib3RoIGFsbG93ZWQgYnkgdGhlIGVudHJ5IGFuZCBp bmNsdWRlZCBpbiB0aGUKPiBncm91cCBtYXNrLAo+IC5JUCBcKGJ1Cj4gT3RoZXJ3aXNlLCByZW1v dmUgYWxsIHBlcm1pc3Npb25zIGZyb20gdGhlIHJlbWFpbmluZyBwZXJtaXNzaW9ucyB3aWNoIGFy ZQo+IGFsbG93ZWQgYnkgdGhlIGVudHJ5Lgo+IC5SRQo+IC5SRQo+IC5JUCAzLgo+IElmIHRoZXJl IGFyZSBubyBtb3JlIHJlbWFpbmluZyBwZXJtaXNzaW9ucywgYWNjZXNzIGlzIGFsbG93ZWQuIE90 aGVyd2lzZSwKPiBhY2Nlc3MgaXMgZGVuaWVkLgo+IAo+IC5TUyBDb21wdXRpbmcgdGhlIG1heGlt dW0gZmlsZSBtYXNrcwo+IFdoZW4gc2V0dGluZyBhbiBBQ0wgYW5kIG5vIGZpbGUgbWFza3MgaGF2 ZSBiZWVuIGV4cGxpY2l0bHkgc3BlY2lmaWVkIGFuZCB3aGVuCj4gaW5oZXJpdGluZyBhbiBBQ0wg ZnJvbSB0aGUgcGFyZW50IGRpcmVjdG9yeSwgdGhlIGZvbGxvd2luZyBhbGdvcml0aG0gaXMgdXNl ZAo+IGZvciBjb21wdXRpbmcgdGhlIGZpbGUgbWFza3M6Cj4gCj4gLklQIDEuIDQKPiBDbGVhciB0 aGUgb3duZXIsIGdyb3VwLCBhbmQgb3RoZXIgZmlsZSBtYXNrcy4gUmVtZW1iZXIgd2hpY2ggcGVy bWlzc2lvbnMgaGF2ZQo+IGFscmVhZHkgYmVlbiBwcm9jZXNzZWQgKGluaXRpYWxseSwgdGhlIGVt cHR5IHNldCkuCj4gLklQIDIuCj4gRm9yIGVhY2ggQUNMIGVudHJ5Ogo+IC5SUyA0Cj4gLklQIFwo YnUgNAo+IElmIHRoZQo+IC5CIGluaGVyaXRfb25seQo+IGZsYWcgaXMgc2V0LCBza2lwIHRoZSBl bnRyeS4KPiAuSVAgXChidSA0Cj4gT3RoZXJ3aXNlLCBjb21wdXRlIHdoaWNoIHBlcm1pc3Npb25z IHRoZSBlbnRyeSBhbGxvd3Mgb3IgZGVuaWVzIHRoYXQgaGF2ZSBub3QKPiBiZWVuIHByb2Nlc3Nl ZCB5ZXQgKHRoZSByZW1haW5pbmcgcGVybWlzc2lvbnMpLgo+IC5JUCBcKGJ1Cj4gSWYgdGhlIGVu dHJ5IGlzIGFuCj4gLkIgb3duZXJACj4gZW50cnksIGFkZCB0aGUgcmVtYWluaW5nIHBlcm1pc3Np b25zIHRvIHRoZSBvd25lciBtYXNrIGZvcgo+IC5CIGFsbG93Cj4gZW50cmllcywgYW5kIHJlbW92 ZSB0aGUgcmVtYWluaW5nIHBlcm1pc3Npb25zIGZyb20gdGhlIG93bmVyIG1hc2sgZm9yCj4gLkIg ZGVueQo+IGVudHJpZXMuCj4gLklQIFwoYnUKPiBPdGhlcndpc2UsIGlmIHRoZSBlbnRyeSBpcyBh bgo+IC5CIGV2ZXJ5b25lQAo+IGVudHJ5LCBwcm9jZWVkIGFzIHdpdGgKPiAuQiBvd25lckAKPiBl bnRyaWVzIGJ1dCBhZGQgb3IgcmVtb3ZlIHRoZSByZW1haW5pbmcgcGVybWlzc2lvbnMgZnJvbSB0 aGUgb3duZXIsIGdyb3VwLCBhbmQKPiBvdGhlciBmaWxlIG1hc2tzLgo+IC5JUCBcKGJ1Cj4gT3Ro ZXJ3aXNlLCBwcm9jZWVkIGFzIHdpdGgKPiAuQiBvd25lckAKPiBlbnRyaWVzIGJ1dCBhZGQgb3Ig cmVtb3ZlIHRoZSByZW1haW5pbmcgcGVybWlzc2lvbnMgZnJvbSB0aGUgb3duZXIgYW5kIGdyb3Vw Cj4gZmlsZSBtYXNrcy4KPiAuSVAgXChidQo+IEFkZCB0aGUgZW50cnkncyBwZXJtaXNzaW9ucyB0 byB0aGUgcHJvY2Vzc2VkIHBlcm1pc3Npb25zLgo+IC5SRQo+IC5QUAo+IFRoZSByZXN1bHRpbmcg ZmlsZSBtYXNrcyByZXByZXNlbnQgdGhlIEFDTCBhcyBjbG9zZWx5IGFzIHBvc3NpYmxlLiBXaXRo IHRoZXNlCj4gZmlsZSBtYXNrcywgaWYgdGhlCj4gLkIgbWFza2VkCj4gQUNMIGZsYWcgaXMgc2V0 LCB0aGUgZWZmZWN0aXZlIHBlcm1pc3Npb25zIHN0aWxsIHN0YXkgdGhlIHNhbWUuCj4gCj4gLlwi IC5TSCBCVUdTCj4gLlNIIEFVVEhPUgo+IFdyaXR0ZW4gYnkgQW5kcmVhcyBHcsO8bmJhY2hlciA8 YWdydWVuYmFAcmVkaGF0LmNvbT4uCj4gCj4gUGxlYXNlIHNlbmQgeW91ciBidWcgcmVwb3J0cywg c3VnZ2VzdGVkIGZlYXR1cmVzIGFuZCBjb21tZW50cyB0byB0aGUgYWJvdmUgYWRkcmVzcy4KCkNv dWxkIHdlIHN0YXJ0IHdpdGgganVzdCBhIGZldyBzaW1wbGUgZXhhbXBsZXMgYWxyZWFkeSwgYW5k IGJ1aWxkIHVwCm92ZXIgZnV0dXJlIGl0ZXJhdGlvbnMgb2YgdGhpcyBwYWdlPwoKPiAuU0ggQ09O Rk9STUlORyBUTwo+IFJpY2ggQWNjZXNzIENvbnRyb2wgTGlzdHMgYXJlIExpbnV4LXNwZWNpZmlj Lgo+IC5TSCBTRUUgQUxTTwo+IC5CUiBhY2wgKDUpLAo+IC5CUiBjaG1vZCAoMSksCj4gLkJSIGdl dHJpY2hhY2wgKDEpLAo+IC5CUiBscyAoMSksCj4gLkJSIHNldHJpY2hhY2wgKDEpCj4gLkJSIHN0 YXQgKDIpLAo+IC5CUiB1bWFzayAoMikKPiAuXCIgbGlicmljaGFjbAoKVGhhbmtzLAoKTWljaGFl bAoKLS0gCk1pY2hhZWwgS2VycmlzawpMaW51eCBtYW4tcGFnZXMgbWFpbnRhaW5lcjsgaHR0cDov L3d3dy5rZXJuZWwub3JnL2RvYy9tYW4tcGFnZXMvCkxpbnV4L1VOSVggU3lzdGVtIFByb2dyYW1t aW5nIFRyYWluaW5nOiBodHRwOi8vbWFuNy5vcmcvdHJhaW5pbmcvCgpfX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwp4ZnMgbWFpbGluZyBsaXN0Cnhmc0Bvc3Mu c2dpLmNvbQpodHRwOi8vb3NzLnNnaS5jb20vbWFpbG1hbi9saXN0aW5mby94ZnMK