From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.1 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,MENTIONS_GIT_HOSTING, NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8465DC433DF for ; Thu, 15 Oct 2020 11:24:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0A34520878 for ; Thu, 15 Oct 2020 11:24:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KC9BPD5G" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727719AbgJOLXt (ORCPT ); Thu, 15 Oct 2020 07:23:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56576 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726018AbgJOLXt (ORCPT ); Thu, 15 Oct 2020 07:23:49 -0400 Received: from mail-wm1-x342.google.com (mail-wm1-x342.google.com [IPv6:2a00:1450:4864:20::342]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82EB9C061755; Thu, 15 Oct 2020 04:23:48 -0700 (PDT) Received: by mail-wm1-x342.google.com with SMTP id p15so2773523wmi.4; Thu, 15 Oct 2020 04:23:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=cc:subject:to:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=GmEVmU88O8qTiwUb+ICW1QOn1EEa3s/908Lo1d+XEAY=; b=KC9BPD5GvkT8f7maqCMdJoPtbT9r/F6jN6s3KjF6ZbDtA9MoFFRkdR8bUUuqJkJCt3 iVzVMSI2SodaAjbbOe1VX7rtYR1LiqcdcbPC9c4Br1nM7t9/po/D0TLKkBkOyJycbeoA a1wiQ0tuWCbYU/7QwpQjvOkXBLnECrjYp8E1VNy1tyu0+bo2/Y5L10MvdpdfgjM1Ks1+ iiX+pSXPCOpQiUAm0a44hSDuvYCw+/rPbkou2ZZGbSaLjEj0F9Ikf0bW3uJZrgWjftR0 DdP8IMeRWNNnqf74ct7ieiZCrn16MW4NBGzy158dRKIuYDod/pL5ZfcF7OXgBCU1tDY0 duvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:cc:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=GmEVmU88O8qTiwUb+ICW1QOn1EEa3s/908Lo1d+XEAY=; b=UnkZzQpLcF0cjo1l32VZy91zwFp0WWW+AiuefrZLzbvH4UV54IfUE0QtnZLzt1PK+0 n/pB4QBqQKNVlM2Z1iHQlMWh7fDruYH7afLYcCPbAmZRAkt4ToqdyhLtnq5G5ejVYfJG 0+eGbXsc7HGMBxNo+EOy+id/6uL4cnRGV5Xi5jjYdzc/YX/q6HV07ZRjPXnlbRVTFRPo HVfGEWLNwzGVokU+a5Of962JrfTbzxVvXMsRcU0tnkG58u1wc4+06Dzpj1/0dyP/mfCQ wtBhH3WFAhw9C4rck7Zglafr46geSk+n75hCF5R8mQJ0SCCayJ1VWEXwLTysZqwHRkFh HAkg== X-Gm-Message-State: AOAM5307ck1tOgbB+aT2sBroSYyHi0755hLIlcRLnRMJaVN44Jm3RpRW /9+M9Esr8NopcntFHal87Pc= X-Google-Smtp-Source: ABdhPJwyufiojU8J691nXzhj6hk9Qnf4xI2ezsyZEgQZFG9kqq1kcH4x83jUdaD+8QpHVcQukgX0xQ== X-Received: by 2002:a1c:7d54:: with SMTP id y81mr3368720wmc.114.1602761025714; Thu, 15 Oct 2020 04:23:45 -0700 (PDT) Received: from [192.168.1.10] (static-176-175-73-29.ftth.abo.bbox.fr. [176.175.73.29]) by smtp.gmail.com with ESMTPSA id y7sm3898721wmg.40.2020.10.15.04.23.43 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 15 Oct 2020 04:23:44 -0700 (PDT) Cc: mtk.manpages@gmail.com, Tycho Andersen , Sargun Dhillon , linux-man , Song Liu , wad@chromium.org, Kees Cook , Daniel Borkmann , Jann Horn , Robert Sesek , Linux Containers , lkml , Alexei Starovoitov , Giuseppe Scrivano , bpf@vger.kernel.org, Andy Lutomirski , Christian Brauner Subject: Re: For review: seccomp_user_notif(2) manual page To: Christian Brauner References: <45f07f17-18b6-d187-0914-6f341fe90857@gmail.com> <20201001123619.fdlk2xb56lej6rx3@gmail.com> From: "Michael Kerrisk (man-pages)" Message-ID: <3cd4826a-074e-e863-af70-43a80a996e58@gmail.com> Date: Thu, 15 Oct 2020 13:23:43 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.11.0 MIME-Version: 1.0 In-Reply-To: <20201001123619.fdlk2xb56lej6rx3@gmail.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Hello Christian, On 10/1/20 2:36 PM, Christian Brauner wrote: > [I'm on vacation so I'll just give this a quick glance for now.] > > On Wed, Sep 30, 2020 at 01:07:38PM +0200, Michael Kerrisk (man-pages) wrote: >> Hi Tycho, Sargun (and all), >> >> I knew it would be a big ask, but below is kind of the manual page >> I was hoping you might write [1] for the seccomp user-space notification >> mechanism. Since you didn't (and because 5.9 adds various new pieces >> such as SECCOMP_ADDFD_FLAG_SETFD and SECCOMP_IOCTL_NOTIF_ADDFD >> that also will need documenting [2]), I did :-). But of course I may >> have made mistakes... >> >> I've shown the rendered version of the page below, and would love >> to receive review comments from you and others, and acks, etc. >> >> There are a few FIXMEs sprinkled into the page, including one >> that relates to what appears to me to be a misdesign (possibly >> fixable) in the operation of the SECCOMP_IOCTL_NOTIF_RECV >> operation. I would be especially interested in feedback on that >> FIXME, and also of course the other FIXMEs. >> >> The page includes an extensive (albeit slightly contrived) >> example program, and I would be happy also to receive comments >> on that program. >> >> The page source currently sits in a branch (along with the text >> that you sent me for the seccomp(2) page) at >> https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/log/?h=seccomp_user_notif >> >> Thanks, >> >> Michael >> >> [1] https://lore.kernel.org/linux-man/2cea5fec-e73e-5749-18af-15c35a4bd23c@gmail.com/#t >> [2] Sargun, can you prepare something on SECCOMP_ADDFD_FLAG_SETFD >> and SECCOMP_IOCTL_NOTIF_ADDFD to be added to this page? >> >> ===== >> >> NAME >> seccomp_user_notif - Seccomp user-space notification mechanism >> >> SYNOPSIS >> #include >> #include >> #include >> >> int seccomp(unsigned int operation, unsigned int flags, void *args); >> >> DESCRIPTION >> This page describes the user-space notification mechanism pro‐ >> vided by the Secure Computing (seccomp) facility. As well as the >> use of the SECCOMP_FILTER_FLAG_NEW_LISTENER flag, the SEC‐ >> COMP_RET_USER_NOTIF action value, and the SECCOMP_GET_NOTIF_SIZES >> operation described in seccomp(2), this mechanism involves the >> use of a number of related ioctl(2) operations (described below). >> >> Overview >> In conventional usage of a seccomp filter, the decision about how >> to treat a particular system call is made by the filter itself. >> The user-space notification mechanism allows the handling of the >> system call to instead be handed off to a user-space process. > > "In contrast, the user notification mechanism allows to delegate the > handling of the system call of one process (target) to another > user-space process (supervisor)."? Thanks. I've reworded similarly to what you suggest. >> The advantages of doing this are that, by contrast with the sec‐ >> comp filter, which is running on a virtual machine inside the >> kernel, the user-space process has access to information that is >> unavailable to the seccomp filter and it can perform actions that >> can't be performed from the seccomp filter. > > This section reads a bit difficult imho: > "A suitably privileged supervisor can use the user notification > mechanism to perform actions in lieu of the target. The supervisor will > usually be able to retrieve information about the target and the > performed system call that the seccomp filter itself cannot." Thanks. Again I've done some rewording. >> In the discussion that follows, the process that has installed >> the seccomp filter is referred to as the target, and the process >> that is notified by the user-space notification mechanism is >> referred to as the supervisor. An overview of the steps per‐ >> formed by these two processes is as follows: After the various rewordings, the opening paragraphs now read: In conventional usage of a seccomp filter, the decision about how to treat a system call is made by the filter itself. By contrast, the user-space notification mechanism allows the seccomp filter to delegate the handling of the system call to another user-space process. In the discussion that follows, the thread(s) on which the seccomp filter is installed is (are) referred to as the target, and the process that is notified by the user-space notification mechanism is referred to as the supervisor. A suitably privileged supervisor can use the user-space notifica‐ tion mechanism to perform actions on behalf of the target. The advantage of the user-space notification mechanism is that the supervisor will usually be able to retrieve information about the target and the performed system call that the seccomp filter itself cannot. (A seccomp filter is limited in the information it can obtain and the actions that it can perform because it is run‐ ning on a virtual machine inside the kernel.) An overview of the steps performed by the target and the supervi‐ sor is as follows: >> 1. The target process establishes a seccomp filter in the usual >> manner, but with two differences: >> >> · The seccomp(2) flags argument includes the flag SECCOMP_FIL‐ >> TER_FLAG_NEW_LISTENER. Consequently, the return value of >> the (successful) seccomp(2) call is a new "listening" file >> descriptor that can be used to receive notifications. > > I think it would be good to mention that seccomp notify fds are > O_CLOEXEC by default somewhere. Yep. This is already noted in seccomp(2). >> · In cases where it is appropriate, the seccomp filter returns >> the action value SECCOMP_RET_USER_NOTIF. This return value >> will trigger a notification event. >> >> 2. In order that the supervisor process can obtain notifications >> using the listening file descriptor, (a duplicate of) that >> file descriptor must be passed from the target process to the >> supervisor process. One way in which this could be done is by >> passing the file descriptor over a UNIX domain socket connec‐ >> tion between the two processes (using the SCM_RIGHTS ancillary >> message type described in unix(7)). Another possibility is >> that the supervisor might inherit the file descriptor via >> fork(2). > > I think a few people have already pointed out other ways of retrieving > an fd. :) Yup. >> 3. The supervisor process will receive notification events on the >> listening file descriptor. These events are returned as >> structures of type seccomp_notif. Because this structure and >> its size may evolve over kernel versions, the supervisor must >> first determine the size of this structure using the sec‐ >> comp(2) SECCOMP_GET_NOTIF_SIZES operation, which returns a >> structure of type seccomp_notif_sizes. The supervisor allo‐ >> cates a buffer of size seccomp_notif_sizes.seccomp_notif bytes >> to receive notification events. In addition,the supervisor >> allocates another buffer of size seccomp_notif_sizes.sec‐ >> comp_notif_resp bytes for the response (a struct sec‐ >> comp_notif_resp structure) that it will provide to the kernel >> (and thus the target process). >> >> 4. The target process then performs its workload, which includes >> system calls that will be controlled by the seccomp filter. >> Whenever one of these system calls causes the filter to return >> the SECCOMP_RET_USER_NOTIF action value, the kernel does not >> execute the system call; instead, execution of the target >> process is temporarily blocked inside the kernel and a notifi‐ > > Maybe mention that the task is killable when so blocked? Jann also noted this, and I thought it could be presumed, and so was not thinking to add anything to the text. But, since you mention it too, I've added some words to note that the sleep state is interruptible by signals. >> cation event is generated on the listening file descriptor. >> >> 5. The supervisor process can now repeatedly monitor the listen‐ >> ing file descriptor for SECCOMP_RET_USER_NOTIF-triggered >> events. To do this, the supervisor uses the SEC‐ >> COMP_IOCTL_NOTIF_RECV ioctl(2) operation to read information >> about a notification event; this operation blocks until an >> event is available. The operation returns a seccomp_notif >> structure containing information about the system call that is >> being attempted by the target process. >> >> 6. The seccomp_notif structure returned by the SEC‐ >> COMP_IOCTL_NOTIF_RECV operation includes the same information >> (a seccomp_data structure) that was passed to the seccomp fil‐ >> ter. This information allows the supervisor to discover the >> system call number and the arguments for the target process's >> system call. In addition, the notification event contains the >> PID of the target process. > > (Technically TID.) Yep. I've already made various fixes after comments from Jann. >> The information in the notification can be used to discover >> the values of pointer arguments for the target process's sys‐ >> tem call. (This is something that can't be done from within a >> seccomp filter.) To do this (and assuming it has suitable >> permissions), the supervisor opens the corresponding >> /proc/[pid]/mem file, seeks to the memory location that corre‐ >> sponds to one of the pointer arguments whose value is supplied >> in the notification event, and reads bytes from that location. >> (The supervisor must be careful to avoid a race condition that >> can occur when doing this; see the description of the SEC‐ >> COMP_IOCTL_NOTIF_ID_VALID ioctl(2) operation below.) In addi‐ >> tion, the supervisor can access other system information that >> is visible in user space but which is not accessible from a >> seccomp filter. >> >> ┌─────────────────────────────────────────────────────┐ >> │FIXME │ >> ├─────────────────────────────────────────────────────┤ >> │Suppose we are reading a pathname from /proc/PID/mem │ >> │for a system call such as mkdir(). The pathname can │ >> │be an arbitrary length. How do we know how much (how │ >> │many pages) to read from /proc/PID/mem? │ >> └─────────────────────────────────────────────────────┘ > > This has already been answered, I believe. Yep. >> >> 7. Having obtained information as per the previous step, the >> supervisor may then choose to perform an action in response to >> the target process's system call (which, as noted above, is >> not executed when the seccomp filter returns the SEC‐ >> COMP_RET_USER_NOTIF action value). > > Nit: It is not _yet_ executed it may very well be if the response is > "continue". Okay. I've added the word "yet" in point 4. I already elaborate on the "continue" details later. > This should either mention that when the fd becomes > _RECVable the system call is guaranteed to not have executed yet or > specify that it is not yet executed, I think. I'm not sure that I understand your point here. I mean, doesn't the arrival of the notification already imply that the system call hasn't yet been executed? You seem to be drawing some distinction between the notification vs FD being RECVable, but I don't understand what that distinction is. Can you elaborate please... >> One example use case here relates to containers. The target >> process may be located inside a container where it does not >> have sufficient capabilities to mount a filesystem in the con‐ >> tainer's mount namespace. However, the supervisor may be a >> more privileged process that that does have sufficient capa‐ >> bilities to perform the mount operation. >> >> 8. The supervisor then sends a response to the notification. The >> information in this response is used by the kernel to con‐ >> struct a return value for the target process's system call and >> provide a value that will be assigned to the errno variable of >> the target process. >> >> The response is sent using the SECCOMP_IOCTL_NOTIF_RECV >> ioctl(2) operation, which is used to transmit a sec‐ >> comp_notif_resp structure to the kernel. This structure >> includes a cookie value that the supervisor obtained in the >> seccomp_notif structure returned by the SEC‐ >> COMP_IOCTL_NOTIF_RECV operation. This cookie value allows the >> kernel to associate the response with the target process. > > I think here or above you should mention that the id or "cookie" _must_ > be used when a file descriptor to /proc//mem or any /proc//* > is opened: > fd = open(/proc/pid/*); > verify_via_cookie_that_pid_still_alive(cookie); > operate_on(fd) > > Otherwise this is a potential security issue. Yes, but already in point 6 above I say: (The supervisor must be careful to avoid a race condition that can occur when doing this; see the description of the SEC‐ COMP_IOCTL_NOTIF_ID_VALID ioctl(2) operation below.) In addi‐ And then I say more about the ioctl() later. So, I think that I've covered this point sufficiently (?). Maybe you missed some of that text. Or do you think there's still something I should add? >> 9. Once the notification has been sent, the system call in the >> target process unblocks, returning the information that was >> provided by the supervisor in the notification response. >> >> As a variation on the last two steps, the supervisor can send a >> response that tells the kernel that it should execute the target >> process's system call; see the discussion of SEC‐ >> COMP_USER_NOTIF_FLAG_CONTINUE, below. >> >> ioctl(2) operations >> The following ioctl(2) operations are provided to support seccomp >> user-space notification. For each of these operations, the first >> (file descriptor) argument of ioctl(2) is the listening file >> descriptor returned by a call to seccomp(2) with the SECCOMP_FIL‐ >> TER_FLAG_NEW_LISTENER flag. >> >> SECCOMP_IOCTL_NOTIF_RECV >> This operation is used to obtain a user-space notification >> event. If no such event is currently pending, the opera‐ >> tion blocks until an event occurs. The third ioctl(2) >> argument is a pointer to a structure of the following form >> which contains information about the event. This struc‐ >> ture must be zeroed out before the call. >> >> struct seccomp_notif { >> __u64 id; /* Cookie */ >> __u32 pid; /* PID of target process */ >> __u32 flags; /* Currently unused (0) */ >> struct seccomp_data data; /* See seccomp(2) */ >> }; >> >> The fields in this structure are as follows: >> >> id This is a cookie for the notification. Each such >> cookie is guaranteed to be unique for the corre‐ >> sponding seccomp filter. In other words, this >> cookie is unique for each notification event from >> the target process. The cookie value has the fol‐ >> lowing uses: >> >> · It can be used with the SEC‐ >> COMP_IOCTL_NOTIF_ID_VALID ioctl(2) operation to >> verify that the target process is still alive. >> >> · When returning a notification response to the >> kernel, the supervisor must include the cookie >> value in the seccomp_notif_resp structure that is >> specified as the argument of the SEC‐ >> COMP_IOCTL_NOTIF_SEND operation. >> >> pid This is the PID of the target process that trig‐ >> gered the notification event. >> >> ┌─────────────────────────────────────────────────────┐ >> │FIXME │ >> ├─────────────────────────────────────────────────────┤ >> │This is a thread ID, rather than a PID, right? │ >> └─────────────────────────────────────────────────────┘ > > Yes. > >> >> flags This is a bit mask of flags providing further >> information on the event. In the current implemen‐ >> tation, this field is always zero. >> >> data This is a seccomp_data structure containing infor‐ >> mation about the system call that triggered the >> notification. This is the same structure that is >> passed to the seccomp filter. See seccomp(2) for >> details of this structure. >> >> On success, this operation returns 0; on failure, -1 is >> returned, and errno is set to indicate the cause of the >> error. This operation can fail with the following errors: >> >> EINVAL (since Linux 5.5) >> The seccomp_notif structure that was passed to the >> call contained nonzero fields. >> >> ENOENT The target process was killed by a signal as the >> notification information was being generated. >> >> ┌─────────────────────────────────────────────────────┐ >> │FIXME │ >> ├─────────────────────────────────────────────────────┤ >> │From my experiments, it appears that if a SEC‐ │ >> │COMP_IOCTL_NOTIF_RECV is done after the target │ >> │process terminates, then the ioctl() simply blocks │ >> │(rather than returning an error to indicate that the │ >> │target process no longer exists). │ >> │ │ >> │I found that surprising, and it required some con‐ │ >> │tortions in the example program. It was not possi‐ │ >> │ble to code my SIGCHLD handler (which reaps the zom‐ │ >> │bie when the worker/target process terminates) to │ >> │simply set a flag checked in the main handleNotifi‐ │ >> │cations() loop, since this created an unavoidable │ >> │race where the child might terminate just after I │ >> │had checked the flag, but before I blocked (for‐ │ >> │ever!) in the SECCOMP_IOCTL_NOTIF_RECV operation. │ >> │Instead, I had to code the signal handler to simply │ >> │call _exit(2) in order to terminate the parent │ >> │process (the supervisor). │ >> │ │ >> │Is this expected behavior? It seems to me rather │ >> │desirable that SECCOMP_IOCTL_NOTIF_RECV should give │ >> │an error if the target process has terminated. │ >> └─────────────────────────────────────────────────────┘ > > This has been discussed later in the thread too, I believe. My patchset > fixed a different but related bug in ->poll() when a filter becomes > unused. I hadn't noticed this behavior since I'm always polling. (Pure > ioctls() feel a bit fishy to me. :) But obviously a valid use.) Yes, I hope the ioctl() can be fixed. >> SECCOMP_IOCTL_NOTIF_ID_VALID >> This operation can be used to check that a notification ID >> returned by an earlier SECCOMP_IOCTL_NOTIF_RECV operation >> is still valid (i.e., that the target process still >> exists). >> >> The third ioctl(2) argument is a pointer to the cookie >> (id) returned by the SECCOMP_IOCTL_NOTIF_RECV operation. >> >> This operation is necessary to avoid race conditions that >> can occur when the pid returned by the SEC‐ >> COMP_IOCTL_NOTIF_RECV operation terminates, and that >> process ID is reused by another process. An example of >> this kind of race is the following >> >> 1. A notification is generated on the listening file >> descriptor. The returned seccomp_notif contains the >> PID of the target process. >> >> 2. The target process terminates. >> >> 3. Another process is created on the system that by chance >> reuses the PID that was freed when the target process >> terminates. >> >> 4. The supervisor open(2)s the /proc/[pid]/mem file for >> the PID obtained in step 1, with the intention of (say) >> inspecting the memory locations that contains the argu‐ >> ments of the system call that triggered the notifica‐ >> tion in step 1. >> >> In the above scenario, the risk is that the supervisor may >> try to access the memory of a process other than the tar‐ >> get. This race can be avoided by following the call to >> open with a SECCOMP_IOCTL_NOTIF_ID_VALID operation to ver‐ >> ify that the process that generated the notification is >> still alive. (Note that if the target process subse‐ >> quently terminates, its PID won't be reused because there >> remains an open reference to the /proc[pid]/mem file; in >> this case, a subsequent read(2) from the file will return >> 0, indicating end of file.) >> >> On success (i.e., the notification ID is still valid), >> this operation returns 0 On failure (i.e., the notifica‐ > > Missing a ".", I think. (Yup. Already fixed.) >> tion ID is no longer valid), -1 is returned, and errno is >> set to ENOENT. >> >> SECCOMP_IOCTL_NOTIF_SEND >> This operation is used to send a notification response >> back to the kernel. The third ioctl(2) argument of this >> structure is a pointer to a structure of the following >> form: >> >> struct seccomp_notif_resp { >> __u64 id; /* Cookie value */ >> __s64 val; /* Success return value */ >> __s32 error; /* 0 (success) or negative >> error number */ >> __u32 flags; /* See below */ >> }; >> >> The fields of this structure are as follows: >> >> id This is the cookie value that was obtained using >> the SECCOMP_IOCTL_NOTIF_RECV operation. This >> cookie value allows the kernel to correctly asso‐ >> ciate this response with the system call that trig‐ >> gered the user-space notification. >> >> val This is the value that will be used for a spoofed >> success return for the target process's system >> call; see below. >> >> error This is the value that will be used as the error >> number (errno) for a spoofed error return for the >> target process's system call; see below. > > Nit: "val" is only used when "error" is not set. Yes. I note that below. I don't want to clutter this part of the page with too many details. >> flags This is a bit mask that includes zero or more of >> the following flags >> >> SECCOMP_USER_NOTIF_FLAG_CONTINUE (since Linux 5.5) >> Tell the kernel to execute the target >> process's system call. >> >> Two kinds of response are possible: >> >> · A response to the kernel telling it to execute the tar‐ >> get process's system call. In this case, the flags >> field includes SECCOMP_USER_NOTIF_FLAG_CONTINUE and the >> error and val fields must be zero. >> >> This kind of response can be useful in cases where the >> supervisor needs to do deeper analysis of the target's >> system call than is possible from a seccomp filter >> (e.g., examining the values of pointer arguments), and, >> having verified that the system call is acceptable, the >> supervisor wants to allow it to proceed. > > I think Jann has pointed this out. This needs to come with a big warning > and I would explicitly put a: > "The user notification mechanism cannot be used to implement a syscall > security policy in user space!" > You might want to take a look at the seccomp.h header file where I > placed a giant warning about how to use this too. Yes. Kees also raised this. See my reply to Jann (who pasted in a copy of part of your comment from seccomp.h). I'm going to freely reuse the text from your comment. Please take a look at the text in my reply to Jann, ad let me know wat you think. >> · A spoofed return value for the target process's system >> call. In this case, the kernel does not execute the >> target process's system call, instead causing the system >> call to return a spoofed value as specified by fields of >> the seccomp_notif_resp structure. The supervisor should >> set the fields of this structure as follows: >> >> + flags does not contain SECCOMP_USER_NOTIF_FLAG_CON‐ >> TINUE. >> >> + error is set either to 0 for a spoofed "success" >> return or to a negative error number for a spoofed >> "failure" return. In the former case, the kernel >> causes the target process's system call to return the >> value specified in the val field. In the later case, >> the kernel causes the target process's system call to >> return -1, and errno is assigned the negated error >> value. >> >> + val is set to a value that will be used as the return >> value for a spoofed "success" return for the target >> process's system call. The value in this field is >> ignored if the error field contains a nonzero value. >> >> On success, this operation returns 0; on failure, -1 is >> returned, and errno is set to indicate the cause of the >> error. This operation can fail with the following errors: >> >> EINPROGRESS >> A response to this notification has already been >> sent. >> >> EINVAL An invalid value was specified in the flags field. >> >> EINVAL The flags field contained SEC‐ >> COMP_USER_NOTIF_FLAG_CONTINUE, and the error or val >> field was not zero. >> >> ENOENT The blocked system call in the target process has >> been interrupted by a signal handler. >> >> NOTES >> The file descriptor returned when seccomp(2) is employed with the >> SECCOMP_FILTER_FLAG_NEW_LISTENER flag can be monitored using >> poll(2), epoll(7), and select(2). When a notification is pend‐ >> ing, these interfaces indicate that the file descriptor is read‐ >> able. > > This should also note that when a filter becomes unused, i.e. the last > task using that filter in its filter hierarchy is dead (been > reaped/autoreaped) ->poll() will notify with (E)POLLHUP. Ahh! Now I understand. I was unaware of this. Jann commented that poll() could be used as well, but you provided enough detail that now I understand how this works. I added the following in NOTES where poll/select/epoll are described: · After the last thread using the filter has terminated and been reaped using waitpid(2) (or similar), the file descriptor indi‐ cates an end-of-file condition (readable in select(2); POLL‐ HUP/EPOLLHUP in poll(2)/ epoll_wait(2)). >> ┌─────────────────────────────────────────────────────┐ >> │FIXME │ >> ├─────────────────────────────────────────────────────┤ >> │Interestingly, after the event had been received, │ >> │the file descriptor indicates as writable (verified │ >> │from the source code and by experiment). How is this │ >> │useful? │ >> └─────────────────────────────────────────────────────┘ >> >> EXAMPLES >> The (somewhat contrived) program shown below demonstrates the use >> of the interfaces described in this page. The program creates a >> child process that serves as the "target" process. The child >> process installs a seccomp filter that returns the SEC‐ >> COMP_RET_USER_NOTIF action value if a call is made to mkdir(2). >> The child process then calls mkdir(2) once for each of the sup‐ >> plied command-line arguments, and reports the result returned by >> the call. After processing all arguments, the child process ter‐ >> minates. >> >> The parent process acts as the supervisor, listening for the >> notifications that are generated when the target process calls >> mkdir(2). When such a notification occurs, the supervisor exam‐ >> ines the memory of the target process (using /proc/[pid]/mem) to >> discover the pathname argument that was supplied to the mkdir(2) >> call, and performs one of the following actions: >> >> · If the pathname begins with the prefix "/tmp/", then the super‐ >> visor attempts to create the specified directory, and then >> spoofs a return for the target process based on the return >> value of the supervisor's mkdir(2) call. In the event that >> that call succeeds, the spoofed success return value is the >> length of the pathname. >> >> · If the pathname begins with "./" (i.e., it is a relative path‐ >> name), the supervisor sends a SECCOMP_USER_NOTIF_FLAG_CONTINUE >> response to the kernel to say that kernel should execute the >> target process's mkdir(2) call. > > Potentially problematic if the two processes have the same privilege > level and the supervisor intends _CONTINUE to mean "is safe to execute". Understood. But I think that needs to be clarified elsewhere in the page, since it's essentially the same point as "The user notification mechanism cannot be used to implement a syscall security policy in user space!" See my reply to Jann. > An attacker could try to re-write arguments afaict. By an attacker, I presume you mean a malign supervisor, right. Sure, it looks to me as though rewriting arguments could be possible. But, if you had privilege to do that, you'd presumably have privileges for any number of other nefarious actities, right? (So, I don't think anything special needs to be said here; let me know if you feel something does need to be said. > A good an easy example is usually mknod() in a user namespace. A > _CONTINUE is always safe since you can't create device nodes anyway. Okay -- but I wanted to provide an example (admittedly very contrived) to show how the supervisor could either do the systcall on behalf of the target, or leave things to the target to execute the system call. Do you feel that the example is leading people astray? > Sorry, I can't review the rest in sufficient detail since I'm on > vacation still so I'm just going to shut up now. :) Well, thanks already, because your comments were already very useful!. I will send out a new draft shortly :-). 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: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.8 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0750FC433DF for ; Thu, 15 Oct 2020 11:23:55 +0000 (UTC) Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 337012080A for ; Thu, 15 Oct 2020 11:23:53 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KC9BPD5G" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 337012080A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=containers-bounces@lists.linux-foundation.org Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 9460F882C7; Thu, 15 Oct 2020 11:23:53 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Jg9ol4CuWQcu; Thu, 15 Oct 2020 11:23:51 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id 7BFB78827E; Thu, 15 Oct 2020 11:23:51 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 620ABC0052; Thu, 15 Oct 2020 11:23:51 +0000 (UTC) Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 982E4C0051 for ; Thu, 15 Oct 2020 11:23:50 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 7991787F44 for ; Thu, 15 Oct 2020 11:23:50 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id WE2VwMCHJpMM for ; Thu, 15 Oct 2020 11:23:48 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-wm1-f67.google.com (mail-wm1-f67.google.com [209.85.128.67]) by hemlock.osuosl.org (Postfix) with ESMTPS id DE79F87B65 for ; Thu, 15 Oct 2020 11:23:47 +0000 (UTC) Received: by mail-wm1-f67.google.com with SMTP id p15so2773528wmi.4 for ; Thu, 15 Oct 2020 04:23:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=cc:subject:to:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=GmEVmU88O8qTiwUb+ICW1QOn1EEa3s/908Lo1d+XEAY=; b=KC9BPD5GvkT8f7maqCMdJoPtbT9r/F6jN6s3KjF6ZbDtA9MoFFRkdR8bUUuqJkJCt3 iVzVMSI2SodaAjbbOe1VX7rtYR1LiqcdcbPC9c4Br1nM7t9/po/D0TLKkBkOyJycbeoA a1wiQ0tuWCbYU/7QwpQjvOkXBLnECrjYp8E1VNy1tyu0+bo2/Y5L10MvdpdfgjM1Ks1+ iiX+pSXPCOpQiUAm0a44hSDuvYCw+/rPbkou2ZZGbSaLjEj0F9Ikf0bW3uJZrgWjftR0 DdP8IMeRWNNnqf74ct7ieiZCrn16MW4NBGzy158dRKIuYDod/pL5ZfcF7OXgBCU1tDY0 duvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:cc:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=GmEVmU88O8qTiwUb+ICW1QOn1EEa3s/908Lo1d+XEAY=; b=M4fI15pEE70pcxxNc0aQ+Jz6oWhe8hfGiV/4NKTtmS3zN+dAewd7LIUieAUXWCLiad BTVPLIWdM8mgcKmPXqx6l6nc8jvEkT3ALrKuoJDvZpAFDi4tDJ9J4x5c1uSB04dCDdA+ F65/DyBD0afKx4tDLCwiqKgTy3+0xndXsdxH/3FnKn4UV5BJn/FzDQgubzi0MpyXdvT/ BV/QMtmZngvgSPYddr0YhkhHQwWc6C4ceGPYlH55FlArENZUza8f0kN7aCG0MPeb0hdd O1p/i5KI9D6osuN1m6MMWYI8QYsPKL0dI4dmWIB3KRpSzjhojC7VYaBiPJVz10eXIB5q obXw== X-Gm-Message-State: AOAM533k3La9OLzhYBUY2pp0psO9wT9t5I1mKdHpNdhYk/3TmKdU3ASd nz4b10AbQa83mLrLwq2gYlo= X-Google-Smtp-Source: ABdhPJwyufiojU8J691nXzhj6hk9Qnf4xI2ezsyZEgQZFG9kqq1kcH4x83jUdaD+8QpHVcQukgX0xQ== X-Received: by 2002:a1c:7d54:: with SMTP id y81mr3368720wmc.114.1602761025714; Thu, 15 Oct 2020 04:23:45 -0700 (PDT) Received: from [192.168.1.10] (static-176-175-73-29.ftth.abo.bbox.fr. [176.175.73.29]) by smtp.gmail.com with ESMTPSA id y7sm3898721wmg.40.2020.10.15.04.23.43 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 15 Oct 2020 04:23:44 -0700 (PDT) Subject: Re: For review: seccomp_user_notif(2) manual page To: Christian Brauner References: <45f07f17-18b6-d187-0914-6f341fe90857@gmail.com> <20201001123619.fdlk2xb56lej6rx3@gmail.com> From: "Michael Kerrisk (man-pages)" Message-ID: <3cd4826a-074e-e863-af70-43a80a996e58@gmail.com> Date: Thu, 15 Oct 2020 13:23:43 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.11.0 MIME-Version: 1.0 In-Reply-To: <20201001123619.fdlk2xb56lej6rx3@gmail.com> Content-Language: en-US Cc: linux-man , Song Liu , wad@chromium.org, Kees Cook , Daniel Borkmann , Jann Horn , Robert Sesek , Linux Containers , lkml , Alexei Starovoitov , mtk.manpages@gmail.com, Giuseppe Scrivano , bpf@vger.kernel.org, Andy Lutomirski , Christian Brauner X-BeenThere: containers@lists.linux-foundation.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Linux Containers List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: containers-bounces@lists.linux-foundation.org Sender: "Containers" SGVsbG8gQ2hyaXN0aWFuLAoKT24gMTAvMS8yMCAyOjM2IFBNLCBDaHJpc3RpYW4gQnJhdW5lciB3 cm90ZToKPiBbSSdtIG9uIHZhY2F0aW9uIHNvIEknbGwganVzdCBnaXZlIHRoaXMgYSBxdWljayBn bGFuY2UgZm9yIG5vdy5dCj4gCj4gT24gV2VkLCBTZXAgMzAsIDIwMjAgYXQgMDE6MDc6MzhQTSAr MDIwMCwgTWljaGFlbCBLZXJyaXNrIChtYW4tcGFnZXMpIHdyb3RlOgo+PiBIaSBUeWNobywgU2Fy Z3VuIChhbmQgYWxsKSwKPj4KPj4gSSBrbmV3IGl0IHdvdWxkIGJlIGEgYmlnIGFzaywgYnV0IGJl bG93IGlzIGtpbmQgb2YgdGhlIG1hbnVhbCBwYWdlCj4+IEkgd2FzIGhvcGluZyB5b3UgbWlnaHQg d3JpdGUgWzFdIGZvciB0aGUgc2VjY29tcCB1c2VyLXNwYWNlIG5vdGlmaWNhdGlvbgo+PiBtZWNo YW5pc20uIFNpbmNlIHlvdSBkaWRuJ3QgKGFuZCBiZWNhdXNlIDUuOSBhZGRzIHZhcmlvdXMgbmV3 IHBpZWNlcyAKPj4gc3VjaCBhcyBTRUNDT01QX0FEREZEX0ZMQUdfU0VURkQgYW5kIFNFQ0NPTVBf SU9DVExfTk9USUZfQURERkQgCj4+IHRoYXQgYWxzbyB3aWxsIG5lZWQgZG9jdW1lbnRpbmcgWzJd KSwgSSBkaWQgOi0pLiBCdXQgb2YgY291cnNlIEkgbWF5IAo+PiBoYXZlIG1hZGUgbWlzdGFrZXMu Li4KPj4KPj4gSSd2ZSBzaG93biB0aGUgcmVuZGVyZWQgdmVyc2lvbiBvZiB0aGUgcGFnZSBiZWxv dywgYW5kIHdvdWxkIGxvdmUKPj4gdG8gcmVjZWl2ZSByZXZpZXcgY29tbWVudHMgZnJvbSB5b3Ug YW5kIG90aGVycywgYW5kIGFja3MsIGV0Yy4KPj4KPj4gVGhlcmUgYXJlIGEgZmV3IEZJWE1FcyBz cHJpbmtsZWQgaW50byB0aGUgcGFnZSwgaW5jbHVkaW5nIG9uZQo+PiB0aGF0IHJlbGF0ZXMgdG8g d2hhdCBhcHBlYXJzIHRvIG1lIHRvIGJlIGEgbWlzZGVzaWduIChwb3NzaWJseSAKPj4gZml4YWJs ZSkgaW4gdGhlIG9wZXJhdGlvbiBvZiB0aGUgU0VDQ09NUF9JT0NUTF9OT1RJRl9SRUNWIAo+PiBv cGVyYXRpb24uIEkgd291bGQgYmUgZXNwZWNpYWxseSBpbnRlcmVzdGVkIGluIGZlZWRiYWNrIG9u IHRoYXQKPj4gRklYTUUsIGFuZCBhbHNvIG9mIGNvdXJzZSB0aGUgb3RoZXIgRklYTUVzLgo+Pgo+ PiBUaGUgcGFnZSBpbmNsdWRlcyBhbiBleHRlbnNpdmUgKGFsYmVpdCBzbGlnaHRseSBjb250cml2 ZWQpCj4+IGV4YW1wbGUgcHJvZ3JhbSwgYW5kIEkgd291bGQgYmUgaGFwcHkgYWxzbyB0byByZWNl aXZlIGNvbW1lbnRzCj4+IG9uIHRoYXQgcHJvZ3JhbS4KPj4KPj4gVGhlIHBhZ2Ugc291cmNlIGN1 cnJlbnRseSBzaXRzIGluIGEgYnJhbmNoIChhbG9uZyB3aXRoIHRoZSB0ZXh0Cj4+IHRoYXQgeW91 IHNlbnQgbWUgZm9yIHRoZSBzZWNjb21wKDIpIHBhZ2UpIGF0Cj4+IGh0dHBzOi8vZ2l0Lmtlcm5l bC5vcmcvcHViL3NjbS9kb2NzL21hbi1wYWdlcy9tYW4tcGFnZXMuZ2l0L2xvZy8/aD1zZWNjb21w X3VzZXJfbm90aWYKPj4KPj4gVGhhbmtzLAo+Pgo+PiBNaWNoYWVsCj4+Cj4+IFsxXSBodHRwczov L2xvcmUua2VybmVsLm9yZy9saW51eC1tYW4vMmNlYTVmZWMtZTczZS01NzQ5LTE4YWYtMTVjMzVh NGJkMjNjQGdtYWlsLmNvbS8jdAo+PiBbMl0gU2FyZ3VuLCBjYW4geW91IHByZXBhcmUgc29tZXRo aW5nIG9uIFNFQ0NPTVBfQURERkRfRkxBR19TRVRGRAo+PiAgICAgYW5kIFNFQ0NPTVBfSU9DVExf Tk9USUZfQURERkQgdG8gYmUgYWRkZWQgdG8gdGhpcyBwYWdlPwo+Pgo+PiA9PT09PQo+Pgo+PiBO QU1FCj4+ICAgICAgICBzZWNjb21wX3VzZXJfbm90aWYgLSBTZWNjb21wIHVzZXItc3BhY2Ugbm90 aWZpY2F0aW9uIG1lY2hhbmlzbQo+Pgo+PiBTWU5PUFNJUwo+PiAgICAgICAgI2luY2x1ZGUgPGxp bnV4L3NlY2NvbXAuaD4KPj4gICAgICAgICNpbmNsdWRlIDxsaW51eC9maWx0ZXIuaD4KPj4gICAg ICAgICNpbmNsdWRlIDxsaW51eC9hdWRpdC5oPgo+Pgo+PiAgICAgICAgaW50IHNlY2NvbXAodW5z aWduZWQgaW50IG9wZXJhdGlvbiwgdW5zaWduZWQgaW50IGZsYWdzLCB2b2lkICphcmdzKTsKPj4K Pj4gREVTQ1JJUFRJT04KPj4gICAgICAgIFRoaXMgIHBhZ2UgIGRlc2NyaWJlcyAgdGhlIHVzZXIt c3BhY2Ugbm90aWZpY2F0aW9uIG1lY2hhbmlzbSBwcm/igJAKPj4gICAgICAgIHZpZGVkIGJ5IHRo ZSBTZWN1cmUgQ29tcHV0aW5nIChzZWNjb21wKSBmYWNpbGl0eS4gIEFzIHdlbGwgYXMgdGhlCj4+ ICAgICAgICB1c2UgICBvZiAgdGhlICBTRUNDT01QX0ZJTFRFUl9GTEFHX05FV19MSVNURU5FUiAg ZmxhZywgIHRoZSAgU0VD4oCQCj4+ICAgICAgICBDT01QX1JFVF9VU0VSX05PVElGIGFjdGlvbiB2 YWx1ZSwgYW5kIHRoZSBTRUNDT01QX0dFVF9OT1RJRl9TSVpFUwo+PiAgICAgICAgb3BlcmF0aW9u ICBkZXNjcmliZWQgIGluICBzZWNjb21wKDIpLCB0aGlzIG1lY2hhbmlzbSBpbnZvbHZlcyB0aGUK Pj4gICAgICAgIHVzZSBvZiBhIG51bWJlciBvZiByZWxhdGVkIGlvY3RsKDIpIG9wZXJhdGlvbnMg KGRlc2NyaWJlZCBiZWxvdykuCj4+Cj4+ICAgIE92ZXJ2aWV3Cj4+ICAgICAgICBJbiBjb252ZW50 aW9uYWwgdXNhZ2Ugb2YgYSBzZWNjb21wIGZpbHRlciwgdGhlIGRlY2lzaW9uIGFib3V0IGhvdwo+ PiAgICAgICAgdG8gIHRyZWF0ICBhIHBhcnRpY3VsYXIgc3lzdGVtIGNhbGwgaXMgbWFkZSBieSB0 aGUgZmlsdGVyIGl0c2VsZi4KPj4gICAgICAgIFRoZSB1c2VyLXNwYWNlIG5vdGlmaWNhdGlvbiBt ZWNoYW5pc20gYWxsb3dzIHRoZSBoYW5kbGluZyBvZiAgdGhlCj4+ICAgICAgICBzeXN0ZW0gIGNh bGwgIHRvICBpbnN0ZWFkICBiZSBoYW5kZWQgb2ZmIHRvIGEgdXNlci1zcGFjZSBwcm9jZXNzLgo+ IAo+ICJJbiBjb250cmFzdCwgdGhlIHVzZXIgbm90aWZpY2F0aW9uIG1lY2hhbmlzbSBhbGxvd3Mg dG8gZGVsZWdhdGUgdGhlCj4gaGFuZGxpbmcgb2YgdGhlIHN5c3RlbSBjYWxsIG9mIG9uZSBwcm9j ZXNzICh0YXJnZXQpIHRvIGFub3RoZXIKPiB1c2VyLXNwYWNlIHByb2Nlc3MgKHN1cGVydmlzb3Ip LiI/CgpUaGFua3MuIEkndmUgcmV3b3JkZWQgc2ltaWxhcmx5IHRvIHdoYXQgeW91IHN1Z2dlc3Qu Cgo+PiAgICAgICAgVGhlIGFkdmFudGFnZXMgb2YgZG9pbmcgdGhpcyBhcmUgdGhhdCwgYnkgY29u dHJhc3Qgd2l0aCB0aGUgIHNlY+KAkAo+PiAgICAgICAgY29tcCAgZmlsdGVyLCAgd2hpY2ggIGlz ICBydW5uaW5nIG9uIGEgdmlydHVhbCBtYWNoaW5lIGluc2lkZSB0aGUKPj4gICAgICAgIGtlcm5l bCwgdGhlIHVzZXItc3BhY2UgcHJvY2VzcyBoYXMgYWNjZXNzIHRvIGluZm9ybWF0aW9uIHRoYXQg IGlzCj4+ICAgICAgICB1bmF2YWlsYWJsZSB0byB0aGUgc2VjY29tcCBmaWx0ZXIgYW5kIGl0IGNh biBwZXJmb3JtIGFjdGlvbnMgdGhhdAo+PiAgICAgICAgY2FuJ3QgYmUgcGVyZm9ybWVkIGZyb20g dGhlIHNlY2NvbXAgZmlsdGVyLgo+IAo+IFRoaXMgc2VjdGlvbiByZWFkcyBhIGJpdCBkaWZmaWN1 bHQgaW1obzoKPiAiQSBzdWl0YWJseSBwcml2aWxlZ2VkIHN1cGVydmlzb3IgY2FuIHVzZSB0aGUg dXNlciBub3RpZmljYXRpb24KPiBtZWNoYW5pc20gdG8gcGVyZm9ybSBhY3Rpb25zIGluIGxpZXUg b2YgdGhlIHRhcmdldC4gVGhlIHN1cGVydmlzb3Igd2lsbAo+IHVzdWFsbHkgYmUgYWJsZSB0byBy ZXRyaWV2ZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgdGFyZ2V0IGFuZCB0aGUKPiBwZXJmb3JtZWQg c3lzdGVtIGNhbGwgdGhhdCB0aGUgc2VjY29tcCBmaWx0ZXIgaXRzZWxmIGNhbm5vdC4iCgpUaGFu a3MuIEFnYWluIEkndmUgZG9uZSBzb21lIHJld29yZGluZy4KCj4+ICAgICAgICBJbiB0aGUgZGlz Y3Vzc2lvbiB0aGF0IGZvbGxvd3MsIHRoZSBwcm9jZXNzICB0aGF0ICBoYXMgIGluc3RhbGxlZAo+ PiAgICAgICAgdGhlICBzZWNjb21wIGZpbHRlciBpcyByZWZlcnJlZCB0byBhcyB0aGUgdGFyZ2V0 LCBhbmQgdGhlIHByb2Nlc3MKPj4gICAgICAgIHRoYXQgaXMgbm90aWZpZWQgYnkgIHRoZSAgdXNl ci1zcGFjZSAgbm90aWZpY2F0aW9uICBtZWNoYW5pc20gIGlzCj4+ICAgICAgICByZWZlcnJlZCAg dG8gIGFzICB0aGUgIHN1cGVydmlzb3IuICBBbiBvdmVydmlldyBvZiB0aGUgc3RlcHMgcGVy4oCQ Cj4+ICAgICAgICBmb3JtZWQgYnkgdGhlc2UgdHdvIHByb2Nlc3NlcyBpcyBhcyBmb2xsb3dzOgoK QWZ0ZXIgdGhlIHZhcmlvdXMgcmV3b3JkaW5ncywgdGhlIG9wZW5pbmcgcGFyYWdyYXBocyBub3cg cmVhZDoKCiAgICAgICBJbiBjb252ZW50aW9uYWwgdXNhZ2Ugb2YgYSBzZWNjb21wIGZpbHRlciwg dGhlIGRlY2lzaW9uIGFib3V0ICBob3cKICAgICAgIHRvIHRyZWF0IGEgc3lzdGVtIGNhbGwgaXMg bWFkZSBieSB0aGUgZmlsdGVyIGl0c2VsZi4gIEJ5IGNvbnRyYXN0LAogICAgICAgdGhlIHVzZXIt c3BhY2Ugbm90aWZpY2F0aW9uIG1lY2hhbmlzbSBhbGxvd3MgdGhlIHNlY2NvbXAgZmlsdGVyIHRv CiAgICAgICBkZWxlZ2F0ZSAgdGhlICBoYW5kbGluZyAgb2YgIHRoZSBzeXN0ZW0gY2FsbCB0byBh bm90aGVyIHVzZXItc3BhY2UKICAgICAgIHByb2Nlc3MuCgogICAgICAgSW4gdGhlIGRpc2N1c3Np b24gdGhhdCBmb2xsb3dzLCB0aGUgdGhyZWFkKHMpIG9uIHdoaWNoIHRoZSBzZWNjb21wCiAgICAg ICBmaWx0ZXIgIGlzICBpbnN0YWxsZWQgIGlzIChhcmUpIHJlZmVycmVkIHRvIGFzIHRoZSB0YXJn ZXQsIGFuZCB0aGUKICAgICAgIHByb2Nlc3MgdGhhdCBpcyBub3RpZmllZCBieSB0aGUgdXNlci1z cGFjZSBub3RpZmljYXRpb24gIG1lY2hhbmlzbQogICAgICAgaXMgcmVmZXJyZWQgdG8gYXMgdGhl IHN1cGVydmlzb3IuCgogICAgICAgQSAgc3VpdGFibHkgcHJpdmlsZWdlZCBzdXBlcnZpc29yIGNh biB1c2UgdGhlIHVzZXItc3BhY2Ugbm90aWZpY2HigJAKICAgICAgIHRpb24gbWVjaGFuaXNtIHRv IHBlcmZvcm0gYWN0aW9ucyBvbiBiZWhhbGYgb2YgIHRoZSAgdGFyZ2V0LiAgIFRoZQogICAgICAg YWR2YW50YWdlICBvZiAgdGhlICB1c2VyLXNwYWNlICBub3RpZmljYXRpb24gbWVjaGFuaXNtIGlz IHRoYXQgdGhlCiAgICAgICBzdXBlcnZpc29yIHdpbGwgdXN1YWxseSBiZSBhYmxlIHRvIHJldHJp ZXZlIGluZm9ybWF0aW9uIGFib3V0ICB0aGUKICAgICAgIHRhcmdldCAgYW5kICB0aGUgIHBlcmZv cm1lZCAgc3lzdGVtICBjYWxsICB0aGF0IHRoZSBzZWNjb21wIGZpbHRlcgogICAgICAgaXRzZWxm IGNhbm5vdC4gIChBIHNlY2NvbXAgZmlsdGVyIGlzIGxpbWl0ZWQgaW4gdGhlIGluZm9ybWF0aW9u IGl0CiAgICAgICBjYW4gIG9idGFpbiBhbmQgdGhlIGFjdGlvbnMgdGhhdCBpdCBjYW4gcGVyZm9y bSBiZWNhdXNlIGl0IGlzIHJ1buKAkAogICAgICAgbmluZyBvbiBhIHZpcnR1YWwgbWFjaGluZSBp bnNpZGUgdGhlIGtlcm5lbC4pCgogICAgICAgQW4gb3ZlcnZpZXcgb2YgdGhlIHN0ZXBzIHBlcmZv cm1lZCBieSB0aGUgdGFyZ2V0IGFuZCB0aGUgIHN1cGVydmnigJAKICAgICAgIHNvciBpcyBhcyBm b2xsb3dzOgoKPj4gICAgICAgIDEuIFRoZSB0YXJnZXQgcHJvY2VzcyBlc3RhYmxpc2hlcyBhIHNl Y2NvbXAgZmlsdGVyIGluICB0aGUgIHVzdWFsCj4+ICAgICAgICAgICBtYW5uZXIsIGJ1dCB3aXRo IHR3byBkaWZmZXJlbmNlczoKPj4KPj4gICAgICAgICAgIMK3IFRoZSBzZWNjb21wKDIpIGZsYWdz IGFyZ3VtZW50IGluY2x1ZGVzIHRoZSBmbGFnIFNFQ0NPTVBfRklM4oCQCj4+ICAgICAgICAgICAg IFRFUl9GTEFHX05FV19MSVNURU5FUi4gIENvbnNlcXVlbnRseSwgdGhlIHJldHVybiAgdmFsdWUg ICBvZgo+PiAgICAgICAgICAgICB0aGUgIChzdWNjZXNzZnVsKSAgc2VjY29tcCgyKSBjYWxsIGlz IGEgbmV3ICJsaXN0ZW5pbmciIGZpbGUKPj4gICAgICAgICAgICAgZGVzY3JpcHRvciB0aGF0IGNh biBiZSB1c2VkIHRvIHJlY2VpdmUgbm90aWZpY2F0aW9ucy4KPiAKPiBJIHRoaW5rIGl0IHdvdWxk IGJlIGdvb2QgdG8gbWVudGlvbiB0aGF0IHNlY2NvbXAgbm90aWZ5IGZkcyBhcmUKPiBPX0NMT0VY RUMgYnkgZGVmYXVsdCBzb21ld2hlcmUuCgpZZXAuIFRoaXMgaXMgYWxyZWFkeSBub3RlZCBpbiBz ZWNjb21wKDIpLgoKPj4gICAgICAgICAgIMK3IEluIGNhc2VzIHdoZXJlIGl0IGlzIGFwcHJvcHJp YXRlLCB0aGUgc2VjY29tcCBmaWx0ZXIgcmV0dXJucwo+PiAgICAgICAgICAgICB0aGUgIGFjdGlv biB2YWx1ZSBTRUNDT01QX1JFVF9VU0VSX05PVElGLiAgVGhpcyByZXR1cm4gdmFsdWUKPj4gICAg ICAgICAgICAgd2lsbCB0cmlnZ2VyIGEgbm90aWZpY2F0aW9uIGV2ZW50Lgo+Pgo+PiAgICAgICAg Mi4gSW4gb3JkZXIgdGhhdCB0aGUgc3VwZXJ2aXNvciBwcm9jZXNzIGNhbiBvYnRhaW4gIG5vdGlm aWNhdGlvbnMKPj4gICAgICAgICAgIHVzaW5nICB0aGUgIGxpc3RlbmluZyAgZmlsZSAgZGVzY3Jp cHRvciwgKGEgZHVwbGljYXRlIG9mKSB0aGF0Cj4+ICAgICAgICAgICBmaWxlIGRlc2NyaXB0b3Ig bXVzdCBiZSBwYXNzZWQgZnJvbSB0aGUgdGFyZ2V0IHByb2Nlc3MgdG8gIHRoZQo+PiAgICAgICAg ICAgc3VwZXJ2aXNvciBwcm9jZXNzLiAgT25lIHdheSBpbiB3aGljaCB0aGlzIGNvdWxkIGJlIGRv bmUgaXMgYnkKPj4gICAgICAgICAgIHBhc3NpbmcgdGhlIGZpbGUgZGVzY3JpcHRvciBvdmVyIGEg VU5JWCBkb21haW4gc29ja2V0ICBjb25uZWPigJAKPj4gICAgICAgICAgIHRpb24gYmV0d2VlbiB0 aGUgdHdvIHByb2Nlc3NlcyAodXNpbmcgdGhlIFNDTV9SSUdIVFMgYW5jaWxsYXJ5Cj4+ICAgICAg ICAgICBtZXNzYWdlIHR5cGUgZGVzY3JpYmVkIGluIHVuaXgoNykpLiAgIEFub3RoZXIgIHBvc3Np YmlsaXR5ICBpcwo+PiAgICAgICAgICAgdGhhdCAgdGhlICBzdXBlcnZpc29yICBtaWdodCAgaW5o ZXJpdCAgdGhlIGZpbGUgZGVzY3JpcHRvciB2aWEKPj4gICAgICAgICAgIGZvcmsoMikuCj4gCj4g SSB0aGluayBhIGZldyBwZW9wbGUgaGF2ZSBhbHJlYWR5IHBvaW50ZWQgb3V0IG90aGVyIHdheXMg b2YgcmV0cmlldmluZwo+IGFuIGZkLiA6KQoKWXVwLgoKPj4gICAgICAgIDMuIFRoZSBzdXBlcnZp c29yIHByb2Nlc3Mgd2lsbCByZWNlaXZlIG5vdGlmaWNhdGlvbiBldmVudHMgb24gdGhlCj4+ICAg ICAgICAgICBsaXN0ZW5pbmcgIGZpbGUgIGRlc2NyaXB0b3IuICAgVGhlc2UgIGV2ZW50cyAgYXJl ICByZXR1cm5lZCBhcwo+PiAgICAgICAgICAgc3RydWN0dXJlcyBvZiB0eXBlIHNlY2NvbXBfbm90 aWYuICBCZWNhdXNlIHRoaXMgc3RydWN0dXJlICBhbmQKPj4gICAgICAgICAgIGl0cyAgc2l6ZSBt YXkgZXZvbHZlIG92ZXIga2VybmVsIHZlcnNpb25zLCB0aGUgc3VwZXJ2aXNvciBtdXN0Cj4+ICAg ICAgICAgICBmaXJzdCBkZXRlcm1pbmUgdGhlIHNpemUgb2YgIHRoaXMgIHN0cnVjdHVyZSAgdXNp bmcgIHRoZSAgc2Vj4oCQCj4+ICAgICAgICAgICBjb21wKDIpICBTRUNDT01QX0dFVF9OT1RJRl9T SVpFUyAgb3BlcmF0aW9uLCAgd2hpY2ggIHJldHVybnMgYQo+PiAgICAgICAgICAgc3RydWN0dXJl IG9mIHR5cGUgc2VjY29tcF9ub3RpZl9zaXplcy4gIFRoZSAgc3VwZXJ2aXNvciAgYWxsb+KAkAo+ PiAgICAgICAgICAgY2F0ZXMgYSBidWZmZXIgb2Ygc2l6ZSBzZWNjb21wX25vdGlmX3NpemVzLnNl Y2NvbXBfbm90aWYgYnl0ZXMKPj4gICAgICAgICAgIHRvIHJlY2VpdmUgbm90aWZpY2F0aW9uIGV2 ZW50cy4gICBJbiAgYWRkaXRpb24sdGhlICBzdXBlcnZpc29yCj4+ICAgICAgICAgICBhbGxvY2F0 ZXMgIGFub3RoZXIgIGJ1ZmZlciAgb2YgIHNpemUgIHNlY2NvbXBfbm90aWZfc2l6ZXMuc2Vj4oCQ Cj4+ICAgICAgICAgICBjb21wX25vdGlmX3Jlc3AgIGJ5dGVzICBmb3IgIHRoZSAgcmVzcG9uc2Ug IChhICAgc3RydWN0ICAgc2Vj4oCQCj4+ICAgICAgICAgICBjb21wX25vdGlmX3Jlc3AgIHN0cnVj dHVyZSkgdGhhdCBpdCB3aWxsIHByb3ZpZGUgdG8gdGhlIGtlcm5lbAo+PiAgICAgICAgICAgKGFu ZCB0aHVzIHRoZSB0YXJnZXQgcHJvY2VzcykuCj4+Cj4+ICAgICAgICA0LiBUaGUgdGFyZ2V0IHBy b2Nlc3MgdGhlbiBwZXJmb3JtcyBpdHMgd29ya2xvYWQsIHdoaWNoICBpbmNsdWRlcwo+PiAgICAg ICAgICAgc3lzdGVtICBjYWxscyAgdGhhdCAgd2lsbCBiZSBjb250cm9sbGVkIGJ5IHRoZSBzZWNj b21wIGZpbHRlci4KPj4gICAgICAgICAgIFdoZW5ldmVyIG9uZSBvZiB0aGVzZSBzeXN0ZW0gY2Fs bHMgY2F1c2VzIHRoZSBmaWx0ZXIgdG8gcmV0dXJuCj4+ICAgICAgICAgICB0aGUgIFNFQ0NPTVBf UkVUX1VTRVJfTk9USUYgIGFjdGlvbiB2YWx1ZSwgdGhlIGtlcm5lbCBkb2VzIG5vdAo+PiAgICAg ICAgICAgZXhlY3V0ZSB0aGUgc3lzdGVtIGNhbGw7ICBpbnN0ZWFkLCAgZXhlY3V0aW9uICBvZiAg dGhlICB0YXJnZXQKPj4gICAgICAgICAgIHByb2Nlc3MgaXMgdGVtcG9yYXJpbHkgYmxvY2tlZCBp bnNpZGUgdGhlIGtlcm5lbCBhbmQgYSBub3RpZmnigJAKPiAKPiBNYXliZSBtZW50aW9uIHRoYXQg dGhlIHRhc2sgaXMga2lsbGFibGUgd2hlbiBzbyBibG9ja2VkPwoKSmFubiBhbHNvIG5vdGVkIHRo aXMsIGFuZCBJIHRob3VnaHQgaXQgY291bGQgYmUgcHJlc3VtZWQsIGFuZCBzbyB3YXMKbm90IHRo aW5raW5nIHRvIGFkZCBhbnl0aGluZyB0byB0aGUgdGV4dC4gQnV0LCBzaW5jZSB5b3UgbWVudGlv biBpdCB0b28sCkkndmUgYWRkZWQgc29tZSB3b3JkcyB0byBub3RlIHRoYXQgdGhlIHNsZWVwIHN0 YXRlIGlzIGludGVycnVwdGlibGUgYnkKc2lnbmFscy4KCj4+ICAgICAgICAgICBjYXRpb24gZXZl bnQgaXMgZ2VuZXJhdGVkIG9uIHRoZSBsaXN0ZW5pbmcgZmlsZSBkZXNjcmlwdG9yLgo+Pgo+PiAg ICAgICAgNS4gVGhlIHN1cGVydmlzb3IgcHJvY2VzcyBjYW4gbm93IHJlcGVhdGVkbHkgbW9uaXRv ciB0aGUgIGxpc3RlbuKAkAo+PiAgICAgICAgICAgaW5nICAgZmlsZSAgIGRlc2NyaXB0b3IgIGZv ciAgU0VDQ09NUF9SRVRfVVNFUl9OT1RJRi10cmlnZ2VyZWQKPj4gICAgICAgICAgIGV2ZW50cy4g ICBUbyAgZG8gIHRoaXMsICAgdGhlICAgc3VwZXJ2aXNvciAgIHVzZXMgICB0aGUgICBTRUPigJAK Pj4gICAgICAgICAgIENPTVBfSU9DVExfTk9USUZfUkVDViAgaW9jdGwoMikgIG9wZXJhdGlvbiB0 byByZWFkIGluZm9ybWF0aW9uCj4+ICAgICAgICAgICBhYm91dCBhIG5vdGlmaWNhdGlvbiBldmVu dDsgdGhpcyAgb3BlcmF0aW9uICBibG9ja3MgIHVudGlsICBhbgo+PiAgICAgICAgICAgZXZlbnQg IGlzICBhdmFpbGFibGUuICAgVGhlICBvcGVyYXRpb24gcmV0dXJucyBhIHNlY2NvbXBfbm90aWYK Pj4gICAgICAgICAgIHN0cnVjdHVyZSBjb250YWluaW5nIGluZm9ybWF0aW9uIGFib3V0IHRoZSBz eXN0ZW0gY2FsbCB0aGF0IGlzCj4+ICAgICAgICAgICBiZWluZyBhdHRlbXB0ZWQgYnkgdGhlIHRh cmdldCBwcm9jZXNzLgo+Pgo+PiAgICAgICAgNi4gVGhlICAgIHNlY2NvbXBfbm90aWYgICAgc3Ry dWN0dXJlICAgcmV0dXJuZWQgICBieSAgIHRoZSAgIFNFQ+KAkAo+PiAgICAgICAgICAgQ09NUF9J T0NUTF9OT1RJRl9SRUNWIG9wZXJhdGlvbiBpbmNsdWRlcyB0aGUgc2FtZSAgaW5mb3JtYXRpb24K Pj4gICAgICAgICAgIChhIHNlY2NvbXBfZGF0YSBzdHJ1Y3R1cmUpIHRoYXQgd2FzIHBhc3NlZCB0 byB0aGUgc2VjY29tcCBmaWzigJAKPj4gICAgICAgICAgIHRlci4gIFRoaXMgaW5mb3JtYXRpb24g YWxsb3dzIHRoZSBzdXBlcnZpc29yIHRvICBkaXNjb3ZlciAgdGhlCj4+ICAgICAgICAgICBzeXN0 ZW0gIGNhbGwgbnVtYmVyIGFuZCB0aGUgYXJndW1lbnRzIGZvciB0aGUgdGFyZ2V0IHByb2Nlc3Mn cwo+PiAgICAgICAgICAgc3lzdGVtIGNhbGwuICBJbiBhZGRpdGlvbiwgdGhlIG5vdGlmaWNhdGlv biBldmVudCBjb250YWlucyB0aGUKPj4gICAgICAgICAgIFBJRCBvZiB0aGUgdGFyZ2V0IHByb2Nl c3MuCj4gCj4gKFRlY2huaWNhbGx5IFRJRC4pCgpZZXAuIEkndmUgYWxyZWFkeSBtYWRlIHZhcmlv dXMgZml4ZXMgYWZ0ZXIgY29tbWVudHMgZnJvbSBKYW5uLgoKPj4gICAgICAgICAgIFRoZSAgaW5m b3JtYXRpb24gIGluICB0aGUgbm90aWZpY2F0aW9uIGNhbiBiZSB1c2VkIHRvIGRpc2NvdmVyCj4+ ICAgICAgICAgICB0aGUgdmFsdWVzIG9mIHBvaW50ZXIgYXJndW1lbnRzIGZvciB0aGUgdGFyZ2V0 IHByb2Nlc3MncyAgc3lz4oCQCj4+ICAgICAgICAgICB0ZW0gY2FsbC4gIChUaGlzIGlzIHNvbWV0 aGluZyB0aGF0IGNhbid0IGJlIGRvbmUgZnJvbSB3aXRoaW4gYQo+PiAgICAgICAgICAgc2VjY29t cCBmaWx0ZXIuKSAgVG8gZG8gdGhpcyAoYW5kICBhc3N1bWluZyAgaXQgIGhhcyAgc3VpdGFibGUK Pj4gICAgICAgICAgIHBlcm1pc3Npb25zKSwgICB0aGUgICBzdXBlcnZpc29yICAgb3BlbnMgICB0 aGUgICBjb3JyZXNwb25kaW5nCj4+ICAgICAgICAgICAvcHJvYy9bcGlkXS9tZW0gZmlsZSwgc2Vl a3MgdG8gdGhlIG1lbW9yeSBsb2NhdGlvbiB0aGF0IGNvcnJl4oCQCj4+ICAgICAgICAgICBzcG9u ZHMgdG8gb25lIG9mIHRoZSBwb2ludGVyIGFyZ3VtZW50cyB3aG9zZSB2YWx1ZSBpcyBzdXBwbGll ZAo+PiAgICAgICAgICAgaW4gdGhlIG5vdGlmaWNhdGlvbiBldmVudCwgYW5kIHJlYWRzIGJ5dGVz IGZyb20gdGhhdCBsb2NhdGlvbi4KPj4gICAgICAgICAgIChUaGUgc3VwZXJ2aXNvciBtdXN0IGJl IGNhcmVmdWwgdG8gYXZvaWQgYSByYWNlIGNvbmRpdGlvbiB0aGF0Cj4+ICAgICAgICAgICBjYW4g b2NjdXIgd2hlbiBkb2luZyB0aGlzOyBzZWUgdGhlICBkZXNjcmlwdGlvbiAgb2YgIHRoZSAgU0VD 4oCQCj4+ICAgICAgICAgICBDT01QX0lPQ1RMX05PVElGX0lEX1ZBTElEIGlvY3RsKDIpIG9wZXJh dGlvbiBiZWxvdy4pICBJbiBhZGRp4oCQCj4+ICAgICAgICAgICB0aW9uLCB0aGUgc3VwZXJ2aXNv ciBjYW4gYWNjZXNzIG90aGVyIHN5c3RlbSBpbmZvcm1hdGlvbiAgdGhhdAo+PiAgICAgICAgICAg aXMgIHZpc2libGUgIGluICB1c2VyIHNwYWNlIGJ1dCB3aGljaCBpcyBub3QgYWNjZXNzaWJsZSBm cm9tIGEKPj4gICAgICAgICAgIHNlY2NvbXAgZmlsdGVyLgo+Pgo+PiAgICAgICAgICAg4pSM4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSQCj4+ICAgICAgICAg ICDilIJGSVhNRSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IOKUggo+PiAgICAgICAgICAg4pSc4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSkCj4+ICAgICAgICAgICDilIJTdXBwb3NlIHdlIGFyZSByZWFkaW5nIGEgcGF0 aG5hbWUgZnJvbSAvcHJvYy9QSUQvbWVtIOKUggo+PiAgICAgICAgICAg4pSCZm9yICBhIHN5c3Rl bSBjYWxsIHN1Y2ggYXMgbWtkaXIoKS4gVGhlIHBhdGhuYW1lIGNhbiDilIIKPj4gICAgICAgICAg IOKUgmJlIGFuIGFyYml0cmFyeSBsZW5ndGguIEhvdyBkbyB3ZSBrbm93IGhvdyBtdWNoIChob3cg 4pSCCj4+ICAgICAgICAgICDilIJtYW55IHBhZ2VzKSB0byByZWFkIGZyb20gL3Byb2MvUElEL21l bT8gICAgICAgICAgICAgIOKUggo+PiAgICAgICAgICAg4pSU4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSYCj4gCj4gVGhpcyBoYXMgYWxyZWFkeSBiZWVuIGFu c3dlcmVkLCBJIGJlbGlldmUuCgpZZXAuCgo+Pgo+PiAgICAgICAgNy4gSGF2aW5nICBvYnRhaW5l ZCAgaW5mb3JtYXRpb24gIGFzICBwZXIgIHRoZSBwcmV2aW91cyBzdGVwLCB0aGUKPj4gICAgICAg ICAgIHN1cGVydmlzb3IgbWF5IHRoZW4gY2hvb3NlIHRvIHBlcmZvcm0gYW4gYWN0aW9uIGluIHJl c3BvbnNlIHRvCj4+ICAgICAgICAgICB0aGUgIHRhcmdldCAgcHJvY2VzcydzICBzeXN0ZW0gY2Fs bCAod2hpY2gsIGFzIG5vdGVkIGFib3ZlLCBpcwo+PiAgICAgICAgICAgbm90ICBleGVjdXRlZCAg d2hlbiAgdGhlICBzZWNjb21wICBmaWx0ZXIgIHJldHVybnMgIHRoZSAgIFNFQ+KAkAo+PiAgICAg ICAgICAgQ09NUF9SRVRfVVNFUl9OT1RJRiBhY3Rpb24gdmFsdWUpLgo+IAo+IE5pdDogSXQgaXMg bm90IF95ZXRfIGV4ZWN1dGVkIGl0IG1heSB2ZXJ5IHdlbGwgYmUgaWYgdGhlIHJlc3BvbnNlIGlz Cj4gImNvbnRpbnVlIi4gCgpPa2F5LiBJJ3ZlIGFkZGVkIHRoZSB3b3JkICJ5ZXQiIGluIHBvaW50 IDQuIEkgYWxyZWFkeSBlbGFib3JhdGUgb24KdGhlICJjb250aW51ZSIgZGV0YWlscyBsYXRlci4K Cj4gVGhpcyBzaG91bGQgZWl0aGVyIG1lbnRpb24gdGhhdCB3aGVuIHRoZSBmZCBiZWNvbWVzCj4g X1JFQ1ZhYmxlIHRoZSBzeXN0ZW0gY2FsbCBpcyBndWFyYW50ZWVkIHRvIG5vdCBoYXZlIGV4ZWN1 dGVkIHlldCBvcgo+IHNwZWNpZnkgdGhhdCBpdCBpcyBub3QgeWV0IGV4ZWN1dGVkLCBJIHRoaW5r LgoKSSdtIG5vdCBzdXJlIHRoYXQgSSB1bmRlcnN0YW5kIHlvdXIgcG9pbnQgaGVyZS4gSSBtZWFu LCBkb2Vzbid0IHRoZQphcnJpdmFsIG9mIHRoZSBub3RpZmljYXRpb24gYWxyZWFkeSBpbXBseSB0 aGF0IHRoZSBzeXN0ZW0gY2FsbCBoYXNuJ3QKeWV0IGJlZW4gZXhlY3V0ZWQ/IFlvdSBzZWVtIHRv IGJlIGRyYXdpbmcgc29tZSBkaXN0aW5jdGlvbiBiZXR3ZWVuCnRoZSBub3RpZmljYXRpb24gdnMg RkQgYmVpbmcgUkVDVmFibGUsIGJ1dCBJIGRvbid0IHVuZGVyc3RhbmQgd2hhdAp0aGF0IGRpc3Rp bmN0aW9uIGlzLiBDYW4geW91IGVsYWJvcmF0ZSBwbGVhc2UuLi4KCj4+ICAgICAgICAgICBPbmUg IGV4YW1wbGUgIHVzZSBjYXNlIGhlcmUgcmVsYXRlcyB0byBjb250YWluZXJzLiAgVGhlIHRhcmdl dAo+PiAgICAgICAgICAgcHJvY2VzcyBtYXkgYmUgbG9jYXRlZCBpbnNpZGUgYSBjb250YWluZXIg d2hlcmUgIGl0ICBkb2VzICBub3QKPj4gICAgICAgICAgIGhhdmUgc3VmZmljaWVudCBjYXBhYmls aXRpZXMgdG8gbW91bnQgYSBmaWxlc3lzdGVtIGluIHRoZSBjb27igJAKPj4gICAgICAgICAgIHRh aW5lcidzIG1vdW50IG5hbWVzcGFjZS4gIEhvd2V2ZXIsIHRoZSBzdXBlcnZpc29yICBtYXkgIGJl ICBhCj4+ICAgICAgICAgICBtb3JlICBwcml2aWxlZ2VkICBwcm9jZXNzIHRoYXQgdGhhdCBkb2Vz IGhhdmUgc3VmZmljaWVudCBjYXBh4oCQCj4+ICAgICAgICAgICBiaWxpdGllcyB0byBwZXJmb3Jt IHRoZSBtb3VudCBvcGVyYXRpb24uCj4+Cj4+ICAgICAgICA4LiBUaGUgc3VwZXJ2aXNvciB0aGVu IHNlbmRzIGEgcmVzcG9uc2UgdG8gdGhlIG5vdGlmaWNhdGlvbi4gIFRoZQo+PiAgICAgICAgICAg aW5mb3JtYXRpb24gIGluICB0aGlzICByZXNwb25zZSAgaXMgdXNlZCBieSB0aGUga2VybmVsIHRv IGNvbuKAkAo+PiAgICAgICAgICAgc3RydWN0IGEgcmV0dXJuIHZhbHVlIGZvciB0aGUgdGFyZ2V0 IHByb2Nlc3MncyBzeXN0ZW0gY2FsbCBhbmQKPj4gICAgICAgICAgIHByb3ZpZGUgYSB2YWx1ZSB0 aGF0IHdpbGwgYmUgYXNzaWduZWQgdG8gdGhlIGVycm5vIHZhcmlhYmxlIG9mCj4+ICAgICAgICAg ICB0aGUgdGFyZ2V0IHByb2Nlc3MuCj4+Cj4+ICAgICAgICAgICBUaGUgIHJlc3BvbnNlICBpcyAg c2VudCAgdXNpbmcgIHRoZSAgIFNFQ0NPTVBfSU9DVExfTk9USUZfUkVDVgo+PiAgICAgICAgICAg aW9jdGwoMikgICBvcGVyYXRpb24sICAgd2hpY2ggIGlzICB1c2VkICB0byAgdHJhbnNtaXQgIGEg IHNlY+KAkAo+PiAgICAgICAgICAgY29tcF9ub3RpZl9yZXNwICBzdHJ1Y3R1cmUgIHRvICB0aGUg IGtlcm5lbC4gICBUaGlzICBzdHJ1Y3R1cmUKPj4gICAgICAgICAgIGluY2x1ZGVzICBhICBjb29r aWUgIHZhbHVlIHRoYXQgdGhlIHN1cGVydmlzb3Igb2J0YWluZWQgaW4gdGhlCj4+ICAgICAgICAg ICBzZWNjb21wX25vdGlmICAgIHN0cnVjdHVyZSAgICByZXR1cm5lZCAgICAgYnkgICAgIHRoZSAg ICAgU0VD4oCQCj4+ICAgICAgICAgICBDT01QX0lPQ1RMX05PVElGX1JFQ1Ygb3BlcmF0aW9uLiAg VGhpcyBjb29raWUgdmFsdWUgYWxsb3dzIHRoZQo+PiAgICAgICAgICAga2VybmVsIHRvIGFzc29j aWF0ZSB0aGUgcmVzcG9uc2Ugd2l0aCB0aGUgdGFyZ2V0IHByb2Nlc3MuCj4gCj4gSSB0aGluayBo ZXJlIG9yIGFib3ZlIHlvdSBzaG91bGQgbWVudGlvbiB0aGF0IHRoZSBpZCBvciAiY29va2llIiBf bXVzdF8KPiBiZSB1c2VkIHdoZW4gYSBmaWxlIGRlc2NyaXB0b3IgdG8gL3Byb2MvPHBpZD4vbWVt IG9yIGFueSAvcHJvYy88cGlkPi8qCj4gaXMgb3BlbmVkOgo+IGZkID0gb3BlbigvcHJvYy9waWQv Kik7Cj4gdmVyaWZ5X3ZpYV9jb29raWVfdGhhdF9waWRfc3RpbGxfYWxpdmUoY29va2llKTsKPiBv cGVyYXRlX29uKGZkKQo+IAo+IE90aGVyd2lzZSB0aGlzIGlzIGEgcG90ZW50aWFsIHNlY3VyaXR5 IGlzc3VlLgoKWWVzLCBidXQgYWxyZWFkeSBpbiBwb2ludCA2IGFib3ZlIEkgc2F5OgoKICAgICAg ICAgICAoVGhlIHN1cGVydmlzb3IgbXVzdCBiZSBjYXJlZnVsIHRvIGF2b2lkIGEgcmFjZSBjb25k aXRpb24gdGhhdAogICAgICAgICAgIGNhbiBvY2N1ciB3aGVuIGRvaW5nIHRoaXM7IHNlZSB0aGUg IGRlc2NyaXB0aW9uICBvZiAgdGhlICBTRUPigJAKICAgICAgICAgICBDT01QX0lPQ1RMX05PVElG X0lEX1ZBTElEIGlvY3RsKDIpIG9wZXJhdGlvbiBiZWxvdy4pICBJbiBhZGRp4oCQCgpBbmQgdGhl biBJIHNheSBtb3JlIGFib3V0IHRoZSBpb2N0bCgpIGxhdGVyLiBTbywgSSB0aGluayB0aGF0IEkn dmUKY292ZXJlZCB0aGlzIHBvaW50IHN1ZmZpY2llbnRseSAoPykuIE1heWJlIHlvdSBtaXNzZWQg c29tZSBvZgp0aGF0IHRleHQuIE9yIGRvIHlvdSB0aGluayB0aGVyZSdzIHN0aWxsIHNvbWV0aGlu ZyBJIHNob3VsZCBhZGQ/Cgo+PiAgICAgICAgOS4gT25jZSB0aGUgbm90aWZpY2F0aW9uIGhhcyBi ZWVuIHNlbnQsIHRoZSBzeXN0ZW0gIGNhbGwgIGluICB0aGUKPj4gICAgICAgICAgIHRhcmdldCAg cHJvY2VzcyAgdW5ibG9ja3MsICByZXR1cm5pbmcgdGhlIGluZm9ybWF0aW9uIHRoYXQgd2FzCj4+ ICAgICAgICAgICBwcm92aWRlZCBieSB0aGUgc3VwZXJ2aXNvciBpbiB0aGUgbm90aWZpY2F0aW9u IHJlc3BvbnNlLgo+Pgo+PiAgICAgICAgQXMgYSB2YXJpYXRpb24gb24gdGhlIGxhc3QgdHdvIHN0 ZXBzLCB0aGUgc3VwZXJ2aXNvciBjYW4gIHNlbmQgIGEKPj4gICAgICAgIHJlc3BvbnNlICB0aGF0 IHRlbGxzIHRoZSBrZXJuZWwgdGhhdCBpdCBzaG91bGQgZXhlY3V0ZSB0aGUgdGFyZ2V0Cj4+ICAg ICAgICBwcm9jZXNzJ3MgICBzeXN0ZW0gICBjYWxsOyAgIHNlZSAgIHRoZSAgIGRpc2N1c3Npb24g ICAgb2YgICAgU0VD4oCQCj4+ICAgICAgICBDT01QX1VTRVJfTk9USUZfRkxBR19DT05USU5VRSwg YmVsb3cuCj4+Cj4+ICAgIGlvY3RsKDIpIG9wZXJhdGlvbnMKPj4gICAgICAgIFRoZSBmb2xsb3dp bmcgaW9jdGwoMikgb3BlcmF0aW9ucyBhcmUgcHJvdmlkZWQgdG8gc3VwcG9ydCBzZWNjb21wCj4+ ICAgICAgICB1c2VyLXNwYWNlIG5vdGlmaWNhdGlvbi4gIEZvciBlYWNoIG9mIHRoZXNlIG9wZXJh dGlvbnMsIHRoZSBmaXJzdAo+PiAgICAgICAgKGZpbGUgIGRlc2NyaXB0b3IpICBhcmd1bWVudCAg b2YgIGlvY3RsKDIpICBpcyB0aGUgbGlzdGVuaW5nIGZpbGUKPj4gICAgICAgIGRlc2NyaXB0b3Ig cmV0dXJuZWQgYnkgYSBjYWxsIHRvIHNlY2NvbXAoMikgd2l0aCB0aGUgU0VDQ09NUF9GSUzigJAK Pj4gICAgICAgIFRFUl9GTEFHX05FV19MSVNURU5FUiBmbGFnLgo+Pgo+PiAgICAgICAgU0VDQ09N UF9JT0NUTF9OT1RJRl9SRUNWCj4+ICAgICAgICAgICAgICAgVGhpcyBvcGVyYXRpb24gaXMgdXNl ZCB0byBvYnRhaW4gYSB1c2VyLXNwYWNlIG5vdGlmaWNhdGlvbgo+PiAgICAgICAgICAgICAgIGV2 ZW50LiAgSWYgbm8gc3VjaCBldmVudCBpcyBjdXJyZW50bHkgcGVuZGluZywgdGhlICBvcGVyYeKA kAo+PiAgICAgICAgICAgICAgIHRpb24gIGJsb2NrcyAgdW50aWwgIGFuICBldmVudCBvY2N1cnMu ICBUaGUgdGhpcmQgaW9jdGwoMikKPj4gICAgICAgICAgICAgICBhcmd1bWVudCBpcyBhIHBvaW50 ZXIgdG8gYSBzdHJ1Y3R1cmUgb2YgdGhlIGZvbGxvd2luZyBmb3JtCj4+ICAgICAgICAgICAgICAg d2hpY2ggIGNvbnRhaW5zICBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZXZlbnQuICBUaGlzIHN0cnVj 4oCQCj4+ICAgICAgICAgICAgICAgdHVyZSBtdXN0IGJlIHplcm9lZCBvdXQgYmVmb3JlIHRoZSBj YWxsLgo+Pgo+PiAgICAgICAgICAgICAgICAgICBzdHJ1Y3Qgc2VjY29tcF9ub3RpZiB7Cj4+ICAg ICAgICAgICAgICAgICAgICAgICBfX3U2NCAgaWQ7ICAgICAgICAgICAgICAvKiBDb29raWUgKi8K Pj4gICAgICAgICAgICAgICAgICAgICAgIF9fdTMyICBwaWQ7ICAgICAgICAgICAgIC8qIFBJRCBv ZiB0YXJnZXQgcHJvY2VzcyAqLwo+PiAgICAgICAgICAgICAgICAgICAgICAgX191MzIgIGZsYWdz OyAgICAgICAgICAgLyogQ3VycmVudGx5IHVudXNlZCAoMCkgKi8KPj4gICAgICAgICAgICAgICAg ICAgICAgIHN0cnVjdCBzZWNjb21wX2RhdGEgZGF0YTsgICAvKiBTZWUgc2VjY29tcCgyKSAqLwo+ PiAgICAgICAgICAgICAgICAgICB9Owo+Pgo+PiAgICAgICAgICAgICAgIFRoZSBmaWVsZHMgaW4g dGhpcyBzdHJ1Y3R1cmUgYXJlIGFzIGZvbGxvd3M6Cj4+Cj4+ICAgICAgICAgICAgICAgaWQgICAg IFRoaXMgaXMgYSBjb29raWUgZm9yIHRoZSBub3RpZmljYXRpb24uICAgRWFjaCAgc3VjaAo+PiAg ICAgICAgICAgICAgICAgICAgICBjb29raWUgIGlzICBndWFyYW50ZWVkICB0byBiZSB1bmlxdWUg Zm9yIHRoZSBjb3JyZeKAkAo+PiAgICAgICAgICAgICAgICAgICAgICBzcG9uZGluZyBzZWNjb21w ICBmaWx0ZXIuICAgSW4gIG90aGVyICB3b3JkcywgIHRoaXMKPj4gICAgICAgICAgICAgICAgICAg ICAgY29va2llICBpcyAgdW5pcXVlIGZvciBlYWNoIG5vdGlmaWNhdGlvbiBldmVudCBmcm9tCj4+ ICAgICAgICAgICAgICAgICAgICAgIHRoZSB0YXJnZXQgcHJvY2Vzcy4gIFRoZSBjb29raWUgdmFs dWUgaGFzIHRoZSAgZm9s4oCQCj4+ICAgICAgICAgICAgICAgICAgICAgIGxvd2luZyB1c2VzOgo+ Pgo+PiAgICAgICAgICAgICAgICAgICAgICDCtyBJdCAgICAgY2FuICAgICBiZSAgICAgdXNlZCAg ICB3aXRoICAgIHRoZSAgICBTRUPigJAKPj4gICAgICAgICAgICAgICAgICAgICAgICBDT01QX0lP Q1RMX05PVElGX0lEX1ZBTElEIGlvY3RsKDIpICBvcGVyYXRpb24gIHRvCj4+ICAgICAgICAgICAg ICAgICAgICAgICAgdmVyaWZ5IHRoYXQgdGhlIHRhcmdldCBwcm9jZXNzIGlzIHN0aWxsIGFsaXZl Lgo+Pgo+PiAgICAgICAgICAgICAgICAgICAgICDCtyBXaGVuICByZXR1cm5pbmcgIGEgIG5vdGlm aWNhdGlvbiAgcmVzcG9uc2UgdG8gdGhlCj4+ICAgICAgICAgICAgICAgICAgICAgICAga2VybmVs LCB0aGUgc3VwZXJ2aXNvciBtdXN0ICBpbmNsdWRlICB0aGUgIGNvb2tpZQo+PiAgICAgICAgICAg ICAgICAgICAgICAgIHZhbHVlIGluIHRoZSBzZWNjb21wX25vdGlmX3Jlc3Agc3RydWN0dXJlIHRo YXQgaXMKPj4gICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQgICBhcyAgIHRoZSAgIGFy Z3VtZW50ICAgb2YgICB0aGUgICBTRUPigJAKPj4gICAgICAgICAgICAgICAgICAgICAgICBDT01Q X0lPQ1RMX05PVElGX1NFTkQgb3BlcmF0aW9uLgo+Pgo+PiAgICAgICAgICAgICAgIHBpZCAgICBU aGlzICBpcyAgdGhlICBQSUQgb2YgdGhlIHRhcmdldCBwcm9jZXNzIHRoYXQgdHJpZ+KAkAo+PiAg ICAgICAgICAgICAgICAgICAgICBnZXJlZCB0aGUgbm90aWZpY2F0aW9uIGV2ZW50Lgo+Pgo+PiAg ICAgICAgICAgICAgICAgICAgICDilIzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilJAKPj4gICAgICAgICAgICAgICAgICAgICAg4pSCRklYTUUgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIKPj4gICAgICAgICAgICAg ICAgICAgICAg4pSc4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSkCj4+ICAgICAgICAgICAgICAgICAgICAgIOKUglRoaXMgaXMgYSB0aHJlYWQgSUQsIHJhdGhl ciB0aGFuIGEgUElELCByaWdodD8gICAgICAg4pSCCj4+ICAgICAgICAgICAgICAgICAgICAgIOKU lOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmAo+IAo+IFll cy4KPiAKPj4KPj4gICAgICAgICAgICAgICBmbGFncyAgVGhpcyBpcyBhICBiaXQgIG1hc2sgIG9m ICBmbGFncyAgcHJvdmlkaW5nICBmdXJ0aGVyCj4+ICAgICAgICAgICAgICAgICAgICAgIGluZm9y bWF0aW9uIG9uIHRoZSBldmVudC4gIEluIHRoZSBjdXJyZW50IGltcGxlbWVu4oCQCj4+ICAgICAg ICAgICAgICAgICAgICAgIHRhdGlvbiwgdGhpcyBmaWVsZCBpcyBhbHdheXMgemVyby4KPj4KPj4g ICAgICAgICAgICAgICBkYXRhICAgVGhpcyBpcyBhIHNlY2NvbXBfZGF0YSBzdHJ1Y3R1cmUgY29u dGFpbmluZyAgaW5mb3LigJAKPj4gICAgICAgICAgICAgICAgICAgICAgbWF0aW9uICBhYm91dCAg dGhlICBzeXN0ZW0gIGNhbGwgdGhhdCB0cmlnZ2VyZWQgdGhlCj4+ICAgICAgICAgICAgICAgICAg ICAgIG5vdGlmaWNhdGlvbi4gIFRoaXMgaXMgdGhlIHNhbWUgc3RydWN0dXJlICB0aGF0ICBpcwo+ PiAgICAgICAgICAgICAgICAgICAgICBwYXNzZWQgIHRvICB0aGUgc2VjY29tcCBmaWx0ZXIuICBT ZWUgc2VjY29tcCgyKSBmb3IKPj4gICAgICAgICAgICAgICAgICAgICAgZGV0YWlscyBvZiB0aGlz IHN0cnVjdHVyZS4KPj4KPj4gICAgICAgICAgICAgICBPbiBzdWNjZXNzLCB0aGlzIG9wZXJhdGlv biByZXR1cm5zIDA7IG9uICBmYWlsdXJlLCAgLTEgIGlzCj4+ICAgICAgICAgICAgICAgcmV0dXJu ZWQsICBhbmQgIGVycm5vICBpcyBzZXQgdG8gaW5kaWNhdGUgdGhlIGNhdXNlIG9mIHRoZQo+PiAg ICAgICAgICAgICAgIGVycm9yLiAgVGhpcyBvcGVyYXRpb24gY2FuIGZhaWwgd2l0aCB0aGUgZm9s bG93aW5nIGVycm9yczoKPj4KPj4gICAgICAgICAgICAgICBFSU5WQUwgKHNpbmNlIExpbnV4IDUu NSkKPj4gICAgICAgICAgICAgICAgICAgICAgVGhlIHNlY2NvbXBfbm90aWYgc3RydWN0dXJlIHRo YXQgd2FzIHBhc3NlZCB0byAgdGhlCj4+ICAgICAgICAgICAgICAgICAgICAgIGNhbGwgY29udGFp bmVkIG5vbnplcm8gZmllbGRzLgo+Pgo+PiAgICAgICAgICAgICAgIEVOT0VOVCBUaGUgIHRhcmdl dCAgcHJvY2VzcyAgd2FzIGtpbGxlZCBieSBhIHNpZ25hbCBhcyB0aGUKPj4gICAgICAgICAgICAg ICAgICAgICAgbm90aWZpY2F0aW9uIGluZm9ybWF0aW9uIHdhcyBiZWluZyBnZW5lcmF0ZWQuCj4+ Cj4+ICAgICAgICDilIzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilJAKPj4gICAgICAgIOKUgkZJWE1FICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAg4pSCCj4+ICAgICAgICDilJzilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilKQKPj4gICAgICAgIOKUgkZyb20gbXkgZXhwZXJpbWVudHMs ICBpdCAgYXBwZWFycyAgdGhhdCAgaWYgIGEgIFNFQ+KAkCDilIIKPj4gICAgICAgIOKUgkNPTVBf SU9DVExfTk9USUZfUkVDViAgIGlzICBkb25lICBhZnRlciAgdGhlICB0YXJnZXQg4pSCCj4+ICAg ICAgICDilIJwcm9jZXNzIHRlcm1pbmF0ZXMsIHRoZW4gdGhlIGlvY3RsKCkgIHNpbXBseSAgYmxv Y2tzIOKUggo+PiAgICAgICAg4pSCKHJhdGhlciB0aGFuIHJldHVybmluZyBhbiBlcnJvciB0byBp bmRpY2F0ZSB0aGF0IHRoZSDilIIKPj4gICAgICAgIOKUgnRhcmdldCBwcm9jZXNzIG5vIGxvbmdl ciBleGlzdHMpLiAgICAgICAgICAgICAgICAgICAg4pSCCj4+ICAgICAgICDilIIgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUggo+PiAgICAgICAg 4pSCSSBmb3VuZCB0aGF0IHN1cnByaXNpbmcsIGFuZCBpdCByZXF1aXJlZCAgc29tZSAgY29u4oCQ IOKUggo+PiAgICAgICAg4pSCdG9ydGlvbnMgIGluIHRoZSBleGFtcGxlIHByb2dyYW0uICBJdCB3 YXMgbm90IHBvc3Np4oCQIOKUggo+PiAgICAgICAg4pSCYmxlIHRvIGNvZGUgbXkgU0lHQ0hMRCBo YW5kbGVyICh3aGljaCByZWFwcyB0aGUgem9t4oCQIOKUggo+PiAgICAgICAg4pSCYmllICB3aGVu ICB0aGUgIHdvcmtlci90YXJnZXQgcHJvY2VzcyB0ZXJtaW5hdGVzKSB0byDilIIKPj4gICAgICAg IOKUgnNpbXBseSBzZXQgYSBmbGFnIGNoZWNrZWQgaW4gdGhlIG1haW4gIGhhbmRsZU5vdGlmaeKA kCDilIIKPj4gICAgICAgIOKUgmNhdGlvbnMoKSAgbG9vcCwgIHNpbmNlICB0aGlzIGNyZWF0ZWQg YW4gdW5hdm9pZGFibGUg4pSCCj4+ICAgICAgICDilIJyYWNlIHdoZXJlIHRoZSBjaGlsZCBtaWdo dCB0ZXJtaW5hdGUgIGp1c3QgIGFmdGVyICBJIOKUggo+PiAgICAgICAg4pSCaGFkICBjaGVja2Vk ICB0aGUgIGZsYWcsICBidXQgYmVmb3JlIEkgYmxvY2tlZCAoZm9y4oCQIOKUggo+PiAgICAgICAg 4pSCZXZlciEpIGluICB0aGUgIFNFQ0NPTVBfSU9DVExfTk9USUZfUkVDViAgb3BlcmF0aW9uLiDi lIIKPj4gICAgICAgIOKUgkluc3RlYWQsICBJIGhhZCB0byBjb2RlIHRoZSBzaWduYWwgaGFuZGxl ciB0byBzaW1wbHkg4pSCCj4+ICAgICAgICDilIJjYWxsIF9leGl0KDIpICBpbiAgb3JkZXIgIHRv ICB0ZXJtaW5hdGUgIHRoZSAgcGFyZW50IOKUggo+PiAgICAgICAg4pSCcHJvY2VzcyAodGhlIHN1 cGVydmlzb3IpLiAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIKPj4gICAgICAgIOKUgiAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCCj4+ ICAgICAgICDilIJJcyAgdGhpcyAgZXhwZWN0ZWQgIGJlaGF2aW9yPyAgSXQgc2VlbXMgdG8gbWUg cmF0aGVyIOKUggo+PiAgICAgICAg4pSCZGVzaXJhYmxlIHRoYXQgU0VDQ09NUF9JT0NUTF9OT1RJ Rl9SRUNWIHNob3VsZCAgZ2l2ZSDilIIKPj4gICAgICAgIOKUgmFuIGVycm9yIGlmIHRoZSB0YXJn ZXQgcHJvY2VzcyBoYXMgdGVybWluYXRlZC4gICAgICAg4pSCCj4+ICAgICAgICDilJTilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJgKPiAKPiBUaGlzIGhhcyBi ZWVuIGRpc2N1c3NlZCBsYXRlciBpbiB0aGUgdGhyZWFkIHRvbywgSSBiZWxpZXZlLiBNeSBwYXRj aHNldAo+IGZpeGVkIGEgZGlmZmVyZW50IGJ1dCByZWxhdGVkIGJ1ZyBpbiAtPnBvbGwoKSB3aGVu IGEgZmlsdGVyIGJlY29tZXMKPiB1bnVzZWQuIEkgaGFkbid0IG5vdGljZWQgdGhpcyBiZWhhdmlv ciBzaW5jZSBJJ20gYWx3YXlzIHBvbGxpbmcuIChQdXJlCj4gaW9jdGxzKCkgZmVlbCBhIGJpdCBm aXNoeSB0byBtZS4gOikgQnV0IG9idmlvdXNseSBhIHZhbGlkIHVzZS4pCgpZZXMsIEkgaG9wZSB0 aGUgaW9jdGwoKSBjYW4gYmUgZml4ZWQuCgo+PiAgICAgICAgU0VDQ09NUF9JT0NUTF9OT1RJRl9J RF9WQUxJRAo+PiAgICAgICAgICAgICAgIFRoaXMgb3BlcmF0aW9uIGNhbiBiZSB1c2VkIHRvIGNo ZWNrIHRoYXQgYSBub3RpZmljYXRpb24gSUQKPj4gICAgICAgICAgICAgICByZXR1cm5lZCBieSBh biBlYXJsaWVyIFNFQ0NPTVBfSU9DVExfTk9USUZfUkVDViAgb3BlcmF0aW9uCj4+ICAgICAgICAg ICAgICAgaXMgIHN0aWxsICB2YWxpZCAgKGkuZS4sICB0aGF0ICB0aGUgIHRhcmdldCAgcHJvY2Vz cyBzdGlsbAo+PiAgICAgICAgICAgICAgIGV4aXN0cykuCj4+Cj4+ICAgICAgICAgICAgICAgVGhl IHRoaXJkIGlvY3RsKDIpIGFyZ3VtZW50IGlzIGEgIHBvaW50ZXIgIHRvICB0aGUgIGNvb2tpZQo+ PiAgICAgICAgICAgICAgIChpZCkgcmV0dXJuZWQgYnkgdGhlIFNFQ0NPTVBfSU9DVExfTk9USUZf UkVDViBvcGVyYXRpb24uCj4+Cj4+ICAgICAgICAgICAgICAgVGhpcyAgb3BlcmF0aW9uIGlzIG5l Y2Vzc2FyeSB0byBhdm9pZCByYWNlIGNvbmRpdGlvbnMgdGhhdAo+PiAgICAgICAgICAgICAgIGNh biAgb2NjdXIgICB3aGVuICAgdGhlICAgcGlkICAgcmV0dXJuZWQgICBieSAgIHRoZSAgIFNFQ+KA kAo+PiAgICAgICAgICAgICAgIENPTVBfSU9DVExfTk9USUZfUkVDViAgIG9wZXJhdGlvbiAgIHRl cm1pbmF0ZXMsICBhbmQgIHRoYXQKPj4gICAgICAgICAgICAgICBwcm9jZXNzIElEIGlzIHJldXNl ZCBieSBhbm90aGVyIHByb2Nlc3MuICAgQW4gIGV4YW1wbGUgIG9mCj4+ICAgICAgICAgICAgICAg dGhpcyBraW5kIG9mIHJhY2UgaXMgdGhlIGZvbGxvd2luZwo+Pgo+PiAgICAgICAgICAgICAgIDEu IEEgIG5vdGlmaWNhdGlvbiAgaXMgIGdlbmVyYXRlZCAgb24gIHRoZSAgbGlzdGVuaW5nIGZpbGUK Pj4gICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLiAgVGhlIHJldHVybmVkICBzZWNjb21wX25v dGlmICBjb250YWlucyAgdGhlCj4+ICAgICAgICAgICAgICAgICAgUElEIG9mIHRoZSB0YXJnZXQg cHJvY2Vzcy4KPj4KPj4gICAgICAgICAgICAgICAyLiBUaGUgdGFyZ2V0IHByb2Nlc3MgdGVybWlu YXRlcy4KPj4KPj4gICAgICAgICAgICAgICAzLiBBbm90aGVyIHByb2Nlc3MgaXMgY3JlYXRlZCBv biB0aGUgc3lzdGVtIHRoYXQgYnkgY2hhbmNlCj4+ICAgICAgICAgICAgICAgICAgcmV1c2VzIHRo ZSBQSUQgdGhhdCB3YXMgZnJlZWQgd2hlbiB0aGUgIHRhcmdldCAgcHJvY2Vzcwo+PiAgICAgICAg ICAgICAgICAgIHRlcm1pbmF0ZXMuCj4+Cj4+ICAgICAgICAgICAgICAgNC4gVGhlICBzdXBlcnZp c29yICBvcGVuKDIpcyAgdGhlIC9wcm9jL1twaWRdL21lbSBmaWxlIGZvcgo+PiAgICAgICAgICAg ICAgICAgIHRoZSBQSUQgb2J0YWluZWQgaW4gc3RlcCAxLCB3aXRoIHRoZSBpbnRlbnRpb24gb2Yg KHNheSkKPj4gICAgICAgICAgICAgICAgICBpbnNwZWN0aW5nIHRoZSBtZW1vcnkgbG9jYXRpb25z IHRoYXQgY29udGFpbnMgdGhlIGFyZ3XigJAKPj4gICAgICAgICAgICAgICAgICBtZW50cyBvZiB0 aGUgc3lzdGVtIGNhbGwgdGhhdCB0cmlnZ2VyZWQgIHRoZSAgbm90aWZpY2HigJAKPj4gICAgICAg ICAgICAgICAgICB0aW9uIGluIHN0ZXAgMS4KPj4KPj4gICAgICAgICAgICAgICBJbiB0aGUgYWJv dmUgc2NlbmFyaW8sIHRoZSByaXNrIGlzIHRoYXQgdGhlIHN1cGVydmlzb3IgbWF5Cj4+ICAgICAg ICAgICAgICAgdHJ5IHRvIGFjY2VzcyB0aGUgbWVtb3J5IG9mIGEgcHJvY2VzcyBvdGhlciB0aGFu IHRoZSAgdGFy4oCQCj4+ICAgICAgICAgICAgICAgZ2V0LiAgIFRoaXMgIHJhY2UgIGNhbiBiZSBh dm9pZGVkIGJ5IGZvbGxvd2luZyB0aGUgY2FsbCB0bwo+PiAgICAgICAgICAgICAgIG9wZW4gd2l0 aCBhIFNFQ0NPTVBfSU9DVExfTk9USUZfSURfVkFMSUQgb3BlcmF0aW9uIHRvIHZlcuKAkAo+PiAg ICAgICAgICAgICAgIGlmeSAgdGhhdCAgdGhlICBwcm9jZXNzIHRoYXQgZ2VuZXJhdGVkIHRoZSBu b3RpZmljYXRpb24gaXMKPj4gICAgICAgICAgICAgICBzdGlsbCBhbGl2ZS4gIChOb3RlIHRoYXQg IGlmICB0aGUgIHRhcmdldCAgcHJvY2VzcyAgc3Vic2XigJAKPj4gICAgICAgICAgICAgICBxdWVu dGx5ICB0ZXJtaW5hdGVzLCBpdHMgUElEIHdvbid0IGJlIHJldXNlZCBiZWNhdXNlIHRoZXJlCj4+ ICAgICAgICAgICAgICAgcmVtYWlucyBhbiBvcGVuIHJlZmVyZW5jZSB0byB0aGUgL3Byb2NbcGlk XS9tZW0gIGZpbGU7ICBpbgo+PiAgICAgICAgICAgICAgIHRoaXMgIGNhc2UsIGEgc3Vic2VxdWVu dCByZWFkKDIpIGZyb20gdGhlIGZpbGUgd2lsbCByZXR1cm4KPj4gICAgICAgICAgICAgICAwLCBp bmRpY2F0aW5nIGVuZCBvZiBmaWxlLikKPj4KPj4gICAgICAgICAgICAgICBPbiBzdWNjZXNzIChp LmUuLCB0aGUgbm90aWZpY2F0aW9uICBJRCAgaXMgIHN0aWxsICB2YWxpZCksCj4+ICAgICAgICAg ICAgICAgdGhpcyAgb3BlcmF0aW9uICByZXR1cm5zIDAgT24gZmFpbHVyZSAoaS5lLiwgdGhlIG5v dGlmaWNh4oCQCj4gCj4gTWlzc2luZyBhICIuIiwgSSB0aGluay4KCihZdXAuIEFscmVhZHkgZml4 ZWQuKQoKPj4gICAgICAgICAgICAgICB0aW9uIElEIGlzIG5vIGxvbmdlciB2YWxpZCksIC0xIGlz IHJldHVybmVkLCBhbmQgZXJybm8gIGlzCj4+ICAgICAgICAgICAgICAgc2V0IHRvIEVOT0VOVC4K Pj4KPj4gICAgICAgIFNFQ0NPTVBfSU9DVExfTk9USUZfU0VORAo+PiAgICAgICAgICAgICAgIFRo aXMgIG9wZXJhdGlvbiAgaXMgIHVzZWQgIHRvIHNlbmQgYSBub3RpZmljYXRpb24gcmVzcG9uc2UK Pj4gICAgICAgICAgICAgICBiYWNrIHRvIHRoZSBrZXJuZWwuICBUaGUgdGhpcmQgaW9jdGwoMikg YXJndW1lbnQgIG9mICB0aGlzCj4+ICAgICAgICAgICAgICAgc3RydWN0dXJlICBpcyAgYSAgcG9p bnRlciAgdG8gYSBzdHJ1Y3R1cmUgb2YgdGhlIGZvbGxvd2luZwo+PiAgICAgICAgICAgICAgIGZv cm06Cj4+Cj4+ICAgICAgICAgICAgICAgICAgIHN0cnVjdCBzZWNjb21wX25vdGlmX3Jlc3Agewo+ PiAgICAgICAgICAgICAgICAgICAgICAgX191NjQgaWQ7ICAgICAgICAgICAgICAgLyogQ29va2ll IHZhbHVlICovCj4+ICAgICAgICAgICAgICAgICAgICAgICBfX3M2NCB2YWw7ICAgICAgICAgICAg ICAvKiBTdWNjZXNzIHJldHVybiB2YWx1ZSAqLwo+PiAgICAgICAgICAgICAgICAgICAgICAgX19z MzIgZXJyb3I7ICAgICAgICAgICAgLyogMCAoc3VjY2Vzcykgb3IgbmVnYXRpdmUKPj4gICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yIG51bWJlciAq Lwo+PiAgICAgICAgICAgICAgICAgICAgICAgX191MzIgZmxhZ3M7ICAgICAgICAgICAgLyogU2Vl IGJlbG93ICovCj4+ICAgICAgICAgICAgICAgICAgIH07Cj4+Cj4+ICAgICAgICAgICAgICAgVGhl IGZpZWxkcyBvZiB0aGlzIHN0cnVjdHVyZSBhcmUgYXMgZm9sbG93czoKPj4KPj4gICAgICAgICAg ICAgICBpZCAgICAgVGhpcyBpcyB0aGUgY29va2llIHZhbHVlIHRoYXQgIHdhcyAgb2J0YWluZWQg IHVzaW5nCj4+ICAgICAgICAgICAgICAgICAgICAgIHRoZSAgIFNFQ0NPTVBfSU9DVExfTk9USUZf UkVDViAgIG9wZXJhdGlvbi4gICAgVGhpcwo+PiAgICAgICAgICAgICAgICAgICAgICBjb29raWUg dmFsdWUgYWxsb3dzIHRoZSBrZXJuZWwgdG8gIGNvcnJlY3RseSAgYXNzb+KAkAo+PiAgICAgICAg ICAgICAgICAgICAgICBjaWF0ZSB0aGlzIHJlc3BvbnNlIHdpdGggdGhlIHN5c3RlbSBjYWxsIHRo YXQgdHJpZ+KAkAo+PiAgICAgICAgICAgICAgICAgICAgICBnZXJlZCB0aGUgdXNlci1zcGFjZSBu b3RpZmljYXRpb24uCj4+Cj4+ICAgICAgICAgICAgICAgdmFsICAgIFRoaXMgaXMgdGhlIHZhbHVl IHRoYXQgd2lsbCBiZSB1c2VkIGZvciAgYSAgc3Bvb2ZlZAo+PiAgICAgICAgICAgICAgICAgICAg ICBzdWNjZXNzICByZXR1cm4gIGZvciAgdGhlICB0YXJnZXQgIHByb2Nlc3MncyBzeXN0ZW0KPj4g ICAgICAgICAgICAgICAgICAgICAgY2FsbDsgc2VlIGJlbG93Lgo+Pgo+PiAgICAgICAgICAgICAg IGVycm9yICBUaGlzIGlzIHRoZSB2YWx1ZSB0aGF0IHdpbGwgYmUgdXNlZCAgYXMgIHRoZSAgZXJy b3IKPj4gICAgICAgICAgICAgICAgICAgICAgbnVtYmVyICAoZXJybm8pICBmb3IgYSBzcG9vZmVk IGVycm9yIHJldHVybiBmb3IgdGhlCj4+ICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCBwcm9j ZXNzJ3Mgc3lzdGVtIGNhbGw7IHNlZSBiZWxvdy4KPiAKPiBOaXQ6ICJ2YWwiIGlzIG9ubHkgdXNl ZCB3aGVuICJlcnJvciIgaXMgbm90IHNldC4KClllcy4gSSBub3RlIHRoYXQgYmVsb3cuIEkgZG9u J3Qgd2FudCB0byBjbHV0dGVyIHRoaXMgcGFydCBvZiB0aGUgcGFnZSB3aXRoCnRvbyBtYW55IGRl dGFpbHMuCgo+PiAgICAgICAgICAgICAgIGZsYWdzICBUaGlzIGlzIGEgYml0IG1hc2sgdGhhdCBp bmNsdWRlcyB6ZXJvICBvciAgbW9yZSAgb2YKPj4gICAgICAgICAgICAgICAgICAgICAgdGhlIGZv bGxvd2luZyBmbGFncwo+Pgo+PiAgICAgICAgICAgICAgICAgICAgICBTRUNDT01QX1VTRVJfTk9U SUZfRkxBR19DT05USU5VRSAoc2luY2UgTGludXggNS41KQo+PiAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgVGVsbCAgIHRoZSAga2VybmVsICB0byAgZXhlY3V0ZSAgdGhlICB0YXJnZXQKPj4g ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3MncyBzeXN0ZW0gY2FsbC4KPj4KPj4g ICAgICAgICAgICAgICBUd28ga2luZHMgb2YgcmVzcG9uc2UgYXJlIHBvc3NpYmxlOgo+Pgo+PiAg ICAgICAgICAgICAgIMK3IEEgcmVzcG9uc2UgdG8gdGhlIGtlcm5lbCB0ZWxsaW5nIGl0IHRvIGV4 ZWN1dGUgdGhlICB0YXLigJAKPj4gICAgICAgICAgICAgICAgIGdldCAgcHJvY2VzcydzICBzeXN0 ZW0gIGNhbGwuICAgSW4gIHRoaXMgY2FzZSwgdGhlIGZsYWdzCj4+ICAgICAgICAgICAgICAgICBm aWVsZCBpbmNsdWRlcyBTRUNDT01QX1VTRVJfTk9USUZfRkxBR19DT05USU5VRSBhbmQgIHRoZQo+ PiAgICAgICAgICAgICAgICAgZXJyb3IgYW5kIHZhbCBmaWVsZHMgbXVzdCBiZSB6ZXJvLgo+Pgo+ PiAgICAgICAgICAgICAgICAgVGhpcyAga2luZCAgb2YgcmVzcG9uc2UgY2FuIGJlIHVzZWZ1bCBp biBjYXNlcyB3aGVyZSB0aGUKPj4gICAgICAgICAgICAgICAgIHN1cGVydmlzb3IgbmVlZHMgdG8g ZG8gZGVlcGVyIGFuYWx5c2lzIG9mICB0aGUgIHRhcmdldCdzCj4+ICAgICAgICAgICAgICAgICBz eXN0ZW0gIGNhbGwgIHRoYW4gIGlzICBwb3NzaWJsZSAgZnJvbSAgYSBzZWNjb21wIGZpbHRlcgo+ PiAgICAgICAgICAgICAgICAgKGUuZy4sIGV4YW1pbmluZyB0aGUgdmFsdWVzIG9mIHBvaW50ZXIg YXJndW1lbnRzKSwgIGFuZCwKPj4gICAgICAgICAgICAgICAgIGhhdmluZyAgdmVyaWZpZWQgdGhh dCB0aGUgc3lzdGVtIGNhbGwgaXMgYWNjZXB0YWJsZSwgdGhlCj4+ICAgICAgICAgICAgICAgICBz dXBlcnZpc29yIHdhbnRzIHRvIGFsbG93IGl0IHRvIHByb2NlZWQuCj4gCj4gSSB0aGluayBKYW5u IGhhcyBwb2ludGVkIHRoaXMgb3V0LiBUaGlzIG5lZWRzIHRvIGNvbWUgd2l0aCBhIGJpZyB3YXJu aW5nCj4gYW5kIEkgd291bGQgZXhwbGljaXRseSBwdXQgYToKPiAiVGhlIHVzZXIgbm90aWZpY2F0 aW9uIG1lY2hhbmlzbSBjYW5ub3QgYmUgdXNlZCB0byBpbXBsZW1lbnQgYSBzeXNjYWxsCj4gc2Vj dXJpdHkgcG9saWN5IGluIHVzZXIgc3BhY2UhIgo+IFlvdSBtaWdodCB3YW50IHRvIHRha2UgYSBs b29rIGF0IHRoZSBzZWNjb21wLmggaGVhZGVyIGZpbGUgd2hlcmUgSQo+IHBsYWNlZCBhIGdpYW50 IHdhcm5pbmcgYWJvdXQgaG93IHRvIHVzZSB0aGlzIHRvby4KClllcy4gS2VlcyBhbHNvIHJhaXNl ZCB0aGlzLiBTZWUgbXkgcmVwbHkgdG8gSmFubiAod2hvIHBhc3RlZCBpbiBhIGNvcHkgCm9mIHBh cnQgb2YgeW91ciBjb21tZW50IGZyb20gc2VjY29tcC5oKS4gSSdtIGdvaW5nIHRvIGZyZWVseSBy ZXVzZSB0aGUKdGV4dCBmcm9tIHlvdXIgY29tbWVudC4gUGxlYXNlIHRha2UgYSBsb29rIGF0IHRo ZSB0ZXh0IGluIG15IHJlcGx5IHRvIEphbm4sCmFkIGxldCBtZSBrbm93IHdhdCB5b3UgdGhpbmsu Cgo+PiAgICAgICAgICAgICAgIMK3IEEgc3Bvb2ZlZCByZXR1cm4gdmFsdWUgZm9yIHRoZSB0YXJn ZXQgIHByb2Nlc3MncyAgc3lzdGVtCj4+ICAgICAgICAgICAgICAgICBjYWxsLiAgIEluICB0aGlz ICBjYXNlLCAgdGhlIGtlcm5lbCBkb2VzIG5vdCBleGVjdXRlIHRoZQo+PiAgICAgICAgICAgICAg ICAgdGFyZ2V0IHByb2Nlc3MncyBzeXN0ZW0gY2FsbCwgaW5zdGVhZCBjYXVzaW5nIHRoZSBzeXN0 ZW0KPj4gICAgICAgICAgICAgICAgIGNhbGwgdG8gcmV0dXJuIGEgc3Bvb2ZlZCB2YWx1ZSBhcyBz cGVjaWZpZWQgYnkgZmllbGRzIG9mCj4+ICAgICAgICAgICAgICAgICB0aGUgc2VjY29tcF9ub3Rp Zl9yZXNwIHN0cnVjdHVyZS4gIFRoZSBzdXBlcnZpc29yIHNob3VsZAo+PiAgICAgICAgICAgICAg ICAgc2V0IHRoZSBmaWVsZHMgb2YgdGhpcyBzdHJ1Y3R1cmUgYXMgZm9sbG93czoKPj4KPj4gICAg ICAgICAgICAgICAgICsgIGZsYWdzICBkb2VzICBub3QgY29udGFpbiBTRUNDT01QX1VTRVJfTk9U SUZfRkxBR19DT07igJAKPj4gICAgICAgICAgICAgICAgICAgIFRJTlVFLgo+Pgo+PiAgICAgICAg ICAgICAgICAgKyAgZXJyb3IgaXMgc2V0IGVpdGhlciB0byAgMCAgZm9yICBhICBzcG9vZmVkICAi c3VjY2VzcyIKPj4gICAgICAgICAgICAgICAgICAgIHJldHVybiAgb3IgIHRvICBhIG5lZ2F0aXZl IGVycm9yIG51bWJlciBmb3IgYSBzcG9vZmVkCj4+ICAgICAgICAgICAgICAgICAgICAiZmFpbHVy ZSIgcmV0dXJuLiAgSW4gdGhlICBmb3JtZXIgIGNhc2UsICB0aGUgIGtlcm5lbAo+PiAgICAgICAg ICAgICAgICAgICAgY2F1c2VzIHRoZSB0YXJnZXQgcHJvY2VzcydzIHN5c3RlbSBjYWxsIHRvIHJl dHVybiB0aGUKPj4gICAgICAgICAgICAgICAgICAgIHZhbHVlIHNwZWNpZmllZCBpbiB0aGUgdmFs IGZpZWxkLiAgSW4gdGhlIGxhdGVyIGNhc2UsCj4+ICAgICAgICAgICAgICAgICAgICB0aGUga2Vy bmVsIGNhdXNlcyB0aGUgdGFyZ2V0IHByb2Nlc3MncyBzeXN0ZW0gY2FsbCB0bwo+PiAgICAgICAg ICAgICAgICAgICAgcmV0dXJuIC0xLCBhbmQgZXJybm8gaXMgYXNzaWduZWQgIHRoZSAgbmVnYXRl ZCAgZXJyb3IKPj4gICAgICAgICAgICAgICAgICAgIHZhbHVlLgo+Pgo+PiAgICAgICAgICAgICAg ICAgKyAgdmFsIGlzIHNldCB0byBhIHZhbHVlIHRoYXQgd2lsbCBiZSB1c2VkIGFzIHRoZSByZXR1 cm4KPj4gICAgICAgICAgICAgICAgICAgIHZhbHVlIGZvciBhIHNwb29mZWQgInN1Y2Nlc3MiIHJl dHVybiBmb3IgIHRoZSAgdGFyZ2V0Cj4+ICAgICAgICAgICAgICAgICAgICBwcm9jZXNzJ3MgIHN5 c3RlbSAgY2FsbC4gICBUaGUgdmFsdWUgaW4gdGhpcyBmaWVsZCBpcwo+PiAgICAgICAgICAgICAg ICAgICAgaWdub3JlZCBpZiB0aGUgZXJyb3IgZmllbGQgY29udGFpbnMgYSBub256ZXJvIHZhbHVl Lgo+Pgo+PiAgICAgICAgICAgICAgIE9uIHN1Y2Nlc3MsIHRoaXMgb3BlcmF0aW9uIHJldHVybnMg MDsgb24gIGZhaWx1cmUsICAtMSAgaXMKPj4gICAgICAgICAgICAgICByZXR1cm5lZCwgIGFuZCAg ZXJybm8gIGlzIHNldCB0byBpbmRpY2F0ZSB0aGUgY2F1c2Ugb2YgdGhlCj4+ICAgICAgICAgICAg ICAgZXJyb3IuICBUaGlzIG9wZXJhdGlvbiBjYW4gZmFpbCB3aXRoIHRoZSBmb2xsb3dpbmcgZXJy b3JzOgo+Pgo+PiAgICAgICAgICAgICAgIEVJTlBST0dSRVNTCj4+ICAgICAgICAgICAgICAgICAg ICAgIEEgcmVzcG9uc2UgdG8gdGhpcyBub3RpZmljYXRpb24gIGhhcyAgYWxyZWFkeSAgYmVlbgo+ PiAgICAgICAgICAgICAgICAgICAgICBzZW50Lgo+Pgo+PiAgICAgICAgICAgICAgIEVJTlZBTCBB biBpbnZhbGlkIHZhbHVlIHdhcyBzcGVjaWZpZWQgaW4gdGhlIGZsYWdzIGZpZWxkLgo+Pgo+PiAg ICAgICAgICAgICAgIEVJTlZBTCBUaGUgICAgICAgZmxhZ3MgICAgICBmaWVsZCAgICAgIGNvbnRh aW5lZCAgICAgIFNFQ+KAkAo+PiAgICAgICAgICAgICAgICAgICAgICBDT01QX1VTRVJfTk9USUZf RkxBR19DT05USU5VRSwgYW5kIHRoZSBlcnJvciBvciB2YWwKPj4gICAgICAgICAgICAgICAgICAg ICAgZmllbGQgd2FzIG5vdCB6ZXJvLgo+Pgo+PiAgICAgICAgICAgICAgIEVOT0VOVCBUaGUgIGJs b2NrZWQgIHN5c3RlbSBjYWxsIGluIHRoZSB0YXJnZXQgcHJvY2VzcyBoYXMKPj4gICAgICAgICAg ICAgICAgICAgICAgYmVlbiBpbnRlcnJ1cHRlZCBieSBhIHNpZ25hbCBoYW5kbGVyLgo+Pgo+PiBO T1RFUwo+PiAgICAgICAgVGhlIGZpbGUgZGVzY3JpcHRvciByZXR1cm5lZCB3aGVuIHNlY2NvbXAo MikgaXMgZW1wbG95ZWQgd2l0aCB0aGUKPj4gICAgICAgIFNFQ0NPTVBfRklMVEVSX0ZMQUdfTkVX X0xJU1RFTkVSICBmbGFnICBjYW4gIGJlICBtb25pdG9yZWQgIHVzaW5nCj4+ICAgICAgICBwb2xs KDIpLCBlcG9sbCg3KSwgYW5kIHNlbGVjdCgyKS4gIFdoZW4gYSBub3RpZmljYXRpb24gIGlzICBw ZW5k4oCQCj4+ICAgICAgICBpbmcsICB0aGVzZSBpbnRlcmZhY2VzIGluZGljYXRlIHRoYXQgdGhl IGZpbGUgZGVzY3JpcHRvciBpcyByZWFk4oCQCj4+ICAgICAgICBhYmxlLgo+IAo+IFRoaXMgc2hv dWxkIGFsc28gbm90ZSB0aGF0IHdoZW4gYSBmaWx0ZXIgYmVjb21lcyB1bnVzZWQsIGkuZS4gdGhl IGxhc3QKPiB0YXNrIHVzaW5nIHRoYXQgZmlsdGVyIGluIGl0cyBmaWx0ZXIgaGllcmFyY2h5IGlz IGRlYWQgKGJlZW4KPiByZWFwZWQvYXV0b3JlYXBlZCkgLT5wb2xsKCkgd2lsbCBub3RpZnkgd2l0 aCAoRSlQT0xMSFVQLgoKQWhoISBOb3cgSSB1bmRlcnN0YW5kLiBJIHdhcyB1bmF3YXJlIG9mIHRo aXMuIEphbm4gY29tbWVudGVkIHRoYXQKcG9sbCgpIGNvdWxkIGJlIHVzZWQgYXMgd2VsbCwgYnV0 IHlvdSBwcm92aWRlZCBlbm91Z2ggZGV0YWlsIHRoYXQKbm93IEkgdW5kZXJzdGFuZCBob3cgdGhp cyB3b3Jrcy4gSSBhZGRlZCB0aGUgZm9sbG93aW5nIGluIE5PVEVTCndoZXJlIHBvbGwvc2VsZWN0 L2Vwb2xsIGFyZSBkZXNjcmliZWQ6CgogICAgICAgwrcgQWZ0ZXIgdGhlIGxhc3QgdGhyZWFkIHVz aW5nIHRoZSBmaWx0ZXIgaGFzIHRlcm1pbmF0ZWQgIGFuZCAgYmVlbgogICAgICAgICByZWFwZWQg IHVzaW5nIHdhaXRwaWQoMikgKG9yIHNpbWlsYXIpLCB0aGUgZmlsZSBkZXNjcmlwdG9yIGluZGni gJAKICAgICAgICAgY2F0ZXMgYW4gZW5kLW9mLWZpbGUgY29uZGl0aW9uICAocmVhZGFibGUgIGlu ICBzZWxlY3QoMik7ICBQT0xM4oCQCiAgICAgICAgIEhVUC9FUE9MTEhVUCBpbiBwb2xsKDIpLyBl cG9sbF93YWl0KDIpKS4KCj4+ICAgICAgICDilIzilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilJAKPj4gICAgICAgIOKUgkZJWE1FICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCCj4+ICAgICAgICDilJzilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilKQKPj4gICAgICAgIOKUgkludGVy ZXN0aW5nbHksIGFmdGVyIHRoZSBldmVudCAgaGFkICBiZWVuICByZWNlaXZlZCwg4pSCCj4+ICAg ICAgICDilIJ0aGUgIGZpbGUgZGVzY3JpcHRvciBpbmRpY2F0ZXMgYXMgd3JpdGFibGUgKHZlcmlm aWVkIOKUggo+PiAgICAgICAg4pSCZnJvbSB0aGUgc291cmNlIGNvZGUgYW5kIGJ5IGV4cGVyaW1l bnQpLiBIb3cgaXMgdGhpcyDilIIKPj4gICAgICAgIOKUgnVzZWZ1bD8gICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCCj4+ICAgICAgICDilJTilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJgKPj4KPj4gRVhBTVBMRVMKPj4g ICAgICAgIFRoZSAoc29tZXdoYXQgY29udHJpdmVkKSBwcm9ncmFtIHNob3duIGJlbG93IGRlbW9u c3RyYXRlcyB0aGUgdXNlCj4+ICAgICAgICBvZiB0aGUgaW50ZXJmYWNlcyBkZXNjcmliZWQgaW4g dGhpcyBwYWdlLiAgVGhlIHByb2dyYW0gY3JlYXRlcyAgYQo+PiAgICAgICAgY2hpbGQgIHByb2Nl c3MgIHRoYXQgIHNlcnZlcyAgYXMgdGhlICJ0YXJnZXQiIHByb2Nlc3MuICBUaGUgY2hpbGQKPj4g ICAgICAgIHByb2Nlc3MgIGluc3RhbGxzICBhICBzZWNjb21wICBmaWx0ZXIgIHRoYXQgIHJldHVy bnMgICB0aGUgICBTRUPigJAKPj4gICAgICAgIENPTVBfUkVUX1VTRVJfTk9USUYgIGFjdGlvbiAg dmFsdWUgaWYgYSBjYWxsIGlzIG1hZGUgdG8gbWtkaXIoMikuCj4+ICAgICAgICBUaGUgY2hpbGQg cHJvY2VzcyB0aGVuIGNhbGxzIG1rZGlyKDIpIG9uY2UgZm9yIGVhY2ggb2YgIHRoZSAgc3Vw4oCQ Cj4+ICAgICAgICBwbGllZCAgY29tbWFuZC1saW5lIGFyZ3VtZW50cywgYW5kIHJlcG9ydHMgdGhl IHJlc3VsdCByZXR1cm5lZCBieQo+PiAgICAgICAgdGhlIGNhbGwuICBBZnRlciBwcm9jZXNzaW5n IGFsbCBhcmd1bWVudHMsIHRoZSBjaGlsZCBwcm9jZXNzIHRlcuKAkAo+PiAgICAgICAgbWluYXRl cy4KPj4KPj4gICAgICAgIFRoZSAgcGFyZW50ICBwcm9jZXNzICBhY3RzICBhcyAgdGhlIHN1cGVy dmlzb3IsIGxpc3RlbmluZyBmb3IgdGhlCj4+ICAgICAgICBub3RpZmljYXRpb25zIHRoYXQgYXJl IGdlbmVyYXRlZCB3aGVuIHRoZSAgdGFyZ2V0ICBwcm9jZXNzICBjYWxscwo+PiAgICAgICAgbWtk aXIoMikuICAgV2hlbiBzdWNoIGEgbm90aWZpY2F0aW9uIG9jY3VycywgdGhlIHN1cGVydmlzb3Ig ZXhhbeKAkAo+PiAgICAgICAgaW5lcyB0aGUgbWVtb3J5IG9mIHRoZSB0YXJnZXQgcHJvY2VzcyAo dXNpbmcgL3Byb2MvW3BpZF0vbWVtKSAgdG8KPj4gICAgICAgIGRpc2NvdmVyICB0aGUgcGF0aG5h bWUgYXJndW1lbnQgdGhhdCB3YXMgc3VwcGxpZWQgdG8gdGhlIG1rZGlyKDIpCj4+ICAgICAgICBj YWxsLCBhbmQgcGVyZm9ybXMgb25lIG9mIHRoZSBmb2xsb3dpbmcgYWN0aW9uczoKPj4KPj4gICAg ICAgIMK3IElmIHRoZSBwYXRobmFtZSBiZWdpbnMgd2l0aCB0aGUgcHJlZml4ICIvdG1wLyIsIHRo ZW4gdGhlIHN1cGVy4oCQCj4+ICAgICAgICAgIHZpc29yICBhdHRlbXB0cyAgdG8gIGNyZWF0ZSAg dGhlICBzcGVjaWZpZWQgZGlyZWN0b3J5LCBhbmQgdGhlbgo+PiAgICAgICAgICBzcG9vZnMgYSBy ZXR1cm4gZm9yIHRoZSB0YXJnZXQgIHByb2Nlc3MgIGJhc2VkICBvbiAgdGhlICByZXR1cm4KPj4g ICAgICAgICAgdmFsdWUgIG9mICB0aGUgIHN1cGVydmlzb3IncyAgbWtkaXIoMikgY2FsbC4gIElu IHRoZSBldmVudCB0aGF0Cj4+ICAgICAgICAgIHRoYXQgY2FsbCBzdWNjZWVkcywgdGhlIHNwb29m ZWQgc3VjY2VzcyAgcmV0dXJuICB2YWx1ZSAgaXMgIHRoZQo+PiAgICAgICAgICBsZW5ndGggb2Yg dGhlIHBhdGhuYW1lLgo+Pgo+PiAgICAgICAgwrcgSWYgIHRoZSBwYXRobmFtZSBiZWdpbnMgd2l0 aCAiLi8iIChpLmUuLCBpdCBpcyBhIHJlbGF0aXZlIHBhdGjigJAKPj4gICAgICAgICAgbmFtZSks IHRoZSBzdXBlcnZpc29yIHNlbmRzIGEgIFNFQ0NPTVBfVVNFUl9OT1RJRl9GTEFHX0NPTlRJTlVF Cj4+ICAgICAgICAgIHJlc3BvbnNlICB0byAgdGhlICBrZXJuZWwgdG8gc2F5IHRoYXQga2VybmVs IHNob3VsZCBleGVjdXRlIHRoZQo+PiAgICAgICAgICB0YXJnZXQgcHJvY2VzcydzIG1rZGlyKDIp IGNhbGwuCj4gCj4gUG90ZW50aWFsbHkgcHJvYmxlbWF0aWMgaWYgdGhlIHR3byBwcm9jZXNzZXMg aGF2ZSB0aGUgc2FtZSBwcml2aWxlZ2UKPiBsZXZlbCBhbmQgdGhlIHN1cGVydmlzb3IgaW50ZW5k cyBfQ09OVElOVUUgdG8gbWVhbiAiaXMgc2FmZSB0byBleGVjdXRlIi4KClVuZGVyc3Rvb2QuIEJ1 dCBJIHRoaW5rIHRoYXQgbmVlZHMgdG8gYmUgY2xhcmlmaWVkIGVsc2V3aGVyZSBpbiB0aGUKcGFn ZSwgc2luY2UgaXQncyBlc3NlbnRpYWxseSB0aGUgc2FtZSBwb2ludCBhcyAiVGhlIHVzZXIgbm90 aWZpY2F0aW9uCm1lY2hhbmlzbSBjYW5ub3QgYmUgdXNlZCB0byBpbXBsZW1lbnQgYSBzeXNjYWxs IHNlY3VyaXR5IHBvbGljeSBpbiAKdXNlciBzcGFjZSEiIFNlZSBteSByZXBseSB0byBKYW5uLgoK PiBBbiBhdHRhY2tlciBjb3VsZCB0cnkgdG8gcmUtd3JpdGUgYXJndW1lbnRzIGFmYWljdC4KCkJ5 IGFuIGF0dGFja2VyLCBJIHByZXN1bWUgeW91IG1lYW4gYSBtYWxpZ24gc3VwZXJ2aXNvciwgcmln aHQuClN1cmUsIGl0IGxvb2tzIHRvIG1lIGFzIHRob3VnaCByZXdyaXRpbmcgYXJndW1lbnRzIGNv dWxkIGJlIApwb3NzaWJsZS4gQnV0LCBpZiB5b3UgaGFkIHByaXZpbGVnZSB0byBkbyB0aGF0LCB5 b3UnZCBwcmVzdW1hYmx5CmhhdmUgcHJpdmlsZWdlcyBmb3IgYW55IG51bWJlciBvZiBvdGhlciBu ZWZhcmlvdXMgYWN0aXRpZXMsIHJpZ2h0PwooU28sIEkgZG9uJ3QgdGhpbmsgYW55dGhpbmcgc3Bl Y2lhbCBuZWVkcyB0byBiZSBzYWlkIGhlcmU7IGxldCBtZQprbm93IGlmIHlvdSBmZWVsIHNvbWV0 aGluZyBkb2VzIG5lZWQgdG8gYmUgc2FpZC4KCj4gQSBnb29kIGFuIGVhc3kgZXhhbXBsZSBpcyB1 c3VhbGx5IG1rbm9kKCkgaW4gYSB1c2VyIG5hbWVzcGFjZS4gQQo+IF9DT05USU5VRSBpcyBhbHdh eXMgc2FmZSBzaW5jZSB5b3UgY2FuJ3QgY3JlYXRlIGRldmljZSBub2RlcyBhbnl3YXkuCgpPa2F5 IC0tIGJ1dCBJIHdhbnRlZCB0byBwcm92aWRlIGFuIGV4YW1wbGUgKGFkbWl0dGVkbHkgdmVyeQpj b250cml2ZWQpIHRvIHNob3cgaG93IHRoZSBzdXBlcnZpc29yIGNvdWxkIGVpdGhlciBkbyB0aGUg c3lzdGNhbGwKb24gYmVoYWxmIG9mIHRoZSB0YXJnZXQsIG9yIGxlYXZlIHRoaW5ncyB0byB0aGUg dGFyZ2V0IHRvIGV4ZWN1dGUKdGhlIHN5c3RlbSBjYWxsLiBEbyB5b3UgZmVlbCB0aGF0IHRoZSBl eGFtcGxlIGlzIGxlYWRpbmcgcGVvcGxlCmFzdHJheT8KCj4gU29ycnksIEkgY2FuJ3QgcmV2aWV3 IHRoZSByZXN0IGluIHN1ZmZpY2llbnQgZGV0YWlsIHNpbmNlIEknbSBvbgo+IHZhY2F0aW9uIHN0 aWxsIHNvIEknbSBqdXN0IGdvaW5nIHRvIHNodXQgdXAgbm93LiA6KQoKV2VsbCwgdGhhbmtzIGFs cmVhZHksIGJlY2F1c2UgeW91ciBjb21tZW50cyB3ZXJlIGFscmVhZHkgdmVyeQp1c2VmdWwhLiBJ IHdpbGwgc2VuZCBvdXQgYSBuZXcgZHJhZnQgc2hvcnRseSA6LSkuCgpUaGFua3MsCgpNaWNoYWVs CgotLSAKTWljaGFlbCBLZXJyaXNrCkxpbnV4IG1hbi1wYWdlcyBtYWludGFpbmVyOyBodHRwOi8v d3d3Lmtlcm5lbC5vcmcvZG9jL21hbi1wYWdlcy8KTGludXgvVU5JWCBTeXN0ZW0gUHJvZ3JhbW1p bmcgVHJhaW5pbmc6IGh0dHA6Ly9tYW43Lm9yZy90cmFpbmluZy8KX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX18KQ29udGFpbmVycyBtYWlsaW5nIGxpc3QKQ29u dGFpbmVyc0BsaXN0cy5saW51eC1mb3VuZGF0aW9uLm9yZwpodHRwczovL2xpc3RzLmxpbnV4Zm91 bmRhdGlvbi5vcmcvbWFpbG1hbi9saXN0aW5mby9jb250YWluZXJz